Process Id in Logback Logging Pattern

There is a better solution than that of @vsminkov. I found it here: Layouts, were it says Creating a custom conversion specifier. Basically you create your converter, but instead of extending PatternLayoutEncoder you add a conversion rule to your configuration:

<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>

That way you get rid of the encoder


You can solve your problem with 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());
    }
}

After that all you need is to re-define your pattern as follows:

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

EDITED

Also you can create your own encoder and converter and use them in 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>

Full example:

    <encoder class="some.package.ExtendedPatternLayoutEncoder">
        <pattern>%d{dd.MM.yyyy HH:mm:ss.SSS} PID:%process_id [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>

The default pattern for console logging defined in DefaultLogbackConfiguration is:

"${CONSOLE_LOG_PATTERN:-"
            + "%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) "
            + "%clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} "
            + "%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"

As @Hlulani has pointed out, and as you can see in this default pattern, you can use ${PID} and logback will replace it with the process id.

Tags:

Java

Logback