如何延迟日志文件的创建,直到以编程方式为 log4j2 设置 Appender 文件名
How to delay log file creation until Appender fileName is set programmatically for log4j2
我有一个项目,其 log4j 属性在 xml 中定义。
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
<Appenders>
<File name="LogFileAppender" fileName="${sys:logFileName:-default}" append="false">
<PatternLayout>
<Pattern>%d [%t] %p - %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="LogFileAppender"/>
</Root>
</Loggers>
</Configuration>
在进行任何日志记录以获取正确的输出文件夹之前,我将 fileName 值更新为代码中的正确路径。
public static void initializeLoggers(String logPath)
{
// set output paths for log files
System.setProperty("logFileName", logPath + "PROJECT.log");
// reconfigure loggers with paths
org.apache.logging.log4j.core.LoggerContext ctx =
(org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();
}
大部分情况下一切都按预期进行。日志文件输出到正确的 logPath 并写出数据。但是,由于调用
,在我们到达 initializeLoggers() 之前,在默认项目目录中创建了一个名为“default”的文件
static Logger log = LogManager.getLogger(MyClass.class); // Logging
在代码的顶部。
我发现只需将字段留空就不会生成“默认文件”,如下所示:
fileName="${sys:logFileName:-}"
但是在这样做的过程中,代码会抱怨并给出错误,因为 属性 在那个特定时间为空。
2022-01-19 13:07:51,936 main ERROR The parameter is null: fileName
2022-01-19 13:07:51,944 main ERROR Could not create plugin of type
class org.apache.logging.log4j.core.appender.FileAppender for element
File org.apache.logging.log4j.core.config.ConfigurationException:
Arguments given for element File are invalid: field 'fileName' has
invalid value '' at
org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.injectFields(PluginBuilder.java:210)
有什么办法可以解决这个问题
- 不生成未使用的“默认文件”
- 没有抛出关于空值的错误
如果要延迟Log4j的初始化,需要谨慎控制LogManager.getLogger
等类似方法的使用。例如,您不应在 main class 中使用静态 Logger
字段,而应仅在 after[=25] 中调用 LogManager.getLogger
=] 您初始化了日志记录。
要做到这一点可能有点棘手,但系统 属性 log4j2.loggerContextStacktraceOnStart
可以帮助您。
一种更简单的方法是将配置文件移出自动配置过程,例如通过调用它 myapp-log4j2.xml
。这样,第一个配置将使用默认配置(仅使用控制台附加程序),您可以在设置适当的系统变量后重新配置它:
private static final String CONFIG_FILE = "myapp-log4j2.xml";
public static void initializeLoggers(String logPath) {
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
final ClassLoader cl = SomeClass.class.getClassLoader();
final URL resource = tccl != null ? tccl.getResource(CONFIG_FILE)
: cl != null ? cl.getResource(CONFIG_FILE) : ClassLoader.getSystemResource(CONFIG_FILE);
if (resource != null) {
System.setProperty("logFileName", logPath + "PROJECT.log");
Configurator.reconfigure(resource.toURI());
}
}
我有一个项目,其 log4j 属性在 xml 中定义。
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
<Appenders>
<File name="LogFileAppender" fileName="${sys:logFileName:-default}" append="false">
<PatternLayout>
<Pattern>%d [%t] %p - %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="LogFileAppender"/>
</Root>
</Loggers>
</Configuration>
在进行任何日志记录以获取正确的输出文件夹之前,我将 fileName 值更新为代码中的正确路径。
public static void initializeLoggers(String logPath)
{
// set output paths for log files
System.setProperty("logFileName", logPath + "PROJECT.log");
// reconfigure loggers with paths
org.apache.logging.log4j.core.LoggerContext ctx =
(org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();
}
大部分情况下一切都按预期进行。日志文件输出到正确的 logPath 并写出数据。但是,由于调用
,在我们到达 initializeLoggers() 之前,在默认项目目录中创建了一个名为“default”的文件static Logger log = LogManager.getLogger(MyClass.class); // Logging
在代码的顶部。
我发现只需将字段留空就不会生成“默认文件”,如下所示:
fileName="${sys:logFileName:-}"
但是在这样做的过程中,代码会抱怨并给出错误,因为 属性 在那个特定时间为空。
2022-01-19 13:07:51,936 main ERROR The parameter is null: fileName 2022-01-19 13:07:51,944 main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.FileAppender for element File org.apache.logging.log4j.core.config.ConfigurationException: Arguments given for element File are invalid: field 'fileName' has invalid value '' at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.injectFields(PluginBuilder.java:210)
有什么办法可以解决这个问题
- 不生成未使用的“默认文件”
- 没有抛出关于空值的错误
如果要延迟Log4j的初始化,需要谨慎控制LogManager.getLogger
等类似方法的使用。例如,您不应在 main class 中使用静态 Logger
字段,而应仅在 after[=25] 中调用 LogManager.getLogger
=] 您初始化了日志记录。
要做到这一点可能有点棘手,但系统 属性 log4j2.loggerContextStacktraceOnStart
可以帮助您。
一种更简单的方法是将配置文件移出自动配置过程,例如通过调用它 myapp-log4j2.xml
。这样,第一个配置将使用默认配置(仅使用控制台附加程序),您可以在设置适当的系统变量后重新配置它:
private static final String CONFIG_FILE = "myapp-log4j2.xml";
public static void initializeLoggers(String logPath) {
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
final ClassLoader cl = SomeClass.class.getClassLoader();
final URL resource = tccl != null ? tccl.getResource(CONFIG_FILE)
: cl != null ? cl.getResource(CONFIG_FILE) : ClassLoader.getSystemResource(CONFIG_FILE);
if (resource != null) {
System.setProperty("logFileName", logPath + "PROJECT.log");
Configurator.reconfigure(resource.toURI());
}
}