2011-10-19 78 views
29

我使用的logback,和我想我的Java程序(類似於Setting Logback Appender path programmatically)內編程設置日誌文件名,我努力去適應這種解決辦法如下:的logback - 集日誌文件名編程

在的logback-的test.xml:

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>log/${log_file_name}.log</file> 
    ... 
在我的Java程序

然後又說:

String logFileName = "" + System.currentTimeMillis(); // just for example 
System.setProperty("log_file_name", logFileName); 

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
ContextInitializer ci = new ContextInitializer(lc); 
lc.reset(); 
try 
{ 
    // I prefer autoConfig() over JoranConfigurator.doConfigure() so I 
    // wouldn't need to find the file myself. 
    ci.autoConfig(); 
} 
catch (JoranException e) 
{ 
    // StatusPrinter will try to log this 
    e.printStackTrace(); 
} 
StatusPrinter.printInCaseOfErrorsOrWarnings(lc); 

然而結果是兩個記錄,一個完整的,命名爲我想要的,例如「131904 1145343.log「,另一個爲空,並命名爲」log_file_name_IS_UNDEFINED.log「。如何停止創建其他空白日誌文件?

+0

你的代碼的唯一問題似乎是你正在設置'System.setProperty(「log_file_name」,logFileName)''太遲了。在Logback autoconfig執行之前執行它,你有你想要的。 – Robert

+0

它實際上可以做得比在你的代碼片段中容易得多:http://stackoverflow.com/a/21886071/709537 –

回答

30

我相信以下內容更接近您的要求。

import ch.qos.logback.classic.Logger; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 
import ch.qos.logback.core.FileAppender; 
import ch.qos.logback.core.util.StatusPrinter; 
import org.slf4j.LoggerFactory; 
import ch.qos.logback.classic.LoggerContext; 

public class Main { 
    public static void main(String[] args) { 
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); 

    FileAppender fileAppender = new FileAppender(); 
    fileAppender.setContext(loggerContext); 
    fileAppender.setName("timestamp"); 
    // set the file name 
    fileAppender.setFile("log/" + System.currentTimeMillis()+".log"); 

    PatternLayoutEncoder encoder = new PatternLayoutEncoder(); 
    encoder.setContext(loggerContext); 
    encoder.setPattern("%r %thread %level - %msg%n"); 
    encoder.start(); 

    fileAppender.setEncoder(encoder); 
    fileAppender.start(); 

    // attach the rolling file appender to the logger of your choice 
    Logger logbackLogger = loggerContext.getLogger("Main"); 
    logbackLogger.addAppender(fileAppender); 

    // OPTIONAL: print logback internal status messages 
    StatusPrinter.print(loggerContext); 

    // log something 
    logbackLogger.debug("hello"); 
    } 
} 

如果你需要的是添加日誌文件名的時間戳,已經的logback supports the timestamp element。因此,你實際上不需要任何自定義代碼。

+0

感謝您的幫助,我會放棄這一點。 (我只是使用時間戳作爲例子,實際的文件名將會不同) – conorsomahony

+0

謝謝,這個工程 - 在logback-test.xml中我不再指定一個文件appender,並且在我創建的一個java代碼中,附加它到'根'記錄器。 – conorsomahony

+3

是不是slf4j的要點,以避免導入ch.qos.logback.classic.Logger – Zombies

4

看起來像記錄器被初始化兩次。第一次,可能在應用程序加載時,它不能解決${log_file_name}。如果您使用-Dlog_file_name=*something*啓動應用程序,則可以驗證此行爲,如果它創建了名稱爲*something*的其他日誌文件

+0

你可以通過程序設置文件名來做的事情是用一個必需的配置(名稱,類別,包等)並將其添加到appender層次結構中。 – srkavin

+0

謝謝,我給VM參數添加了'-Dlog_file_name = verify',並確實得到了一個名爲「verify.log」的空日誌 - 有沒有辦法停止記錄器啓動兩次? – conorsomahony

8

這裏是你可以做什麼,以忽略那些多餘的文件creation.Below的配置文件

<configuration> 
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
<!-- "application-name" is a variable --> 
<File>c:/logs/${application-name}.log</File> 
<layout class="ch.qos.logback.classic.PatternLayout"> 
<Pattern>%d %p %t %c - %m%n</Pattern> 
</layout> 
</appender> 
<root level="debug"> 
<appender-ref ref="FILE"/> 
</root> 
</configuration> 

這裏是java的一部分,

LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 
JoranConfigurator jc = new JoranConfigurator(); 
jc.setContext(context); 
context.reset(); // override default configuration 
// inject the name of the current application as "application-name" 
// property of the LoggerContext 
context.putProperty("application-name", NAME_OF_CURRENT_APPLICATION); 
jc.doConfigure("/path/to/the/above/configuration/file.xml"); 

我得到這個從這裏http://logback.qos.ch/faq.html#sharedConfiguration

+0

另一種方法是在調用Logger之前初始化所有的系統變量。這也可以。 –

+0

使用System.setProperty(..)結束而不是重置上下文。對我來說似乎更清潔。感謝例如。 –

+0

不幸的是,當你想共享配置時,使用系統屬性不能工作 – Brice

10

要根據運行時屬性將日誌消息分隔/篩選到不同的文件,您可能需要使用ch.qos.logback.classic.sift.SiftingAppender

概括地說,這可以讓你在那裏${userId}是基於MDC (Mapped Diagnostic Context)(例如,MDC.put("userid", "Alice");)取代有<file>${userid}.log</file>設置一個FileAppender(或任何其它附加器)。請參閱完整示例的第一個鏈接。

相關問題