log4j2:设置Log4jContextSelector系统属性以进行异步日志记录的位置

17

为了提高性能,我正在尝试在当前在自由配置文件服务器中运行的 REST web 方法中设置异步日志记录。

为了实现这一目标,我已经设置了以下属性:

System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");

我的问题是,无论在哪里进行操作,有时它可以正常工作并且日志记录非常快,而有时则不行。

我尝试了以下位置: (a) 包含所有REST web方法的类的构造函数中 (b) 在调用REST方法之前调用的过滤器doFilter方法中 (c) 在过滤器init方法中 (d) 在REST方法本身中

这些位置没有一个能够始终正常工作。

是否有人能够解释这种行为,如果可能的话,请提供一个修复问题的建议。

编辑:似乎log4j在调用setProperty之前已被初始化。因此,我需要通过自由配置文件设置属性。


@fnt 不,我没有证据,也没有进行比较,所以我会更改我的评论。我只是在这里与标准日志记录进行比较[二进制日志记录性能-幻灯片23](http://www.slideshare.net/cnbailey/websphere-technical-university-top-websphere-problem-determination-features)。 - Gas
1
你可以在Liberty中评估二进制日志记录选项,因为它比标准日志记录具有更好的性能。也许对你来说已经足够好了。 - Gas
不错的阅读。https://springframework.guru/asynchronous-logging-with-log4j-2/ - Chacko
1
看起来,Log4J2使用属性名称log4j2.contextSelectorLog4JContextSelector支持此功能-文档似乎在某些地方混合了这两个。 - Ed Randall
4个回答

34

有一种未记录的方法可以为您的项目设置此值,而无需在启动时手动传递系统属性值。

在类路径中添加一个名为 log4j2.component.properties 的文件。这可以通过将其保存在 src/main/resources 中的大多数maven或gradle项目中完成。

该文件只是一个简单的java.util.Properties文件。通过向文件添加以下行设置上下文选择器的值。

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

Log4j首先尝试读取系统属性。如果系统属性为空,则默认回退到该文件中存储的值。

执行此设置的代码位于Log4jContextFactory.java:91

文件位置


1
如果将其作为文件添加,有什么我可以做来验证是否考虑了此属性?附注:现在可以在org.apache.logging.log4j.util.PropertiesUtil.LOG4J_PROPERTIES_FILE_NAME中看到文件名。 - membersound
1
那真是太有帮助了。谢谢,你有任何关于如何为log4j文档做出贡献的想法吗?如果我当时就有这些信息,可能会节省我几个小时的搜索时间。 - Chris

2
我的问题是,无论我在哪里这样做,有时它可以正常工作并且日志记录非常快,而有时则不行。将该代码添加到定义主入口点的类中的静态初始化程序块中。
public class MainClass {
    // NOTE: Nothing can appear before this initializer
    // NOTE: This initializer must be in the class that contains your entry point
    static {
        System.setProperty("Log4jContextSelector",
            "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
    }

    public static void main(final String[] args) {
        // Do anything you want to here
    }
}

根据Java规范,静态初始化按照声明的顺序进行。因此,System.setProperty调用在Log4j初始化之前得到保证。

0

如果将它添加到Tomcat服务器配置的VM参数中,它能够正常工作吗? - Tushar Banne

0

在调用主方法之前,Log4j已经被初始化。因此,它无法从系统中选择您的属性Log4jContextSelector,并且默认情况下它是同步工作的。

为了验证相同的内容:删除disruptor依赖项,如果您的项目仍在运行,则它不会变成异步。

如果您通过-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector添加属性,则在删除disruptor项目后,项目将无法启动。

如果您正在使用tomcat,则在catalina.properties中添加系统属性。并且不要忘记使用immediateFlush="false"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接