Программно изменить уровень журнала в Log4j2
Я заинтересован в программном изменении уровня журнала в Log4j2. Я пытался смотреть на их настройки документация но это, казалось, не было ничего. Я также попытался посмотреть в пакете:org.apache.logging.log4j.core.config, но ничего там не выглядело полезным либо.
7 ответов:
отредактировано в соответствии с log4j2 версии 2.4 FAQ
вы можете установить уровень регистратора с Конфигуратором класса из ядра Log4j. но имейте в виду, что класс конфигуратора не является частью публичного 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);отредактировано для отражения изменений в 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универсальное использование:Configurator.setAllLevels(LogManager.getRootLogger().getName(), level);изменить журнал
Levelтолько для текущего класса, использовать:Configurator.setLevel(LogManager.getLogger(CallingClass.class).getName(), level);
Я нашел хороший ответ здесь: https://garygregory.wordpress.com/2016/01/11/changing-log-levels-in-log4j2/
вы можете использовать org.апаш.лесозаготовительный.log4j. core.конфиг.Конфигуратор для установки уровня для конкретного регистратора.
Logger logger = LogManager.getLogger(Test.class); Configurator.setLevel(logger.getName(), Level.DEBUG);
программный подход является довольно навязчивым. Возможно, вам следует проверить поддержку JMX, предоставленную Log4J2:
включите порт JMX в вашем приложении start up:
- Dcom.солнце.управление.jmxremote.port=[port_num]
используйте любой из доступных клиентов JMX (JVM предоставляет один в JAVA_HOME/bin/jconsole.exe) при выполнении вашего приложения.
в JConsole ищите "орг.апаш.лесозаготовительный.log4j2.Лесорубы " Боб
наконец-то изменить уровень вашего регистратора
больше всего мне нравится то, что вам не нужно изменять свой код или конфигурацию для управления этим. Его все внешние и прозрачные.
дополнительная информация: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("a.b.c") could return logger for "a.b" if there is no logger for "a.b.c" 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<String, Appender> 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("a.b.c"); logger.debug("Marvel-1"); logConfigManager.setLogLevel("a.b.c", "debug"); logger.debug("DC-1"); // Parent logger level should remain same LoggerFactory.getLogger("a.b").debug("Marvel-2"); logConfigManager.setLogLevel("a.b.c", "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 находится в classpath
<?xml version="1.0" encoding="UTF-8"?> <Configuration xmlns="http://logging.apache.org/log4j/2.0/config"> <Appenders> <File name="FILE" fileName="logs/server.log" append="true"> <PatternLayout pattern="%m%n"/> </File> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%m%n"/> </Console> </Appenders> <Loggers> <AsyncLogger name="a.b" level="info"> <AppenderRef ref="STDOUT"/> <AppenderRef ref="FILE"/> </AsyncLogger> <AsyncRoot level="info"> <AppenderRef ref="STDOUT"/> </AsyncRoot> </Loggers> </Configuration>
один необычный способ, который я нашел, это создать два отдельных файла с разным уровнем ведения журнала.
например. log4j2.xml и log4j-отладка.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));
Comments