LOG4J2 - 如何以编程方式创建File appender?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LOG4J2 - 如何以编程方式创建File appender?相关的知识,希望对你有一定的参考价值。
我需要以编程方式设置File appender。
我想在log4j2.xml上设置我的appender但是我想在运行时只编程(编程)到其中一个appender。
<Configuration status="WARN">
<Appenders>
<File name="File_1" fileName="c:/FILE_1.log" >
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<File name="File_2" fileName="c:/FILE_2.log" >
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<File name="File_3" fileName="c:/FILE_3.log" >
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="File_1"/>
<AppenderRef ref="File_2"/>
<AppenderRef ref="File_3"/>
</Root>
</Loggers>
例:
if(condition.equals("A")){
//write log on File_1
}else if(condition.equals("B")){
//write log on File_2
}else {
//write log on File_3
}
查看Internet中的各种教程,他们解释了如何在运行时以编程方式添加appender;有没有办法在运行时选择只有一个在xml配置文件中定义的appender?
第一个解决方案:
我试图通过以下方式解决问题,但我对我的解决方案不满意,因为log4j2.xml中定义的文件没有以编程方式删除而且第一个Appender永远不会被删除!我认为log4j2中存在一个错误:https://issues.apache.org/jira/browse/LOG4J2-135(状态已解决,但我不这么认为......我正在使用log4j-2.0-beta9)
static org.apache.logging.log4j.core.Logger coreLogger =
(org.apache.logging.log4j.core.Logger)LogManager.getLogger(MyClass.class.getName());
static LoggerContext context = (LoggerContext)coreLogger.getContext();
static BaseConfiguration configuration = (BaseConfiguration)context.getConfiguration();
static String FILE_1 = "File_1";
static String FILE_2 = "File_2";
static String FILE_3 = "File_3";
private static Map<String, Boolean> appendersMap;
static
{
appendersMap = new HashMap<String, Boolean>();
appendersMap.put(FILE_1, true);
appendersMap.put(FILE_2, true);
appendersMap.put(FILE_3, true);
}
/**
* Configure appenders.
*
* @param appender the appender
*/
public static void configureAppenders(String appender){
if(appender.equals(FILE_1)){
addAppenders(FILE_1);
removeAppenders(FILE_2,FILE_3);
}
else if(appender.equals(FILE_3)){
addAppenders(FILE_3);
removeAppenders(FILE_1,FILE_2);
}
else if(appender.equals(FILE_2)){
addAppenders(FILE_2);
removeAppenders(FILE_1,FILE_3);
}
}
private static void addAppenders(String appender){
if (!appendersMap.get(appender)){
appendersMap.put(appender, true);
coreLogger.addAppender(configuration.getAppender(appender));
}
}
private static void removeAppenders(String... appenders){
for(String appender : appenders){
appendersMap.put(appender, false);
coreLogger.removeAppender(configuration.getAppender(appender));
}
}
我向log4j2团队报告了这个问题,他们告诉我他们很快就会修复它。
https://issues.apache.org/jira/browse/LOG4J2-468
自问这个问题以来已经有一段时间了,并且已经有很多请求支持Log4j 2的更好的编程配置。从Log4j 2.4开始,API被添加到log4j-core以便于programmatic configuration。
新的ConfigurationBuilder
API允许用户构建组件定义。使用此API,无需直接使用实际配置对象(如LoggerConfig和FileAppender),这些对象需要大量了解Log4j如何在底层工作。组件定义被添加到ConfigurationBuilder中,一旦收集了所有定义,就构造了所有实际配置对象(如Loggers和Appender)。感觉有点像XML配置语法,除了您正在编写Java代码。
请注意,新的ConfigurationBuilder
API允许用户代码创建新配置或完全替换现有配置。如果您的用例不同,并且您希望在Log4j启动后以编程方式修改(而不是替换)现有配置,那么您将需要使用实际的配置对象。在这种情况下,请参阅手册的Programmatically Modifying the Current Configuration after Initialization部分。
如果您确实需要直接使用内部配置对象,请注意您需要在末尾调用LoggerContext.updateLoggers()
或Configurator.initialize(Configuration)
以使更改生效。例如:
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
... // make changes
ctx.updateLoggers(); // NECESSARY!
这对我有用。不确定如何。我没有更新记录器,也没有重新配置上下文。
Logger coreLogger = (Logger)LogManager.getLogger(LoggingStuff.class.getName());
Layout layout = ((LoggerContext)LogManager.getContext()).getConfiguration().getAppender("Console").getLayout();
Appender appender = FileAppender.newBuilder().withName("File").withFileName("target/bash.log").withLayout(layout).build();
appender.start();
coreLogger.addAppender(appender);
以上是关于LOG4J2 - 如何以编程方式创建File appender?的主要内容,如果未能解决你的问题,请参考以下文章