2011-10-19 57 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(或任何其它附加器)。请参阅完整示例的第一个链接。

相关问题