Log4J 2 查找值在 loaded/present 之前在配置中使用
Log4J 2 Lookup values are used in config before they are loaded/present
我正在使用 SystemPropertiesLookup 查找来配置我的 Log4J2 配置。系统属性被设置为我的主要方法中的第一行。问题是,当Log4J加载配置时,还没有调用main方法,所以系统属性还没有填写。
这是我的 log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN" packages="org.base">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%highlight{%d [%c{1}] %-5level: %msg%n}{STYLE=Logback}"/>
</Console>
<File name="AppLog" fileName="logs/app-${sys:MIGRATION_ENV:-UNKNOWN}-${sys:MIGRATION_TITLE:-UNKNOWN}.log" append="false">
<PatternLayout pattern="%d [%c{1}] %-5level: %msg%n"/>
</File>
</appenders>
<loggers>
<root level="error">
<appender-ref ref="Console" level="error"/>
<appender-ref ref="AppLog" level="error"/>
</root>
<logger name="org.base" level="debug" additivity="false">
<appender-ref ref="Console" level="debug"/>
<appender-ref ref="AppLog" level="debug"/>
</logger>
</loggers>
</configuration>
该文件将被称为 app-UNKNOWN-UNKNOWN,因为当 Log4J 填充它时,属性尚不可用。
有没有办法让 Log4J 等待,最好不要将配置移动到 Java 代码?
必须在运行时设置属性(main 方法的第一行)。
一个可能的解决方法是只在该方法之后调用 getLogger(..)
,而不是用变量初始化它,但这并不适合我的任务。
您可以使用 RoutingAppender
做您想做的事。这是一些示例代码:
package example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
System.setProperty("myProperty", "myFile.log");
if(log.isDebugEnabled())
log.debug("This is some debug!");
log.info("Here's some info!");
log.error("Some erorr happened!");
}
}
这是 log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<Routing name="Routing">
<Routes pattern="$${sys:myProperty}">
<Route>
<File name="File" fileName="logs/${sys:myProperty}"
immediateFlush="false" append="false">
<PatternLayout
pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" level="debug" />
<AppenderRef ref="Routing" level="debug" />
</Root>
</Loggers>
</Configuration>
运行 上面的 java 代码在当前工作目录的日志文件夹中创建了一个名为 myFile.log 的文件。日志文件的内容类似于以下内容:
2018-05-21 22:13:29.147 [main] DEBUG example.SomeClass - This is some debug!
2018-05-21 22:13:29.160 [main] INFO example.SomeClass - Here's some info!
2018-05-21 22:13:29.161 [main] ERROR example.SomeClass - Some erorr happened!
我正在使用 SystemPropertiesLookup 查找来配置我的 Log4J2 配置。系统属性被设置为我的主要方法中的第一行。问题是,当Log4J加载配置时,还没有调用main方法,所以系统属性还没有填写。
这是我的 log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN" packages="org.base">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%highlight{%d [%c{1}] %-5level: %msg%n}{STYLE=Logback}"/>
</Console>
<File name="AppLog" fileName="logs/app-${sys:MIGRATION_ENV:-UNKNOWN}-${sys:MIGRATION_TITLE:-UNKNOWN}.log" append="false">
<PatternLayout pattern="%d [%c{1}] %-5level: %msg%n"/>
</File>
</appenders>
<loggers>
<root level="error">
<appender-ref ref="Console" level="error"/>
<appender-ref ref="AppLog" level="error"/>
</root>
<logger name="org.base" level="debug" additivity="false">
<appender-ref ref="Console" level="debug"/>
<appender-ref ref="AppLog" level="debug"/>
</logger>
</loggers>
</configuration>
该文件将被称为 app-UNKNOWN-UNKNOWN,因为当 Log4J 填充它时,属性尚不可用。
有没有办法让 Log4J 等待,最好不要将配置移动到 Java 代码?
必须在运行时设置属性(main 方法的第一行)。
一个可能的解决方法是只在该方法之后调用 getLogger(..)
,而不是用变量初始化它,但这并不适合我的任务。
您可以使用 RoutingAppender
做您想做的事。这是一些示例代码:
package example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
System.setProperty("myProperty", "myFile.log");
if(log.isDebugEnabled())
log.debug("This is some debug!");
log.info("Here's some info!");
log.error("Some erorr happened!");
}
}
这是 log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<Routing name="Routing">
<Routes pattern="$${sys:myProperty}">
<Route>
<File name="File" fileName="logs/${sys:myProperty}"
immediateFlush="false" append="false">
<PatternLayout
pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" level="debug" />
<AppenderRef ref="Routing" level="debug" />
</Root>
</Loggers>
</Configuration>
运行 上面的 java 代码在当前工作目录的日志文件夹中创建了一个名为 myFile.log 的文件。日志文件的内容类似于以下内容:
2018-05-21 22:13:29.147 [main] DEBUG example.SomeClass - This is some debug!
2018-05-21 22:13:29.160 [main] INFO example.SomeClass - Here's some info!
2018-05-21 22:13:29.161 [main] ERROR example.SomeClass - Some erorr happened!