2012-12-19 39 views
3

我使用的logback作为我的日志框架,并有几个有运行相同main功能使用不同的参数,并希望创建为每个作业日志文件并将其命名与作业名称的日志文件的工作。有没有办法在java中使用dyamic名称日志文件?

例如,如果我的工作a,b,c所有运行MyClass.main()但具有不同的参数,那么我想看到a-{date}.log, b-{date}.log, c-{date}.log

我可以在我的logback.xml指定<fileNamePattern>myjob-%d{yyyy-MM-dd}.log</fileNamePattern>实现{date}的一部分,但我不知道如何(或者如果它甚至有可能)创建的文件名的前缀动态(是作业的名称)。

有没有办法在logback中动态命名日志文件?是否有另一个日志框架使这成为可能?

作为一个后续问题,我只是采取了一种错误的方法,让多个作业使用不同的参数调用相同的main函数,并希望在每个作业之后命名一个日志文件?如果有的话,是否有这种情况下的标准/最佳实践解决方案?

编辑:为什么我想命名每个日志文件之后的作业名称是每个工作自然定义一个“工作单元”,它更容易找到适当的日志文件,以防万一工作失败。我可以简单地使用滚动日志文件进行作业a,b,c,但我发现查看日志并确定每个作业的开始和结束位置很困难。

回答

1

有没有办法在logback中动态命名日志文件?是否有另一个日志框架使这成为可能?

我不相信这是可能使用out of the box追加程序(FileRollingFile等)通过标准logback.xml文件进行配置。要做你想做的事,你需要动态地创建appender,并将记录器分配给不同的appender。或者您需要创建一个新的appender,该appender可以根据记录器的名称同时写入多个文件。

我只是采取了一种错误的方法,让多个作业使用不同的参数调用相同的主函数,并希望在每个作业之后命名一个日志文件?

的的logback解决这一问题,并slightly discourage它在部分上Mapped Diagnostic Context

可能的,但稍微气馁方法作者区分另一个客户端的日志输出由实例化一个新的,独立的为每个客户记录。这种技术促进了伐木工人的泛滥,并可能增加他们的管理开销。 ...更轻的技术包括唯一地标记每个为给定客户端服务的日志请求。

然后他们继续讨论映射的诊断上下文作为解决这个问题的方法。他们给出了一个NumberCruncherServer的例子,它可以同时处理各种线程中的各种客户端的数字。通过设置映射的诊断上下文和适当的日志记录模式,可以轻松确定哪些日志事件来自哪个客户端。然后,您可以使用grep工具将感兴趣的记录事件分离到单独的文件中进行详细分析。

2

我会用你自己的日志记录。

public static PrintWriter getLogerFor(String prefix) { 
    SimpleDatFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
    String filename= prefix + sdf.format(new Date()); 
    return new PrintWriter(filename, true); // auto flush. 
} 

您可以编写一个简单的LRU缓存,例如用LinkedHashMap重用PrintWriters。

0

是的,你可以。

首先,您必须熟悉以下两个概念:Logger和Appender。一般来说,您的代码会获得一个Logger,并调用诸如debug(),warn(),info()等日志记录方法。Logger将附加Appender,Appender会根据配置设置它。

一旦你熟悉的,你需要做的是动态创建为每个不同作业类型不同的文件名FileAppender,并将其连接到您的记录仪。

我建议你花一些时间用logback手册,如果以上都没有意义。

0

您可以使用logback鉴别符,因为可以在<FileNamePattern>标记中使用鉴别符的键。我能想到的两个选项:

方案一:

可以使用Mapped Diagnostic Context鉴别来实现你的日志分离,你需要使用设置每个作业的独特价值MDC.put();

一旦你这样做,你的logback上配置的appender看起来是这样的:

<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> 
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"> 
     <key>jobName</key> <!-- the key you used with MDC.put() --> 
     <defaultValue>none</defaultValue> 
    </discriminator> 
    <sift> 
     <appender name="jobsLogs-${jobName}" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
       <FileNamePattern>${jobName}.%d{dd-MM-yyyy}.log.zip</FileNamePattern> 
       . 
       . 
       . 
      </rollingPolicy> 
      <layout class="ch.qos.logback.classic.PatternLayout"> 
       <Pattern>...</Pattern> 
      </layout> 
     </appender> 
    </sift> 
</appender> 

方案二:

实现您自己的鉴别符 - 实现ch.qos.logback.core.sift.Discriminator - ,根据线程名称进行区分。会是这个样子:

public class ThreadNameDiscriminator implements Discriminator<ILoggingEvent> { 

    private final String THREAD_NAME_KEY = "threadName"; 

    @Override 
    public String getDiscriminatingValue(ILoggingEvent event) { 
    return Thread.currentThread().getName(); 
    } 

    @Override 
    public String getKey() { 
    return THREAD_NAME_KEY; 
    } 

    // implementation for more methods 
    . 
    . 
    . 
} 

日志记录的appender看起来像一个选项与鉴别类是ThreadNameDiscriminator,关键是threadName。在这个选项中,不需要从作业中为MDC设置一个值,因此不需要修改它们。

相关问题