Quelles sont les différentes approches pour modifier 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?
Quelles sont les différentes approches pour modifier 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?
Réponses:
La modification du niveau de journalisation est simple; la modification d'autres parties de la configuration posera une approche plus approfondie.
LogManager.getRootLogger().setLevel(Level.DEBUG);
Les changements sont permanents à travers le 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 persiste pas le changement de niveau.
MISE À JOUR: Si vous utilisez Log4j 2, vous devez supprimer les appels à setLevel
selon la documentation car cela peut être réalisé 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 doivent les supprimer. Des fonctionnalités équivalentes sont fournies dans les classes d'implémentation de Log4j 2 mais peuvent laisser l'application vulnérable aux modifications internes de Log4j 2.
LogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
Log4j est capable de surveiller le log4j.xml
fichier pour les changements de configuration. Si vous modifiez le fichier log4j, log4j actualisera automatiquement les niveaux de journal 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, car vous modifiez directement le fichier de configuration sur le système de fichiers. Tout ce que vous avez à faire est d'appeler DOMConfigurator.configureAndWatch () une fois.
Attention: la méthode configureAndWatch n'est pas sûre pour une utilisation dans les environnements J2EE en raison d'une fuite de thread
Une autre façon 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. En utilisant les consoles MBeanServer des serveurs d'applications (ou jconsole.exe de JDK), vous pouvez reconfigurer chaque enregistreur individuel. Ces modifications ne sont pas persistantes et seraient réinitialisées dans la configuration définie dans le fichier de configuration après le redémarrage de votre application (serveur).
Comme décrit par Aaron, vous pouvez définir le niveau de journalisation par programme. 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 appelle les setLevel()
méthodes sur l'enregistreur. Que vous conserviez les paramètres quelque part ou non, cela dépend de vous.
Log4j2 peut être configuré pour actualiser sa configuration en analysant le fichier .xml log4j 2 (ou équivalent) à des intervalles donnés. Ajoutez simplement le paramètre " monitorInterval " à votre balise de configuration. Consultez la ligne 2 de l'exemple de fichier .xml log4j 2 , qui indique à log4j de réexaminer 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 Spring Boot. Cela semble quelque peu hors de portée ici et mérite probablement une question distincte.
Cette réponse ne vous aidera pas à changer le niveau de journalisation de manière dynamique, vous devez redémarrer le service, si vous redémarrez correctement le service, veuillez utiliser la solution ci-dessous
J'ai fait cela pour changer le niveau de journalisation de log4j et cela a fonctionné pour moi, je n'ai fait référence à aucun document. J'ai utilisé cette valeur de propriété système pour définir le nom de mon fichier journal. J'ai également utilisé la même technique pour définir le niveau de journalisation, et cela a fonctionné
passé ceci en tant que paramètre JVM (j'utilise Java 1.7)
Désolé, cela ne changera pas dynamiquement le niveau de journalisation, 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>
Avec log4j 1.x, je trouve que le meilleur moyen est d'utiliser un DOMConfigurator pour soumettre l'une d'un ensemble prédéfini de configurations de journaux XML (par exemple, une pour une utilisation normale et une pour le débogage).
Les utiliser peut être fait 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-le simplement avec le nom de configuration approprié et assurez-vous de placer les modèles sur le chemin de classe.
J'ai utilisé cette méthode avec succès pour réduire la verbosité des logs "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);
Pour l'API log4j 2, vous pouvez utiliser
Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));
Si vous souhaitez modifier le niveau de journalisation de tous les enregistreurs, utilisez la méthode ci-dessous. Cela énumérera tous les enregistreurs et changera le niveau de journalisation au niveau donné. Veuillez vous assurer que vous n'avez PAS delog4j.appender.loggerName.Threshold=DEBUG
propriété définie dans votre log4j.properties
fichier.
public static void changeLogLevel(Level level) {
Enumeration<?> loggers = LogManager.getCurrentLoggers();
while(loggers.hasMoreElements()) {
Logger logger = (Logger) loggers.nextElement();
logger.setLevel(level);
}
}
Vous pouvez utiliser l'extrait de code suivant
((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));