1
votes

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

1 Answers

-1
votes

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.