简体   繁体   中英

Log4j2: Programatically remove the existing appenders and add new RollingFileAppender dynamically for all loggers

We have a requirement to add the rolling file appender programmatically in application startup. And also I need to remove the existing appenders(which are configured from log4j2.xml file). I tried various approaches, but it didnt worked for me.

The problems I'm facing now are:

  1. Some logs are still coming to the old appenders.
  2. If I update logger level(from INFO to DEBUG ) for any logger package those things also not coming properly.
        LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
        Configuration configuration = loggerContext.getConfiguration();

        //Removing the existing appenders
        configuration.getAppenders().keySet().forEach(((AbstractConfiguration)configuration)::removeAppender);
        
        String rollingAppenderName = "RollAppender";
        RollingFileAppender rollingFileAppender = RollingFileAppender.newBuilder()
                .setConfiguration(configuration)
                .setName(rollingAppenderName)
                .setLayout(layout)
                .withFileName("/tmp/test.log")
                .withFilePattern("/tmp/test.%i.log")
                .withPolicy(SizeBasedTriggeringPolicy.createPolicy("10MB"))
                .build();
        rollingFileAppender.start();
        configuration.addAppender(rollingFileAppender);

        /*
         * Updating appenders of all the loggerConfigs configured in the log4j2 config file.
         * */
        LoggerConfig rootLogger = configuration.getRootLogger();
        

        Map<String, LoggerConfig> loggerMap = configuration.getLoggers();
        for (LoggerConfig loggerConfig : loggerMap.values()) {
            AppenderRef appenderRef = AppenderRef.createAppenderRef(rollingAppenderName, loggerConfig.getLevel(), loggerConfig.getFilter());
            AppenderRef[] refs = new AppenderRef[]{appenderRef};
            if (Objects.equals(loggerConfig.getName(), rootLogger.getName())) {
                loggerConfig = LoggerConfig.RootLogger.createLogger("true", loggerConfig.getLevel(),
                        Boolean.toString(loggerConfig.isIncludeLocation()), refs, null, configuration, loggerConfig.getFilter());
                loggerConfig.addAppender(rollingFileAppender, loggerConfig.getLevel(), loggerConfig.getFilter());
            } else {
                loggerConfig = LoggerConfig.createLogger(true, loggerConfig.getLevel(), loggerConfig.getName(),
                        Boolean.toString(loggerConfig.isIncludeLocation()), refs, null, configuration, loggerConfig.getFilter());
            }

            configuration.removeLogger(loggerConfig.getName());
            configuration.addLogger(loggerConfig.getName(), loggerConfig);
        }

        loggerContext.updateLoggers();

The approach you are taking is incorrect. Trying to manipulate the existing configuration in the way you are will result in log events being lost while you are messing with the configuration. Instead, create a new configuration and once it is constructed replace the old configuration with the new one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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