web-dev-qa-db-fra.com

Modification dynamique du niveau de journalisation log4j

Quelles sont les différentes approches pour changer dynamiquement le niveau de journalisation log4j, de sorte que je n'aurai pas à redéployer l'application. Les changements seront-ils permanents dans ces cas?

117
Ravi

Changer le niveau de journalisation est simple; la modification d'autres parties de la configuration constituera une approche plus approfondie.

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

Les changements sont permanents tout au long du cycle de vie du Logger. Lors de la réinitialisation, la configuration sera lue et utilisée car le réglage du niveau au moment de l'exécution ne maintient pas le changement de niveau.

UPDATE: Si vous utilisez Log4j 2, vous devez supprimer les appels à setLevel selon le documentation comme ceci peut être atteint via des classes d'implémentation.

Les appels à logger.setLevel () ou à des méthodes similaires ne sont pas pris en charge dans l'API. Les applications devraient les supprimer. Une fonctionnalité équivalente est fournie dans les classes d'implémentation Log4j 2 mais peut laisser l'application susceptible à des modifications dans les éléments internes de Log4j 2.

81
Aaron McIver

Fichier Watchdog

Log4j peut regarder le fichier log4j.xml Pour connaître les changements de configuration. Si vous modifiez le fichier log4j, log4j actualisera automatiquement les niveaux de journalisation en fonction de vos modifications. Voir la documentation de org.Apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long) Pour plus de détails. Le temps d'attente par défaut entre les vérifications est de 60 secondes. Ces modifications seraient persistantes puisque vous modifiez directement le fichier de configuration sur le système de fichiers. Tout ce que vous avez à faire est d'appeler une fois DOMConfigurator.configureAndWatch ().

Attention: la méthode configureAndWatch n'est pas sécurisée dans les environnements J2EE en raison d'une fuite de thread.

JMX

Un autre moyen de définir le niveau de journalisation (ou de reconfigurer en général) log4j consiste à utiliser JMX. Log4j enregistre ses enregistreurs en tant que MBeans JMX. À l'aide des consoles de serveur d'applications MBeanServer (ou de jconsole.exe du JDK), vous pouvez reconfigurer chaque enregistreur. Ces modifications ne sont pas permanentes et seraient réinitialisées à la configuration définie dans le fichier de configuration après le redémarrage de votre application (serveur).

Fait maison

Comme décrit par Aaron, vous pouvez définir le niveau de journalisation par programmation. Vous pouvez l'implémenter dans votre application comme vous le souhaitez. Par exemple, vous pouvez avoir une interface graphique dans laquelle l'utilisateur ou l'administrateur modifie le niveau de journalisation, puis appelez les méthodes setLevel() sur le consignateur. Que vous persistiez ou non les réglages, cela dépend de vous.

85
mhaller

Log4j2 peut être configuré pour actualiser sa configuration en analysant le fichier log4j 2. Xml (ou équivalent) à des intervalles donnés. Ajoutez simplement le paramètre "monitorInterval" à votre balise de configuration. Voir la ligne 2 de l'exemple de fichier log4j 2. Xml, qui indique à log4j de ré-analyser sa configuration si plus de 5 secondes se sont écoulées depuis le dernier événement de journal.

<?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>

Il existe des étapes supplémentaires pour que cela fonctionne si vous déployez sur une instance Tomcat, dans un IDE ou lorsque vous utilisez un démarrage à ressort. Cela semble un peu hors de portée ici et mérite probablement une question distincte.

5
Kimball Robinson

Avec log4j 1.x, je trouve que le meilleur moyen consiste à utiliser un DOMConfigurator pour soumettre l'une des configurations de journaux XML prédéfinies (une pour l'utilisation normale et une pour le débogage).

L'utilisation de ceux-ci peut être faite avec quelque chose comme ceci:

  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");
    }
  }

Appelez simplement cela avec le nom de configuration approprié et assurez-vous de placer les modèles dans le chemin de classe.

2
ISparkes

Cette réponse ne vous aidera pas à modifier le niveau de journalisation de manière dynamique, vous devez redémarrer le service. Si vous redémarrez correctement le service, utilisez la solution ci-dessous.

Je l’ai fait pour changer le niveau de journalisation log4j et cela a fonctionné pour moi, je n’ai référé aucun document. J'ai utilisé cette valeur de propriété système pour définir mon nom de fichier journal. J'ai utilisé la même technique pour définir le niveau de journalisation et cela a fonctionné

passé ceci comme paramètre de machine virtuelle Java (j'utilise Java 1.7)

Désolé, cela ne changera pas le niveau de journalisation de façon dynamique, cela nécessite un redémarrage du service

Java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.Java

dans le fichier log4j.properties, j'ai ajouté cette entrée

log4j.rootLogger=${logging.level},file,stdout

J'ai essayé

 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

Tout a fonctionné J'espère que cela t'aides!

J'ai ces dépendances suivantes dans mon 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