Jakie są różne podejścia do dynamicznej zmiany poziomu dziennika log4j, aby nie musieć ponownie wdrażać aplikacji. Czy w tych przypadkach zmiany będą trwałe?
Jakie są różne podejścia do dynamicznej zmiany poziomu dziennika log4j, aby nie musieć ponownie wdrażać aplikacji. Czy w tych przypadkach zmiany będą trwałe?
Odpowiedzi:
Zmiana poziomu dziennika jest prosta; modyfikowanie innych części konfiguracji będzie stanowić bardziej szczegółowe podejście.
LogManager.getRootLogger().setLevel(Level.DEBUG);
Zmiany są trwałe w całym cyklu życia Logger
. Podczas ponownej inicjalizacji konfiguracja zostanie odczytana i wykorzystana, ponieważ ustawienie poziomu w czasie wykonywania nie utrwala zmiany poziomu.
AKTUALIZACJA: Jeśli używasz Log4j 2, powinieneś usunąć wywołania setLevel
zgodnie z dokumentacją, ponieważ można to osiągnąć za pomocą klas implementacji.
Wywołania logger.setLevel () lub podobne metody nie są obsługiwane w interfejsie API. Aplikacje powinny je usunąć. Równoważne funkcje są dostępne w klasach implementacji Log4j 2, ale mogą pozostawić aplikację podatną na zmiany w wewnętrznych elementach Log4j 2.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4j jest w stanie obserwować log4j.xml
plik pod kątem zmian konfiguracji. Jeśli zmienisz plik log4j, log4j automatycznie odświeży poziomy dziennika zgodnie ze zmianami. Zobacz dokumentację org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
), aby uzyskać szczegółowe informacje. Domyślny czas oczekiwania między sprawdzeniami to 60 sekund. Te zmiany byłyby trwałe, ponieważ bezpośrednio zmieniasz plik konfiguracyjny w systemie plików. Wystarczy raz wywołać DOMConfigurator.configureAndWatch ().
Uwaga: metoda configureAndWatch nie jest bezpieczna w środowiskach J2EE ze względu na wyciek wątku
Innym sposobem ustawienia poziomu dziennika (lub ogólnie rekonfiguracji) log4j jest użycie JMX. Log4j rejestruje swoje loggery jako JMX MBean. Korzystając z konsol MBeanServer serwerów aplikacji (lub jconsole.exe JDK) można rekonfigurować poszczególne rejestratory. Te zmiany nie są trwałe i zostaną zresetowane do konfiguracji określonej w pliku konfiguracyjnym po ponownym uruchomieniu aplikacji (serwera).
Zgodnie z opisem Aarona, poziom dziennika można ustawić programowo. Możesz zaimplementować to w swojej aplikacji tak, jak byś chciał. Na przykład możesz mieć GUI, w którym użytkownik lub administrator zmienia poziom dziennika, a następnie wywołuje setLevel()
metody w programie rejestrującym. To, czy utrzymasz ustawienia gdzieś, czy nie, zależy od Ciebie.
Log4j2 można skonfigurować tak, aby odświeżał swoją konfigurację, skanując plik log4j 2 .xml (lub odpowiednik) w określonych odstępach czasu. Po prostu dodaj parametr „ monitorInterval ” do tagu konfiguracyjnego. Zobacz wiersz 2 przykładowego pliku log4j 2 .xml, w którym program log4j ma przeskanować swoją konfigurację, jeśli minęło więcej niż 5 sekund od ostatniego zdarzenia w dzienniku.
<?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>
Istnieją dodatkowe kroki, aby to zadziałało, jeśli wdrażasz w instancji tomcat, wewnątrz IDE lub podczas korzystania z rozruchu sprężynowego. Wydaje się to nieco poza zakresem i prawdopodobnie zasługuje na osobne pytanie.
Ta odpowiedź nie pomoże Ci dynamicznie zmienić poziomu logowania, musisz zrestartować usługę, jeśli możesz ponownie uruchomić usługę, skorzystaj z poniższego rozwiązania
Zrobiłem to, aby zmienić poziom dziennika log4j i zadziałało, nie poleciłem żadnego dokumentu. Użyłem tej wartości właściwości systemowej, aby ustawić nazwę mojego pliku dziennika. Użyłem tej samej techniki do ustawienia poziomu rejestrowania i zadziałało
przekazałem to jako parametr JVM (używam Java 1.7)
Przepraszamy, to nie zmieni dynamicznie poziomu logowania, wymaga ponownego uruchomienia usługi
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
w pliku log4j.properties dodałem ten wpis
log4j.rootLogger=${logging.level},file,stdout
próbowałem
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
Wszystko działało. mam nadzieję że to pomoże!
Mam następujące zależności w moim 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>
Z log4j 1.x uważam, że najlepszym sposobem jest użycie DOMConfigurator do przesłania jednej z predefiniowanych konfiguracji dziennika XML (powiedzmy, jednej do normalnego użytku, a drugiej do debugowania).
Skorzystanie z tych można zrobić za pomocą czegoś takiego:
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");
}
}
Po prostu wywołaj to z odpowiednią nazwą konfiguracji i upewnij się, że umieściłeś szablony w ścieżce klas.
Z powodzeniem korzystałem z tej metody w celu zmniejszenia szczegółowości dzienników „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);
W przypadku interfejsu API log4j 2 możesz użyć
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Jeśli chcesz zmienić poziom rejestrowania wszystkich rejestratorów, użyj poniższej metody. Spowoduje to wyliczenie wszystkich rejestratorów i zmianę poziomu rejestrowania na dany poziom. Upewnij się, że NIE masz log4j.appender.loggerName.Threshold=DEBUG
ustawionej właściwości w swoim log4j.properties
pliku.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Możesz użyć następującego fragmentu kodu
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));