我正在尝试在当前在自由配置文件服务器中运行的REST Web方法中设置异步日志记录(出于性能原因)。
为此,我设置了以下属性:
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
我的问题是,无论我在哪里这样做,有时候它都能正常工作,而且记录非常快,有时却没有。
我在包含所有REST Web方法的类的构造函数中尝试过(a) (b)在REST方法之前调用的过滤器doFilter方法中 (c)在过滤器初始化方法中 (d)在REST方法本身
这些地点都不一致。
任何人都可以提供此行为的解释,如果可能的话,建议解决问题的方法。
编辑:在调用setProperty之前,似乎正在初始化log4j。所以我需要做的是通过自由配置文件设置属性。
答案 0 :(得分:15)
有一种未记录的方法可以为您的项目设置此值,而无需在启动期间手动传入系统属性值。
将名为log4j2.component.properties
的文件添加到类路径中。这可以在大多数maven或gradle项目中完成,方法是将其保存在src/main/resources
。
这个文件只是java.util.Properties
文件。通过将以下行添加到文件来设置上下文选择器的值。
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
Log4j将首先尝试读取系统属性。如果系统属性为null,则默认情况下它将回退到存储在此文件中的值。
执行此设置的代码位于Log4jContextFactory.java:91。
答案 1 :(得分:1)
我的问题是,无论我在哪里这样做,有时它都有效,而且记录非常快,有时它不会。
将该代码添加到定义主入口点的类中的静态初始化程序块中。
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初始化之前发生。
答案 2 :(得分:0)
显然我需要在jvm.options文件中添加一行
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
jvm.options文件位于:
${server.config.dir}/jvm.options
可以使用以下链接找到该目录:
就我而言,它位于:C:\ eclipse \ runtime \ usr \ servers \ serverName
答案 3 :(得分:0)
在调用main方法之前初始化了Log4j。所以它无法从系统中选择你的属性Log4jContextSelector,默认情况下,它同步工作。
要验证相同:删除disruptor依赖项,如果你的项目仍在上升,那么它就不会异步。
如果你通过-DLog4jContextSelector = org.apache.logging.log4j.core.async.AsyncLoggerContextSelector添加属性,那么删除disruptor项目后就不会了。
如果您使用的是tomcat,请在catalina.properties中添加系统属性。并且不要忘记使用immediateFlush =“false”。