2013-06-19 25 views

回答

11

我不知道這是否是最好的方式,但你設定的水平上org.apache.logging.log4j.core.config.LoggerConfig您可以從通過日誌管理的LoggerContext得到。

設置後,您可以使用新配置更新記錄器。

舉個例子:

public static void main(String[] args) { 
    Logger log = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME); 
    log.error("An error"); 
    log.debug("A debug"); 

    LoggerContext ctx = (LoggerContext) LogManager.getContext(false); 
    Configuration conf = ctx.getConfiguration(); 
    conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(Level.DEBUG); 
    ctx.updateLoggers(conf); 

    log.error("Another error"); 
    log.debug("Another debug"); 
} 

產量:

14:03:41.346 [main] ERROR - An error 
14:03:41.348 [main] ERROR - Another error 
14:03:41.348 [main] DEBUG - Another debug 
+1

適用於根日誌記錄器,但不適用於任何其他日誌記錄器 - 每個包,例如。在這種情況下,即使在上下文中調用「reconfigure」,日誌級別也不會改變。 – amoe

+1

@amoe同樣的問題在這裏。我想這與webapp程序的正確上下文有關。你的經理是否改變了所有的記錄器級別? – oak

7

感謝amcintosh,我包了answer的功能:

/** Override the logging level of a given logger, return the previous level */ 
public static Level setLevel(Logger log, Level level) { 
    LoggerContext ctx = (LoggerContext)LogManager.getContext(false); 
    Configuration conf = ctx.getConfiguration(); 
    LoggerConfig lconf = conf.getLoggerConfig(log.getName()); 
    Level oldLevel = lconf.getLevel(); 
    lconf.setLevel(level); 
    ctx.updateLoggers(conf); 
    return oldLevel; 
} 

儘管AMOE的評論,這似乎對於使用Log4J 2.5的我來說工作正常。

+0

它可以配置爲特定線程嗎?行爲與ThreadContext相同。 – theGamblerRises

+1

@theGamblerRises我建議發佈一個單獨的問題,而不是試圖在評論中探討這一點。我認爲你不能用這種機制控制每個線程的日誌級別,但也可能有其他方法來做你想做的事情。如果您發佈單獨的問題,請隨時在此處分享鏈接。 – dimo414

5

在我身邊,我不得不使用這段代碼才能使這個工作正常(根據以前的答案)。

import org.apache.logging.log4j.core.LoggerContext; 
import org.apache.logging.log4j.core.config.AbstractConfiguration; 

... 

public static void changeLoggerLevel(final String module, final Level level) { 
    String moduleRenamed = module.replaceAll("/", "."); 
    LoggerContext ctx = (LoggerContext)LogManager.getContext(false); 
    AbstractConfiguration configuration = (AbstractConfiguration) ctx 
     .getConfiguration(); 
    if (configuration.getLogger(moduleRenamed) != null) { 
    LoggerConfig loggerConfig = configuration.getLoggerConfig(moduleRenamed); 
    loggerConfig.setLevel(level); 
    } else { 
    LoggerConfig loggerConfig = new LoggerConfig(moduleRenamed, level, true); 
    configuration.addLogger(moduleRenamed, loggerConfig); 
    } 
    ctx.updateLoggers(configuration); 
} 

問題出在getLoggerConfig()調用;如果您嘗試提供新級別的模塊尚未註冊,則此方法將返回根記錄器(或已註冊的任何中間子路徑),因此您將改爲rootcom級別,而不是更改com.mycompany的級別。這就是爲什麼你必須添加一個新的LoggerConfig萬一要更改的模塊尚未註冊。

+0

良好的發現,這種行爲是有記錄的,但不是人們通常期望的。如果我明白你在說什麼,這可以通過在調用getLoggerConfig()之前簡單地確保'Logger'存在來解決,對吧? – dimo414

+0

我沒有嘗試過,但我會說,記錄器繼承了前一個(上)級別(可能是根),所以總是被定義......它似乎只是配置繼承沒有完全提供(並且它是爲了更改日誌級別而不是記錄器本身必須改變的配置)。 – SRG

+0

做了詭計,謝謝! – leeor

1

加里·格雷戈裏是正確的。

同樣,這個問題的答案就在那裏的FAQ頁面上log4j2的網站下面

https://logging.apache.org/log4j/2.x/faq.html#reconfig_level_from_code

示例代碼:

Configurator.setLevel(logger.getName(), Level.INFO); 
+0

雖然這可能在理論上回答這個問題,[這將是更可取的](/ meta.stackoverflow.com/q/8259)在這裏包括答案的基本部分,並提供鏈接供參考。 – Draken

+0

使用代碼示例更新了答案。 –

相關問題