繁体   English   中英

Log4j2 日志未指向正确的日志文件

[英]Log4j2 logs are not directing to correct log file

我遇到了以编程方式配置 log4j2 日志的问题。

请看下面的代码,我正在创建 class App3 的 2 个对象,我想创建 2 个调试日志文件(每个 App3 对象一个日志文件),此后每个 object 应该能够登录到相应的日志文件。

但是我的代码在创建第二个日志后将所有日志记录到第二个日志文件中。 有人可以帮忙吗。

Output的程序

文件名:app3_logger1.log_debug.log

2020-06-16 16:19:31,100 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1

文件名:app3_logger2.log_debug.log

2020-06-16 16:19:31,211 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,217 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2

Java Class - 你只需要添加log4j2依赖编译

public class App3 {

public Logger logger;

public static void main(String[] args) {
    App3 app1 = new App3();
    app1.initializeYourLogger("app3_logger1.log", "%d %p %c [%t] %m%n");
    app1.testProg("app3_logger1");
    App3 app2 = new App3();
    app2.initializeYourLogger("app3_logger2.log", "%d %p %c [%t] %m%n");
    app2.testProg("app3_logger2");

    app2.testProg("app3_logger2");
    app1.testProg("app3_logger1");
    app1.testProg("app3_logger1");
    app2.testProg("app3_logger2");

}

public void testProg(String s) {
    logger.debug("Hello from Log4j 2" + s);
}

public void initializeYourLogger(String fileName, String pattern) {
    this.logger = LogManager.getLogger(fileName);
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

    builder.setStatusLevel(Level.DEBUG);
    builder.setConfigurationName(fileName);

    AppenderComponentBuilder componentBuilder = builder.newAppender("log", "File");
    componentBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", pattern));
    RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);

    LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout").addAttribute("pattern", pattern);
    ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
            .addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));

    componentBuilder = builder.newAppender("LogToRollingErrorFile", "RollingFile")
            .add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
                    .addAttribute("level", Level.ERROR))
            .addAttribute("fileName", fileName + "_error.log")
            .addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_error.log").add(layoutBuilder)
            .addComponent(triggeringPolicy);
    builder.add(componentBuilder);

    componentBuilder = builder.newAppender("LogToRollingDebugFile", "RollingFile")
            .add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
                    .addAttribute("level", Level.DEBUG))
            .addAttribute("fileName", fileName + "_debug.log")
            .addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_debug.log").add(layoutBuilder)
            .addComponent(triggeringPolicy);
    builder.add(componentBuilder);

    AppenderRefComponentBuilder rollingError = rootLogger.getBuilder().newAppenderRef("LogToRollingErrorFile");
    AppenderRefComponentBuilder rollingDebug = rootLogger.getBuilder().newAppenderRef("LogToRollingDebugFile");
    rootLogger.add(rollingError);
    rootLogger.add(rollingDebug);
    builder.add(rootLogger);
    Configurator.reconfigure(builder.build());
}

}

这正是我想要在 log4j 旧版本中做的事情,我还在为 log4j2 苦苦挣扎,

    private void initLogger(String serviceName, String instance) throws IOException {
    String loggerName = serviceName+"_"+instance;
    this.logger = Logger.getLogger(loggerName);
    this.logger.removeAllAppenders();

    PatternLayout layout = new PatternLayout();
    layout.setConversionPattern("%d: %m%n");

    String loggingFolder = this.properties.getLoggingFolder();
    String debugFileName = loggingFolder+"/"+loggerName+"_debug.log";
    String errorFileName = loggingFolder+"/"+loggerName+"_error.log";

    RollingFileAppender debugAppender = new RollingFileAppender(layout, debugFileName, true);
    debugAppender.setThreshold(Level.DEBUG);
    debugAppender.setMaxFileSize("10000000");
    debugAppender.setMaxBackupIndex(49);
    logger.addAppender(debugAppender);

    RollingFileAppender errorAppender = new RollingFileAppender(layout, errorFileName, true);
    errorAppender.setThreshold(Level.ERROR);
    errorAppender.setMaxFileSize("10000000");
    errorAppender.setMaxBackupIndex(49);
    logger.addAppender(debugAppender);
}

实际上,我很确定您的 Logger 正在正确更新。 问题是两个应用程序实例都将使用相同的日志记录配置。

如果您查看Log4j 的架构,您会发现 Loggers 和配置都锚定在 LoggerContext 中。 默认情况下,Log4j 使用 ClassLoaderContextSelector,这意味着每个 ClassLoader 都可以有自己的 LoggerContext。 您的示例应用程序只有一个 ClassLoader,因此只有一个 LoggerContext,因此只有一个 Configuration。

因此,当您第二次重新配置时,您只需将之前的配置替换为新配置即可。 由于根记录器正在处理所有日志事件,它会将事件从您创建的两个记录器路由到在第二个配置中创建的文件。

如果您希望日志最终位于两个不同的文件中,则使用这两个文件创建一个配置,并找出一种方法将它们路由到正确的文件,无论是通过记录器名称还是过滤器。

根据观察,您的记录器使用上次初始化更新,因此在app2.initializeYourLogger()之后,您的对象级logger object 使用 App2 配置更新。

您需要从initializeYourLogger()返回记录器 object 并创建单独的记录器 object。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM