简体   繁体   English

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

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

I am facing an issue with configuring log4j2 logs programmatically.我遇到了以编程方式配置 log4j2 日志的问题。

Please see the below code, I am creating 2 objects of the class App3, and I want to create 2 debug log files(a log file per App3 object), thereafter each object should be able to log to corresponding log file.请看下面的代码,我正在创建 class App3 的 2 个对象,我想创建 2 个调试日志文件(每个 App3 对象一个日志文件),此后每个 object 应该能够登录到相应的日志文件。

But my code is logging all the logs to the second log file after 2nd log is created.但是我的代码在创建第二个日志后将所有日志记录到第二个日志文件中。 Can someone help on this.有人可以帮忙吗。

Output of the program Output的程序

file Name: app3_logger1.log_debug.log文件名:app3_logger1.log_debug.log

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

file Name: app3_logger2.log_debug.log文件名: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 - you just need to add log4j2 dependencies to compile 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());
}

} }

This is exactly what I want to do in log4j older version, I am still struggling with log4j2,这正是我想要在 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);
}

Actually, I am quite sure your Logger is being updated correctly.实际上,我很确定您的 Logger 正在正确更新。 The problem is that both application instances are going to use the same Logging configuration.问题是两个应用程序实例都将使用相同的日志记录配置。

If you look at Log4j's architecture you will see that the Loggers and the configuration are anchored in the LoggerContext.如果您查看Log4j 的架构,您会发现 Loggers 和配置都锚定在 LoggerContext 中。 By default, Log4j uses the ClassLoaderContextSelector, which means that every ClassLoader can have its own LoggerContext.默认情况下,Log4j 使用 ClassLoaderContextSelector,这意味着每个 ClassLoader 都可以有自己的 LoggerContext。 Your sample application only has a single ClassLoader and so will only have a single LoggerContext and, therefore, only a single Configuration.您的示例应用程序只有一个 ClassLoader,因此只有一个 LoggerContext,因此只有一个 Configuration。

So when you reconfigured the second time you simply replaced the prior configuration with the new one.因此,当您第二次重新配置时,您只需将之前的配置替换为新配置即可。 Since the root logger is handling all log events it will route the events from both Loggers you have created to the file created in the second configuration.由于根记录器正在处理所有日志事件,它会将事件从您创建的两个记录器路由到在第二个配置中创建的文件。

If you want logs to end up in two different files then create a configuration with both files and figure out a way to route them to the correct file, either via logger names or filters.如果您希望日志最终位于两个不同的文件中,则使用这两个文件创建一个配置,并找出一种方法将它们路由到正确的文件,无论是通过记录器名称还是过滤器。

As per observation, your logger is updated with the last initialization so after app2.initializeYourLogger() your object-level logger object updated with App2 configuration.根据观察,您的记录器使用上次初始化更新,因此在app2.initializeYourLogger()之后,您的对象级logger object 使用 App2 配置更新。

You need to return the logger object from initializeYourLogger() and also create separate Logger object.您需要从initializeYourLogger()返回记录器 object 并创建单独的记录器 object。

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

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