Программно изменить уровень журнала в Log4j2

Я заинтересован в программном изменении уровня журнала в Log4j2. Я попытался посмотреть их конфигурационную документацию, но, похоже, ничего не было. Я также пробовал посмотреть в пакете: org.apache.logging.log4j.core.config , но ничего там не оказалось полезным.

    EDITED согласно версии log4j2 2.4 Часто задаваемые вопросы

    Вы можете установить уровень журнала с помощью classа Configurator из Log4j Core. НО имейте в виду, что class Configurator не является частью общедоступного API.

     // org.apache.logging.log4j.core.config.Configurator; Configurator.setLevel("com.example.Foo", Level.DEBUG); // You can also set the root logger: Configurator.setRootLevel(Level.DEBUG); 

    Источник

    EDITED отражают изменения в API, представленные в версии Log4j2 версии 2.0.2

    Если вы хотите изменить уровень корневого регистратора, выполните следующие действия:

     LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration(); LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); loggerConfig.setLevel(level); ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig. 

    Вот javadoc для LoggerConfig.

    Если вы хотите изменить один определенный уровень регистратора (не корневой регистратор или журналы, настроенные в файле конфигурации), вы можете сделать это:

     public static void setLevel(Logger logger, Level level) { final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); final Configuration config = ctx.getConfiguration(); LoggerConfig loggerConfig = config.getLoggerConfig(logger.getName()); LoggerConfig specificConfig = loggerConfig; // We need a specific configuration for this logger, // otherwise we would change the level of all other loggers // having the original configuration as parent as well if (!loggerConfig.getName().equals(logger.getName())) { specificConfig = new LoggerConfig(logger.getName(), level, true); specificConfig.setParent(loggerConfig); config.addLogger(logger.getName(), specificConfig); } specificConfig.setLevel(level); ctx.updateLoggers(); } 

    Принятый ответ от @slaadvak не работал для меня для Log4j2 2.8.2 . Было сделано следующее.

    Чтобы изменить общий Level журнала, Level :

     Configurator.setAllLevels(LogManager.getRootLogger().getName(), level); 

    Чтобы изменить уровень журнала только для текущего classа, используйте:

     Configurator.setLevel(LogManager.getLogger(CallingClass.class).getName(), level); 

    Я нашел здесь хороший ответ: https://garygregory.wordpress.com/2016/01/11/changing-log-levels-in-log4j2/

    Вы можете использовать org.apache.logging.log4j.core.config.Configurator, чтобы установить уровень для определенного регистратора.

     Logger logger = LogManager.getLogger(Test.class); Configurator.setLevel(logger.getName(), Level.DEBUG); 

    Программный подход довольно навязчивый. Возможно, вам стоит проверить поддержку JMX, предоставленную Log4J2:

    1. Включите порт JMX в вашем приложении:

      -Dcom.sun.management.jmxremote.port = [port_num]

    2. Используйте любой из доступных JMX-клиентов (JVM предоставляет один в JAVA_HOME / bin / jconsole.exe) во время выполнения вашего приложения.

    3. В JConsole найдите компонент “org.apache.logging.log4j2.Loggers”

    4. Наконец, измените уровень вашего регистратора

    Мне больше всего нравится то, что вам не нужно изменять свой код или конфигурацию для управления этим. Все это внешнее и прозрачное.

    Дополнительная информация: http://logging.apache.org/log4j/2.x/manual/jmx.html

    Большинство ответов по умолчанию предполагают, что регистрация должна быть аддитивной. Но скажите, что какой-то пакет генерирует множество журналов, и вы хотите отключить ведение журнала только для этого конкретного регистратора. Вот код, который я использовал, чтобы заставить его работать

      public class LogConfigManager { public void setLogLevel(String loggerName, String level) { Level newLevel = Level.valueOf(level); LoggerContext logContext = (LoggerContext) LogManager.getContext(false); Configuration configuration = logContext.getConfiguration(); LoggerConfig loggerConfig = configuration.getLoggerConfig(loggerName); // getLoggerConfig("abc") could return logger for "ab" if there is no logger for "abc" if (loggerConfig.getName().equalsIgnoreCase(loggerName)) { loggerConfig.setLevel(newLevel); log.info("Changed logger level for {} to {} ", loggerName, newLevel); } else { // create a new config. loggerConfig = new LoggerConfig(loggerName, newLevel, false); log.info("Adding config for: {} with level: {}", loggerConfig, newLevel); configuration.addLogger(loggerName, loggerConfig); LoggerConfig parentConfig = loggerConfig.getParent(); do { for (Map.Entry entry : parentConfig.getAppenders().entrySet()) { loggerConfig.addAppender(entry.getValue(), null, null); } parentConfig = parentConfig.getParent(); } while (null != parentConfig && parentConfig.isAdditive()); } logContext.updateLoggers(); } } 

    Тест для одного и того же

     public class LogConfigManagerTest { @Test public void testLogChange() throws IOException { LogConfigManager logConfigManager = new LogConfigManager(); File file = new File("logs/server.log"); Files.write(file.toPath(), new byte[0], StandardOpenOption.TRUNCATE_EXISTING); Logger logger = LoggerFactory.getLogger("abc"); logger.debug("Marvel-1"); logConfigManager.setLogLevel("abc", "debug"); logger.debug("DC-1"); // Parent logger level should remain same LoggerFactory.getLogger("ab").debug("Marvel-2"); logConfigManager.setLogLevel("abc", "info"); logger.debug("Marvel-3"); // Flush everything LogManager.shutdown(); String content = Files.readAllLines(file.toPath()).stream().reduce((s1, s2) -> s1 + "\t" + s2).orElse(null); Assert.assertEquals(content, "DC-1"); } } 

    Предполагая, что следующий log4j2.xml находится в пути к classам

                         

    Один необычный способ, который я нашел, – создать два отдельных файла с различным уровнем ведения журнала.
    Например. log4j2.xml и log4j-debug.xml Теперь измените конфигурацию из этих файлов.
    Образец кода:

     ConfigurationFactory configFactory = XmlConfigurationFactory.getInstance(); ConfigurationFactory.setConfigurationFactory(configFactory); LoggerContext ctx = (LoggerContext) LogManager.getContext(false); ClassLoader classloader = Thread.currentThread().getContextClassLoader(); InputStream inputStream = classloader.getResourceAsStream(logFileName); ConfigurationSource configurationSource = new ConfigurationSource(inputStream); ctx.start(configFactory.getConfiguration(ctx, configurationSource)); 
    Interesting Posts
    Давайте будем гением компьютера.