Logback Logging Pattern中的进程ID

时间:2016-04-26 20:54:23

标签: java 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文档中找到这样自动设置变量的文档列表时遇到了很多麻烦,有没有人知道更好的文档源?

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

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:4)

有一个比@vsminkov更好的解决方案。 我在此处找到了它:Layouts,是否说创建自定义转化说明符。 基本上您创建转换器,但不是扩展sub sub2{ my @m=@_; .... } ,而是在配置中添加转换规则:

PatternLayoutEncoder

这样你摆脱了编码器

答案 2 :(得分:-2)

可能您可以尝试%thread 而不是进程。