Modifier le niveau de journal par programme dans Log4j2

Je suis intéressé par la modification par programme du niveau de journalisation dans Log4j2. J’ai essayé de regarder leur documentation de configuration mais cela ne semblait rien avoir. J’ai également essayé de regarder dans le paquetage: org.apache.logging.log4j.core.config , mais rien ne semblait utile non plus.

    EDITED selon log4j2 version 2.4 FAQ

    Vous pouvez définir le niveau d’un enregistreur avec la classe Configurator de Log4j Core. MAIS sachez que la classe Configurator ne fait pas partie de l’API publique.

     // org.apache.logging.log4j.core.config.Configurator; Configurator.setLevel("com.example.Foo", Level.DEBUG); // You can also set the root logger: Configurator.setRootLevel(Level.DEBUG); 

    La source

    EDITED pour refléter les modifications de l’API introduites dans Log4j2 version 2.0.2

    Si vous souhaitez modifier le niveau de l’enregistreur racine, procédez comme suit:

     LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration(); LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); loggerConfig.setLevel(level); ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig. 

    Voici le javadoc pour LoggerConfig.

    Si vous souhaitez modifier un seul niveau de journalisation spécifique (et non le ou les enregistreurs racine configurés dans le fichier de configuration), vous pouvez le faire:

     public static void setLevel(Logger logger, Level level) { final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); final Configuration config = ctx.getConfiguration(); LoggerConfig loggerConfig = config.getLoggerConfig(logger.getName()); LoggerConfig specificConfig = loggerConfig; // We need a specific configuration for this logger, // otherwise we would change the level of all other loggers // having the original configuration as parent as well if (!loggerConfig.getName().equals(logger.getName())) { specificConfig = new LoggerConfig(logger.getName(), level, true); specificConfig.setParent(loggerConfig); config.addLogger(logger.getName(), specificConfig); } specificConfig.setLevel(level); ctx.updateLoggers(); } 

    La réponse acceptée par @slaadvak ne fonctionnait pas pour moi pour Log4j2 2.8.2 . Les suivants ont fait.

    Pour modifier le Level journalisation, utilisez universellement :

     Configurator.setAllLevels(LogManager.getRootLogger().getName(), level); 

    Pour modifier le Level journalisation de la classe actuelle uniquement, utilisez:

     Configurator.setLevel(LogManager.getLogger(CallingClass.class).getName(), level); 

    J’ai trouvé une bonne réponse ici: https://garygregory.wordpress.com/2016/01/11/changing-log-levels-in-log4j2/

    Vous pouvez utiliser org.apache.logging.log4j.core.config.Configurator pour définir le niveau d’un enregistreur spécifique.

     Logger logger = LogManager.getLogger(Test.class); Configurator.setLevel(logger.getName(), Level.DEBUG); 

    L’approche programmatique est plutôt intrusive. Vous devriez peut-être vérifier le support JMX fourni par Log4J2:

    1. Activez le port JMX dans le démarrage de votre application:

      -Dcom.sun.management.jmxremote.port = [port_num]

    2. Utilisez l’un des clients JMX disponibles (la JVM en fournit un dans JAVA_HOME / bin / jconsole.exe) lors de l’exécution de votre application.

    3. Dans JConsole, cherchez le bean “org.apache.logging.log4j2.Loggers”

    4. Enfin, changez le niveau de votre enregistreur

    La chose que j’aime le plus, c’est que vous n’avez pas à modifier votre code ou votre configuration pour gérer cela. Tout est externe et transparent.

    Plus d’infos: http://logging.apache.org/log4j/2.x/manual/jmx.html

    La plupart des réponses par défaut supposent que la journalisation doit être additive. Mais disons que certains paquets génèrent beaucoup de journaux et que vous souhaitez désactiver la journalisation pour cet enregistreur particulier uniquement. Voici le code que j’ai utilisé pour le faire fonctionner

      public class LogConfigManager { public void setLogLevel(Ssortingng loggerName, Ssortingng level) { Level newLevel = Level.valueOf(level); LoggerContext logContext = (LoggerContext) LogManager.getContext(false); Configuration configuration = logContext.getConfiguration(); LoggerConfig loggerConfig = configuration.getLoggerConfig(loggerName); // getLoggerConfig("abc") could return logger for "ab" if there is no logger for "abc" if (loggerConfig.getName().equalsIgnoreCase(loggerName)) { loggerConfig.setLevel(newLevel); log.info("Changed logger level for {} to {} ", loggerName, newLevel); } else { // create a new config. loggerConfig = new LoggerConfig(loggerName, newLevel, false); log.info("Adding config for: {} with level: {}", loggerConfig, newLevel); configuration.addLogger(loggerName, loggerConfig); LoggerConfig parentConfig = loggerConfig.getParent(); do { for (Map.Entry entry : parentConfig.getAppenders().entrySet()) { loggerConfig.addAppender(entry.getValue(), null, null); } parentConfig = parentConfig.getParent(); } while (null != parentConfig && parentConfig.isAdditive()); } logContext.updateLoggers(); } } 

    Un cas de test pour le même

     public class LogConfigManagerTest { @Test public void testLogChange() throws IOException { LogConfigManager logConfigManager = new LogConfigManager(); File file = new File("logs/server.log"); Files.write(file.toPath(), new byte[0], StandardOpenOption.TRUNCATE_EXISTING); Logger logger = LoggerFactory.getLogger("abc"); logger.debug("Marvel-1"); logConfigManager.setLogLevel("abc", "debug"); logger.debug("DC-1"); // Parent logger level should remain same LoggerFactory.getLogger("ab").debug("Marvel-2"); logConfigManager.setLogLevel("abc", "info"); logger.debug("Marvel-3"); // Flush everything LogManager.shutdown(); Ssortingng content = Files.readAllLines(file.toPath()).stream().reduce((s1, s2) -> s1 + "\t" + s2).orElse(null); Assert.assertEquals(content, "DC-1"); } } 

    En supposant que log4j2.xml soit dans classpath

     < ?xml version="1.0" encoding="UTF-8"?>                    

    Une façon inhabituelle de le faire est de créer deux fichiers séparés avec un niveau de journalisation différent.
    Par exemple. log4j2.xml et log4j-debug.xml Modifiez maintenant la configuration de ces fichiers.
    Exemple de code:

     ConfigurationFactory configFactory = XmlConfigurationFactory.getInstance(); ConfigurationFactory.setConfigurationFactory(configFactory); LoggerContext ctx = (LoggerContext) LogManager.getContext(false); ClassLoader classloader = Thread.currentThread().getContextClassLoader(); InputStream inputStream = classloader.getResourceAsStream(logFileName); ConfigurationSource configurationSource = new ConfigurationSource(inputStream); ctx.start(configFactory.getConfiguration(ctx, configurationSource));