2014-10-31 52 views
10

我想使用log4j 而不是任何配置文件。 我婉做是值得的:如何在log4j2.02中以編程方式配置記錄器?

logger = (Logger) LogManager.getLogger(this.getClass()); 
String pattern = "[%level] %m%n"; 
//do something to make this logger output to an local file "/xxx/yyy/zzz.log" 

我發現這個答案:Configuring Log4j Loggers Programmatically

Logger#addAppender的文檔說: 這種方法是不通過公共API暴露並主要用於單元測試。

我不確定是否在我的代碼中使用此方法的正確方法,或者有其他更好的解決方案來解決我的問題。

回答

19

The official documentation示出了一個例子:如果配置文件被改變的配置將被裝載,並手動更改將

  1. 編程方式添加到當前配置

    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); 
    final Configuration config = ctx.getConfiguration(); 
    
    Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null); 
    Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config); 
    appender.start(); 
    config.addAppender(appender); 
    
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null); 
    AppenderRef[] refs = new AppenderRef[] {ref}; 
    LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null); 
    loggerConfig.addAppender(appender, null, null); 
    config.addLogger("org.apache.logging.log4j", loggerConfig); 
    ctx.updateLoggers(); 
    

    有了這些限制迷路了。

  2. 對運行配置的修改要求所有被調用的方法(addAppender和addLogger)都要同步。

該解決方案避免使用這種方法從核心實現org.apache.logging.log4j.core.Logger,它可以避免髒投這樣的:

import org.apache.logging.log4j.Logger; 

Logger logger = (Logger) LogManager.getLogger(this.getClass()); 
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API 
+0

如果您打算將記錄器jar遮蔽以將其完全隱藏,請將其添加爲第一行:LogManager.setFactory(new Log4jContextFactory());現在,您還可以使用遮陽過濾器省略所有配置和屬性文件。 – bebbo 2017-12-20 14:44:31

0

如果我只是迴應您的要求,我可以提出三種選擇。我使用第一個引導記錄器配置;不過,我認爲第一個是必要的。你的第三個選擇似乎很麻煩,因爲你需要調用不同的log4j API-s來配置。

使用的Log4j在Java的簡單日誌框架...

  1. 做出「最小」或「默認」 log4j.properties在你的資源的JAR文件的文件。然後聲明一些靜...

    private static final URL LOGGER_CONFIG_URL = resolveConfigUrl(); 
        : 
    
    private static URL resolveConfigUrl(){ 
    
        URL url = LogConfig.class.getResource(LOGGER_CONFIG_NAME); 
    
        if(null == url) // Second chance, try for a file. 
        { 
         url = FileHelp.resolveUrlNameAsUrlToFile(LOGGER_CONFIG_NAME); 
            //-- Make this function with: url = tmpFile.toURI().toURL() 
            // Plus appropriate try/catch and error checks. 
         } 
         return url; 
    } 
    
    private static void configureLogger(){ 
    
        BasicConfigurator.configure(); 
        PropertyConfigurator.configure(LOGGER_CONFIG_URL ); 
        LOG.info("Logging config done: " + LOGGER_CONFIG_NAME); 
    } 
    
  2. 寫你的配置到一個StreamWriter,而不是將文件放在你的JAR,然後給流將日誌配置爲StringReader並用上面的例子(或更多減)。

  3. 您可以使用slf4j API來執行您的日誌配置,而不是直接寫入Log4j。大多數地方我一直喜歡SLF4J路線。

就個人而言,我更喜歡選項#1;很容易維護。簡單,您可以隨時重新排序代碼以接受/查找要先加載的文件。還有其他一些可以考慮的側向途徑,例如在啓動時以編程方式設置環境變量。這似乎是我設計的。

我使用#1的方式是通過資源文件建立默認/引導記錄器配置,資源文件本身被包裝到JAR文件中。你可以重新配置'以後的',而這個選項爲你提供了一個簡約的星型配置或引導配置。在早期階段,我發現事情還沒有被記錄,因爲記錄器初始化還沒有在嵌入式應用上發生。所以我把bootstrap(或默認)這個簡單的選項作爲一個基礎。希望這可以幫助。

0

隨着log4j2的最新版本中,所有創建像

PatternLayout.createLayout, 
FileAppender.createAppender, 
LoggerConfig.createLogger 
這些API

已被棄用,最好使用自定義日誌ConfigurationFactory以及ConfigurationBuilder以編程方式定義日誌配置。

相關問題