2016-04-26 594 views
11

我有以下的logback图案:进程ID中的logback记录模式

<pattern> 
    {"hostname": "${HOSTNAME}", 
    "level": "%p", 
    "method": "%M", 
    "process_id": "${process}", 
    "thread_id": "%t", 
    "timestamp": "%d{Y-M-d}T%d{H:M:S.s}", 
    "mesg":"%msg"}%n 
</pattern> 

不幸的是,当实际产生的日志消息我看到:"process_id": "process_IS_UNDEFINED"

是否有任何自动设置的进程id,这样的可变如同主机名一样?我在查找logback文档中的这些自动设置变量的文档列表时遇到了很多麻烦,是否有人知道更好的文档来源?

编辑:我知道映射诊断上下文的,但希望的是内置的解决方案,并不需要这样的设置,就像主机是如何工作的。

回答

13

您可以Mapped Diagnostic Context解决您的问题:

import org.slf4j.MDC; 

public class Main { 
    public static void main(String... args) { 
     // put process ID early 
     MDC.put("process_id", 
      ManagementFactory.getRuntimeMXBean().getName()); 
    } 
} 

后,所有你需要的是重新定义您的模式如下:

<pattern>{..., "process_id": "%X{process_id}"}</pattern> 

EDITED

你也可以创建自己的编码器和转换器,并在logback.xml中使用它们:

import ch.qos.logback.classic.PatternLayout; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 

public class ExtendedPatternLayoutEncoder extends PatternLayoutEncoder { 
    @Override 
    public void start() { 
     // put your converter 
     PatternLayout.defaultConverterMap.put(
      "process_id", ProcessIdConverter.class.getName()); 
     super.start(); 
    } 
} 
import ch.qos.logback.classic.pattern.ClassicConverter; 
import ch.qos.logback.classic.spi.ILoggingEvent; 

import java.lang.management.ManagementFactory; 

public class ProcessIdConverter extends ClassicConverter { 
    private static final String PROCESS_ID = 
      ManagementFactory.getRuntimeMXBean().getName(); 

    @Override 
    public String convert(final ILoggingEvent event) { 
     // for every logging event return processId from mx bean 
     // (or better alternative) 
     return PROCESS_ID; 
    } 
} 
<encoder class="some.package.ExtendedPatternLayoutEncoder"> 
    <pattern>{..., "process_id": "%process_id"}</pattern> 
</encoder> 
+0

这是我意识到的解决方案,但它很烦人,因为它需要修改我们的实际代码。无论如何在修改应用程序代码之外设置MDC?也许通过编写一个单独的类来修改MDC并将其放在类路径上? – qwwqwwq

+0

@qwwqwwq我不确定是否有一些记录的方式来做到这一点。我想你可以重载'ch.qos.logback.classic.PatternLayoutBase'类并将你的转换器放在'defaultConverterMap'中。但这是一个肮脏的黑客:) – vsminkov

+0

@qwwqwwq还有另一种方法。您可以从'ch.qos.logback.classic.PatternLayout'实际上继承,并用它在你的logback.xml像[这里](http://logback.qos.ch/manual/layouts.html)。 – vsminkov

-2

可能是你可以尝试%线程而不是过程。

+0

感谢您的答复,我已经有线程ID ,但我正在寻找进程ID。 – qwwqwwq

1

有比@vsminkov更好的解决方案。 我在这里找到:Layouts,是它说创建自定义转换符。 基本上你创建你的转换器,但不是延长PatternLayoutEncoder你添加一个转换规则到您的配置:

<configuration> 

    <conversionRule conversionWord="pid" 
        converterClass="my.custom.converter.ProcessIdConverter" /> 
    <conversionRule conversionWord="processId" 
        converterClass="my.custom.converter.ProcessIdConverter" /> 

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
     <pattern>%-6pid [%thread] - %msg%n</pattern> 
    </encoder> 
    </appender> 
    ... 
</configuration> 

这样,你摆脱了编码器的