Log4j2 系统属性写入文件

2024-02-14

我使用以下 log4j2 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5.5level %-60.60logger - %msg%n" />
            <Filters>
                <ThresholdFilter level="info" onMatch="ACCEPT"
                    onMismatch="DENY" />
            </Filters>
        </Console>
        <RollingFile name="RollingFile"
            fileName="${sys:log.file}"
            filePattern="${sys:log.parent.path}\$${date:yyyy-MM}\${sys:log.file.name}-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>
                    %d{yyy-MM-dd HH:mm:ss.SSS} [%30.30t]%-10.10level%-60.60logger - %msg%n
                </Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="60 MB" />
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="RollingFile" />
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

当文件位置作为命令行参数传递时,系统参数被设置,然后函数 reconfigureLog() 设置属性

public static void reconfigureLog(String logPath)
    {
        File logFile = new File(logPath);
        System.setProperty("log.file", logPath);
        System.setProperty("log.parent.path", logFile.getParent());
        System.setProperty("log.file.name", FilenameUtils.getBaseName(logFile.getName()));

        org.apache.logging.log4j.core.Logger rootLogger = (org.apache.logging.log4j.core.Logger) LogManager
                .getRootLogger();
        LoggerContext context = rootLogger.getContext();
        context.reconfigure();
    }

这是我从命令行读取参数然后再设置的场景的示例用法。

if (cmd.hasOption("logFile"))
        {
            String logPath = cmd.getOptionValue("logFile");
            Utility.reconfigureLog(logPath);
            logger = LogManager.getLogger(Test.class);
        }

每个类都有一个静态记录器初始化,如下所示:

private final static Logger logger = LogManager.getLogger(Connector.class);

问题是当我运行应用程序时,${sys.log.file}正在创建,然后根据参数创建相应的日志文件。通过参数摸索,似乎RolllingFile下的参数fileName是自动添加的。

log4j2的调试日志是:

2015-12-03 11:07:19,204 main DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="${sys:log.file}", filePattern="${sys:log.parent.path}\${date:yyyy-MM}\${sys:log.file.name}-%d{MM-dd-yyyy}-%i.log.gz", append="null", name="RollingFile", bufferedIO="null", bufferSize="null", immediateFlush="null", Policies(CompositeTriggeringPolicy(policies=[TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false), SizeBasedTriggeringPolicy(size=62914560)])), null, PatternLayout(%d{yyy-MM-dd HH:mm:ss.SSS} [%30.30t]%-10.10level%-60.60logger - %msg%n), null, ignoreExceptions="null", advertise="null", advertiseURI="null", Configuration(<path>\Connector\target\classes\log4j2.xml))
2015-12-03 11:07:19,207 main DEBUG Starting RollingFileManager ${sys:log.file}

可以看出,系统参数是按字面意思选取的,而不是替换的。我需要避免早期初始化并仅在调用 reconfigureLog 方法后才开始加载。 我怎样才能避免${sys.log.file}当我可以使用系统参数作为我的应用程序的一部分时创建?


TL;DR

只需将 ${sys:value} 查找替换为 ${main:--value} 查找即可。

解释

http://logging.apache.org/log4j/2.x/manual/lookups.html#AppMainArgsLookup http://logging.apache.org/log4j/2.x/manual/lookups.html#AppMainArgsLookup

将此功能与配置属性结合起来

http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution http://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution

您可以使用参数进行一些非常强大的配置,而无需接触代码。

请密切关注 PropertySubstitution 文档中的这一点。

如果在与该关联的查找中没有找到该键的值 前缀是与属性中的键关联的值 将使用配置文件中的声明。如果没有值 发现变量声明将作为值返回。默认 可以通过执行以下操作在配置中声明值:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Properties>
    <Property name="--file">log_file_path</property>
  </Properties>
  ...
</Configuration>

这意味着像这样的配置查找${main:--file}将返回命令行参数 --file 如果存在,但如果不存在,则会返回属性声明中的默认值(我不确定属性的名称是否需要为“file”或“--file”才能正确匹配)。如果您的目标是在启动时简单地通过参数设置日志文件,则不需要代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Log4j2 系统属性写入文件 的相关文章

随机推荐

  • React Native - SQLite 找不到预填充的数据库文件

    我正在尝试使用https github com andpor react native sqlite storage https github com andpor react native sqlite storage对于 SQLite
  • 我们如何在没有第三个变量和算术运算符的情况下交换两个数字?

    我们如何在没有第三个变量和算术运算符的情况下交换两个数字 XOR算不算算术运算符 如果没有 那么 X X XOR Y Y X XOR Y X X XOR Y 将此伪代码转换为可编译的 Java 代码作为练习留给读者 关于 java 标签
  • docker-compose如何引用其他目录中的文件

    有这个 dockerfile FROM python 3 8 3 alpine ENV MICRO SERVICE home app microservice RUN addgroup S APP USER adduser S APP US
  • CordovaWebView 与 android 中的 onBackPressed 方法混淆

    正如标题所说CordovaWebView and onBackPressed在 android 中组合起来会产生奇怪的结果 我有混合应用程序 我的主要活动有DrawerLayout and CordovaWebView 我的 onBackP
  • android ndk数据保存/加载

    我正在致力于将 PC OpenGL 应用程序移植到 Android 上 我选择使用 NDK android native app glue 框架 据我了解 它允许我继续使用 C 甚至不编写任何 JAVA 代码行 听起来很有希望 对我来说第一
  • 将加密的 csv 导入 Python 3

    因此 我计划使用 Jupyter Notebook Python 3 进行一些数据分析 出于协作原因 我想将数据存储在 github 存储库上 但数据集很敏感 因此 我想将数据 当前为 csv 作为加密文件存储在存储库上 然后在运行时解密
  • .NET ORM、不可变值对象、结构、默认构造函数和只读属性

    我刚刚开始使用 NET ORM 甚至还没有在 Entity Framework 和 NHibernate 之间做出决定 但在这两种情况下 我都遇到了一个问题 因为他们似乎希望我以各种方式损害域模型的完整性 特别是在 C 对象设计的更精细的方
  • (numpy) __array_wrap__ 有什么作用?

    我第一次深入 SciPy LinAlg 模块 我看到了这个函数 def makearray a new asarray a wrap getattr a array prepare new array wrap return new wra
  • 'quietly = TRUE' 何时在 require() 函数中真正起作用?

    我正在尝试编写一组函数来检查丢失的 R 软件包 并在必要时安装它们 StackOverflow 上有一些很好的代码可以做到这一点 从这里开始 https stackoverflow com questions 4090169 elegant
  • 在更改视图的可见性时应用动画

    我的应用程序中有一个 Horizo ntalScrollView 并且我经常使用它的可见性 可见和消失 所以我想要的是 我可以应用某种动画或其他东西 使其开始以滑动的方式变得可见和不可见 而不是突然使其可见和不可见吗 任何帮助或建议将不胜感
  • 本地主机上的 Django/Celery 多个队列 - 路由不起作用

    我跟着芹菜docs http celery readthedocs org en latest userguide routing html manual routing在我的开发机器上定义 2 个队列 我的芹菜设置 CELERY ALWA
  • 从 Eclipse 中删除插件的正确方法

    上次 我遇到了从 Eclipse 中删除插件的问题 症状 1 如果删除通过已安装菜单 无法正确重新安装并且有多个视角 例如对于 SQL 资源管理器 在Open Perspective menu 2 如果通过文件系统删除 手动从plugins
  • 人员 API 谷歌配额限制

    我正在研究 People API 这仅适用于 google 用户 有人知道吗 我一天 分钟可以免费询问多少次 一般配额限制是多少 超过门槛需要花费多少钱 Thanks 有两种不同的 People API 您可以在云控制台中查看两者的配额 G
  • 具有基本身份验证的 Webclient / HttpWebRequest 返回 404 未找到有效 URL

    编辑 我想回来指出问题根本不在我这边 而是与另一家公司的代码有关 我正在尝试使用基本身份验证来打开页面 我不断收到 404 页面未找到错误 我可以将我的网址复制并粘贴到浏览器中 它工作正常 如果我尚未登录他们的网站 它会弹出一个凭据框 否则
  • ASP.NET Core 默认调试启动 URL

    使用 ASP NET Core Web API 模板时 默认调试启动 URL 以某种方式设置为api values 此默认配置在哪里以及如何更改它 我能找到的有关此启动 URL 声明位置的文档非常少 这个里面有简短的提及博客文章 https
  • vuelidate 异步验证器 - 如何去抖?

    因此 我的电子邮件 用户表单元素上的异步验证器存在问题 每次输入字母时 它都会检查有效性 如果电子邮件有 30 个字符 那么就超过 30 个电话 有人知道消除 vuelidate 自定义验证器的最佳方法吗 当我尝试使用 debounce 时
  • 传统 For 循环与增强型 For 循环 [重复]

    这个问题在这里已经有答案了 这段代码 import java util import java io class TestClass public static void main String args throws Exception
  • Visual Basic .NET 中的 UInt32 数据类型是什么?

    是什么UInt32VB NET 中的数据类型 有人可以告诉我它的位长度和之间的区别吗UInt32 and Int32 它是整数还是浮点数 它是一个无符号 32 位整数 U 表示无符号 Int 表示整数 32 换 32 或者你可以看看文档 h
  • 将 SageMaker 管道模式与 tfrecords 的 s3 目录结合使用

    我打电话给sagemaker tensorflow TensorFlow fit 当我使用时无限期挂起 没有错误消息Pipe代替File as the input mode 我相应地替换了TensorFlowDataset with Pip
  • Log4j2 系统属性写入文件

    我使用以下 log4j2 配置