Welche unterschiedlichen Ansätze gibt es, um die Protokollstufe log4j dynamisch zu ändern, damit ich die Anwendung nicht erneut bereitstellen muss? Werden die Änderungen in diesen Fällen dauerhaft sein?
Welche unterschiedlichen Ansätze gibt es, um die Protokollstufe log4j dynamisch zu ändern, damit ich die Anwendung nicht erneut bereitstellen muss? Werden die Änderungen in diesen Fällen dauerhaft sein?
Antworten:
Das Ändern der Protokollstufe ist einfach. Das Ändern anderer Teile der Konfiguration bietet einen tieferen Ansatz.
LogManager.getRootLogger().setLevel(Level.DEBUG);
Die Veränderungen sind dauerhaft durch den Lebensstil des Logger
. Bei der Neuinitialisierung wird die Konfiguration gelesen und verwendet, da durch das Festlegen des Pegels zur Laufzeit die Pegeländerung nicht beibehalten wird.
UPDATE: Wenn Sie Log4j 2 verwenden, sollten Sie die Aufrufe setLevel
gemäß der Dokumentation entfernen, da dies über Implementierungsklassen erreicht werden kann.
Aufrufe von logger.setLevel () oder ähnlichen Methoden werden in der API nicht unterstützt. Anwendungen sollten diese entfernen. Gleichwertige Funktionen werden in den Log4j 2-Implementierungsklassen bereitgestellt, können jedoch dazu führen, dass die Anwendung Änderungen an den Log4j 2-Interna unterliegt.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4j kann die log4j.xml
Datei auf Konfigurationsänderungen überwachen . Wenn Sie die log4j-Datei ändern, aktualisiert log4j die Protokollstufen automatisch entsprechend Ihren Änderungen. org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long
Einzelheiten finden Sie in der Dokumentation von ). Die Standardwartezeit zwischen den Überprüfungen beträgt 60 Sekunden. Diese Änderungen bleiben bestehen, da Sie die Konfigurationsdatei direkt im Dateisystem ändern. Sie müssen lediglich DOMConfigurator.configureAndWatch () einmal aufrufen.
Achtung: Die configureAndWatch-Methode ist für die Verwendung in J2EE-Umgebungen aufgrund eines Thread-Lecks nicht sicher
Eine andere Möglichkeit, die Protokollstufe (oder die Neukonfiguration im Allgemeinen) log4j festzulegen, ist die Verwendung von JMX. Log4j registriert seine Logger als JMX-MBeans. Mit den MBeanServer-Konsolen der Anwendungsserver (oder der jconsole.exe von JDK) können Sie jeden einzelnen Logger neu konfigurieren. Diese Änderungen sind nicht dauerhaft und werden nach dem Neustart Ihrer Anwendung (Server) auf die in der Konfigurationsdatei festgelegte Konfiguration zurückgesetzt.
Wie von Aaron beschrieben, können Sie die Protokollstufe programmgesteuert einstellen. Sie können es in Ihrer Anwendung so implementieren, wie Sie es möchten. Beispielsweise könnten Sie eine GUI haben, in der der Benutzer oder Administrator die Protokollstufe ändert und dann die setLevel()
Methoden auf dem Protokollierer aufruft. Ob Sie die Einstellungen irgendwo beibehalten oder nicht, liegt bei Ihnen.
Log4j2 kann so konfiguriert werden, dass seine Konfiguration aktualisiert wird, indem die XML- Datei log4j 2 (oder eine gleichwertige Datei) in bestimmten Intervallen gescannt wird . Fügen Sie einfach den Parameter " monitorInterval " zu Ihrem Konfigurations-Tag hinzu. Siehe Zeile 2 der XML-Beispieldatei log4j 2 , in der log4j angewiesen wird, die Konfiguration erneut zu scannen, wenn seit dem letzten Protokollereignis mehr als 5 Sekunden vergangen sind.
<?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>
Es gibt zusätzliche Schritte, damit dies funktioniert, wenn Sie auf einer Tomcat-Instanz, in einer IDE oder bei Verwendung von Spring Boot bereitstellen. Das scheint hier etwas außerhalb des Rahmens zu liegen und verdient wahrscheinlich eine gesonderte Frage.
Diese Antwort hilft Ihnen nicht dabei, die Protokollierungsstufe dynamisch zu ändern. Sie müssen den Dienst neu starten. Wenn Sie den Dienst problemlos neu starten können, verwenden Sie bitte die folgende Lösung
Ich habe dies getan, um die Protokollstufe log4j zu ändern, und es hat bei mir funktioniert. Ich habe kein Dokument weitergeleitet. Ich habe diesen Systemeigenschaftswert verwendet, um meinen Protokolldateinamen festzulegen. Ich habe dieselbe Technik verwendet, um auch die Protokollierungsstufe festzulegen, und es hat funktioniert
hat dies als JVM-Parameter übergeben (ich verwende Java 1.7)
Dies ändert leider nicht dynamisch die Protokollierungsstufe, sondern erfordert einen Neustart des Dienstes
java -Dlogging.level=DEBUG -cp xxxxxx.jar xxxxx.java
In der Datei log4j.properties habe ich diesen Eintrag hinzugefügt
log4j.rootLogger=${logging.level},file,stdout
Ich habe es versucht
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
Es hat alles funktioniert. hoffe das hilft!
Ich habe diese folgenden Abhängigkeiten in meiner 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>
Mit log4j 1.x finde ich, dass der beste Weg darin besteht, einen DOMConfigurator zu verwenden, um eine vordefinierte Reihe von XML-Protokollkonfigurationen zu senden (z. B. eine für den normalen Gebrauch und eine für das Debuggen).
Die Nutzung dieser Möglichkeiten kann wie folgt erfolgen:
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");
}
}
Rufen Sie dies einfach mit dem entsprechenden Konfigurationsnamen auf und stellen Sie sicher, dass Sie die Vorlagen in den Klassenpfad einfügen.
Ich habe diese Methode mit Erfolg verwendet, um die Ausführlichkeit der "org.apache.http" -Protokolle zu reduzieren:
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
Für die log4j 2-API können Sie verwenden
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Wenn Sie die Protokollierungsstufe aller Protokollierer ändern möchten, verwenden Sie die folgende Methode. Dadurch werden alle Protokollierer aufgelistet und die Protokollierungsstufe auf die angegebene Stufe geändert. Bitte stellen Sie sicher , dass Sie NICHT SIE haben log4j.appender.loggerName.Threshold=DEBUG
Eigenschaftssatz in Ihrer log4j.properties
Datei.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Sie können das folgende Code-Snippet verwenden
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));