2016-04-26 37 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> 

這樣,你擺脫了編碼器的