Каковы различные подходы к динамическому изменению уровня журнала log4j, чтобы мне не пришлось повторно развертывать приложение. Будут ли изменения в этих случаях постоянными?
Каковы различные подходы к динамическому изменению уровня журнала log4j, чтобы мне не пришлось повторно развертывать приложение. Будут ли изменения в этих случаях постоянными?
Ответы:
Изменить уровень журнала очень просто; изменение других частей конфигурации приведет к более глубокому подходу.
LogManager.getRootLogger().setLevel(Level.DEBUG);
Изменения постоянны на протяжении всего жизненного цикла Logger
. При повторной инициализации конфигурация будет считана и использована, поскольку установка уровня во время выполнения не сохраняет изменение уровня.
ОБНОВЛЕНИЕ: если вы используете Log4j 2, вы должны удалить вызовы в setLevel
соответствии с документацией, поскольку это может быть достигнуто с помощью классов реализации.
Вызовы logger.setLevel () или подобных методов не поддерживаются в API. Приложения должны удалить их. Эквивалентная функциональность предоставляется в классах реализации Log4j 2, но может сделать приложение уязвимым для изменений во внутреннем устройстве Log4j 2.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4j может отслеживать log4j.xml
изменения конфигурации в файле. Если вы измените файл log4j, log4j автоматически обновит уровни журнала в соответствии с вашими изменениями. Подробности см. В документации org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
). По умолчанию время ожидания между проверками составляет 60 секунд. Эти изменения будут постоянными, поскольку вы напрямую меняете файл конфигурации в файловой системе. Все, что вам нужно сделать, это один раз вызвать DOMConfigurator.configureAndWatch ().
Внимание: метод configureAndWatch небезопасен для использования в средах J2EE из-за утечки потока
Другой способ установить уровень журнала (или перенастроить в целом) log4j - использовать JMX. Log4j регистрирует свои регистраторы как JMX MBeans. Используя консоли серверов приложений MBeanServer (или jconsole.exe JDK), вы можете перенастроить каждый отдельный регистратор. Эти изменения не являются постоянными и будут сброшены до конфигурации, установленной в файле конфигурации, после перезапуска приложения (сервера).
Как описано Аароном, вы можете установить уровень журнала программно. Вы можете реализовать это в своем приложении так, как хотите. Например, у вас может быть графический интерфейс, в котором пользователь или администратор изменяет уровень журнала, а затем вызывает setLevel()
методы в регистраторе. Сохраняете ли вы настройки где-нибудь или нет, решать вам.
Log4j2 можно настроить для обновления своей конфигурации путем сканирования файла log4j 2 .xml (или его эквивалента) с заданными интервалами. Просто добавьте параметр monitorInterval в свой тег конфигурации. См. Строку 2 образца файла log4j 2 .xml, в которой log4j сообщает о необходимости повторного сканирования своей конфигурации, если с момента последнего события журнала прошло более 5 секунд.
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">
<Appenders>
<RollingFile name="MY_TRY_IT"
fileName="/var/log/tryIt.log"
filePattern="/var/log/tryIt-%i.log.gz">
<Policies>
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
...
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MY_TRY_IT"/>
</Root>
</Loggers>
</Configuration>
Есть дополнительные шаги, чтобы заставить эту работу работать, если вы выполняете развертывание в экземпляре Tomcat, внутри IDE или при использовании весенней загрузки. Здесь это кажется несколько выходящим за рамки и, вероятно, заслуживает отдельного вопроса.
Этот ответ не поможет вам динамически изменять уровень ведения журнала, вам необходимо перезапустить службу, если вы нормально перезапускаете службу, используйте приведенное ниже решение.
Я сделал это, чтобы изменить уровень журнала log4j, и у меня это сработало, я не ссылался ни на один документ. Я использовал это значение системного свойства, чтобы установить имя файла журнала. Я использовал ту же технику для установки уровня ведения журнала, и это сработало.
передал это как параметр JVM (я использую Java 1.7)
К сожалению, это не приведет к динамическому изменению уровня ведения журнала, для этого требуется перезапуск службы.
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
в файле log4j.properties я добавил эту запись
log4j.rootLogger=${logging.level},file,stdout
Я попытался
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
java -Dlogging.level=INFO-cp xxxxxx.jar xxxxx.java
java -Dlogging.level=OFF -cp xxxxxx.jar xxxxx.java
Все заработало. надеюсь это поможет!
У меня есть следующие зависимости в моем pom.xml
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.2.17</version>
</dependency>
С log4j 1.x я считаю, что лучший способ - использовать DOMConfigurator для отправки одной из предопределенных наборов конфигураций журнала XML (скажем, для обычного использования и для отладки).
Их можно использовать примерно так:
public static void reconfigurePredefined(String newLoggerConfigName) {
String name = newLoggerConfigName.toLowerCase();
if ("default".equals(name)) {
name = "log4j.xml";
} else {
name = "log4j-" + name + ".xml";
}
if (Log4jReconfigurator.class.getResource("/" + name) != null) {
String logConfigPath = Log4jReconfigurator.class.getResource("/" + name).getPath();
logger.warn("Using log4j configuration: " + logConfigPath);
try (InputStream defaultIs = Log4jReconfigurator.class.getResourceAsStream("/" + name)) {
new DOMConfigurator().doConfigure(defaultIs, LogManager.getLoggerRepository());
} catch (IOException e) {
logger.error("Failed to reconfigure log4j configuration, could not find file " + logConfigPath + " on the classpath", e);
} catch (FactoryConfigurationError e) {
logger.error("Failed to reconfigure log4j configuration, could not load file " + logConfigPath, e);
}
} else {
logger.error("Could not find log4j configuration file " + name + ".xml on classpath");
}
}
Просто вызовите это с соответствующим именем конфигурации и убедитесь, что вы поместили шаблоны в путь к классам.
Я успешно использовал этот метод, чтобы уменьшить подробность журналов "org.apache.http":
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
Для log4j 2 API вы можете использовать
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Если вы хотите изменить уровень ведения журнала всех регистраторов, используйте метод ниже. Это будет перечислять по всем регистраторам и изменить уровень ведения журнала на заданный уровень. Пожалуйста , убедитесь , что вы НЕ имеете log4j.appender.loggerName.Threshold=DEBUG
набор свойств в вашем log4j.properties
файле.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Вы можете использовать следующий фрагмент кода
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));