it-swarm.com.de

Dynamische Änderung der Log-Ebene von log4j

Welche unterschiedlichen Ansätze gibt es, um die Log-Ebene von log4j dynamisch zu ändern, sodass ich die Anwendung nicht erneut bereitstellen muss? Werden die Änderungen in diesen Fällen dauerhaft sein?

117
Ravi

Das Ändern der Protokollebene ist einfach. Das Ändern anderer Teile der Konfiguration führt zu einem tiefergehenden Ansatz.

LogManager.getRootLogger().setLevel(Level.DEBUG);

Die Änderungen sind während des Lebenszyklus des Logger dauerhaft. Bei der Neuinitialisierung wird die Konfiguration gelesen und verwendet, da das Einstellen des Levels zur Laufzeit den Levelwechsel nicht fortsetzt.

UPDATE: Wenn Sie Log4j 2 verwenden, sollten Sie die Aufrufe von setLevel gemäß documentation wie folgt entfernen kann über Implementierungsklassen erreicht werden.

Aufrufe von logger.setLevel () oder ähnlichen Methoden werden in der API nicht unterstützt. Anwendungen sollten diese entfernen. Entsprechende Funktionen werden in den Log4j 2-Implementierungsklassen bereitgestellt, die Anwendung kann jedoch Änderungen in den Log4j 2-Interna unterliegen.

81
Aaron McIver

Datei-Watchdog

Log4j kann die Datei log4j.xml Auf Konfigurationsänderungen überwachen. Wenn Sie die log4j-Datei ändern, aktualisiert log4j die Protokollebenen automatisch entsprechend Ihren Änderungen. Einzelheiten finden Sie in der Dokumentation zu org.Apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long). Die Standardwartezeit zwischen Überprüfungen beträgt 60 Sekunden. Diese Änderungen wären dauerhaft, da Sie die Konfigurationsdatei im Dateisystem direkt ändern. Sie müssen nur einmal DOMConfigurator.configureAndWatch () aufrufen.

Achtung: Die configureAndWatch-Methode ist für die Verwendung in J2EE-Umgebungen aufgrund eines Thread-Lecks nicht sicher.

JMX

Eine andere Möglichkeit, die Protokollstufe festzulegen (oder log4j im Allgemeinen neu zu konfigurieren), ist die Verwendung von JMX. Log4j registriert seine Logger als JMX-MBeans. Mit den MBeanServer-Konsolen des Anwendungsservers (oder der JDK-Datei jconsole.exe) können Sie die einzelnen Logger neu konfigurieren. Diese Änderungen sind nicht dauerhaft und werden nach dem Neustart der Anwendung (des Servers) auf die in der Konfigurationsdatei festgelegte Konfiguration zurückgesetzt.

Selbstgemacht

Wie von Aaron beschrieben, können Sie die Protokollebene programmgesteuert festlegen. Sie können es in Ihrer Anwendung so implementieren, wie Sie es möchten. Sie könnten beispielsweise eine grafische Benutzeroberfläche haben, in der der Benutzer oder Administrator die Protokollebene ändert und dann die setLevel() -Methoden für den Logger aufruft. Ob Sie die Einstellungen irgendwo beibehalten oder nicht, liegt bei Ihnen.

85
mhaller

Log4j2 kann so konfiguriert werden, dass die Konfiguration aktualisiert wird, indem die Datei log4j 2. Xml (oder eine entsprechende Datei) in bestimmten Intervallen gescannt wird. Fügen Sie einfach den Parameter "monitorInterval" zu Ihrem Konfigurationstag hinzu. Siehe Zeile 2 der Beispieldatei log4j 2. Xml, 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 erscheint hier etwas unangemessen und verdient wahrscheinlich eine eigene Frage.

5

Mit log4j 1.x kann ich am besten einen DOMConfigurator verwenden, um eine vordefinierte Gruppe von XML-Protokollkonfigurationen (z. B. eine für den normalen Gebrauch und eine für das Debuggen) zu übermitteln.

Diese können Sie folgendermaßen nutzen:

  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.

2
ISparkes

Diese Antwort hilft Ihnen nicht dabei, die Protokollierungsstufe dynamisch zu ändern. Sie müssen den Dienst neu starten. Wenn Sie den Dienst neu starten möchten, verwenden Sie bitte die folgende Lösung.

Ich habe dies getan, um die Protokollstufe von 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 die gleiche Technik verwendet, um die Protokollierungsstufe festzulegen, und es hat funktioniert

hat dies als JVM-Parameter übergeben (ich verwende Java 1.7)

Entschuldigung, dadurch wird die Protokollierungsstufe nicht dynamisch geändert, es ist ein Neustart des Dienstes erforderlich.

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 geklappt. 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>
2
Anandkumar