【问题标题】:LOG4J2 - How to create a File appender programmatically?LOG4J2 - 如何以编程方式创建文件附加程序?
【发布时间】:2014-01-01 10:20:58
【问题描述】:

我需要以编程方式设置文件附加程序。

我想在 log4j2.xml 上设置我的附加程序,但我想(以编程方式)在运行时仅写入这些附加程序之一。

<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 上的各种教程,他们解释了如何在运行时以编程方式添加附加程序;有没有办法选择 在运行时只有 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));
    }
}

【问题讨论】:

  • 思科,老兄,你的代码对我帮助很大。在看到您的代码之前,我无法附加我的附加程序。

标签: java logging log4j log4j2 appender


【解决方案1】:

这对我有用。不知道怎么做。我没有更新记录器,也没有重新配置上下文。

    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);

【讨论】:

  • 不确定,那你怎么把它作为答案发布?
  • 好吧,它可以完成这项工作。但是任何关于它如何工作的解释都会很有用。
  • 这是对这些记录器的不必要的复杂性的控诉,而不是反映 Ash 真诚地提供帮助的努力。
  • 太棒了!正是我将遗留代码迁移到 log4j2 所需要的。
【解决方案2】:

自从提出这个问题以来已经有一段时间了,并且已经有许多请求支持更好的 Log4j 2 编程配置。从 Log4j 2.4 开始,API 被添加到 log4j-core 以方便programmatic configuration

新的ConfigurationBuilder API 允许用户构造组件定义。使用此 API,无需直接使用实际配置对象(如 LoggerConfig 和 FileAppender),这需要大量了解 Log4j 如何在后台工作的知识。组件定义被添加到 ConfigurationBuilder 中,一旦收集了所有定义,所有实际的配置对象(如 Loggers 和 Appenders)就会被构建。感觉有点像 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!

【讨论】:

  • 手册的链接:“初始化后以编程方式修改当前配置”部分提供了几个示例,非常有用。
【解决方案3】:

我向 log4j2 团队报告了这个问题,他们告诉我他们会尽快解决。

https://issues.apache.org/jira/browse/LOG4J2-468

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-14
    • 2013-03-04
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2014-01-31
    • 1970-01-01
    相关资源
    最近更新 更多