log4j2:用于设置异步日志记录的 Log4jContextSelector 系统属性的位置

2022-09-03 04:50:31

我正在尝试在当前在 liberty 概要文件服务器中运行的 REST Web 方法中设置异步日志记录(出于性能原因)。

为此,我设置了以下属性:

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

我的问题是,无论我在哪里这样做,有时它都能工作并且日志记录非常快,有时则不然。

我已经尝试(a)在包含所有REST Web方法的类的构造函数中(b)在过滤器doFilter方法中被调用,该方法在REST方法本身的过滤器初始化方法(d)中的REST方法(c)之前被调用

这些位置都无法始终如一地工作。

任何人都可以为这种行为提供解释,如果可能的话,还可以提供解决问题的建议方法。

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


答案 1

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

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

这是文件,只是文件。通过将以下行添加到文件中来设置上下文选择器的值。java.util.Properties

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

Log4j将首先尝试读取系统属性。如果系统属性为 null,则默认情况下它将回退到此文件中存储的值。

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

File Location


答案 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 规范,静态初始化按声明的顺序进行。因此,保证在 Log4j 初始化之前进行调用。System.setProperty


推荐