Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process Id in Logback Logging Pattern

Tags:

java

logback

I have the following logback pattern:

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

Unfortunately when the log messages are actually generated I see: "process_id": "process_IS_UNDEFINED"

Is there any automatically set variable for process id, such as there is for hostname? I am having a lot of trouble finding a documented list of such automatically set variables in the logback documentation, does anyone know of a better documentation source?

Edit: I am aware of Mapped Diagnostic Contexts, but was hoping for a builtin solution that does not need such setup, much like how hostname works.

like image 312
qwwqwwq Avatar asked Apr 26 '16 20:04

qwwqwwq


People also ask

How do I read application properties in Logback xml?

xml , you can use <springProperty> to access properties from Spring's environment including those configured in application. properties . This is described in the documentation: The tag allows you to surface properties from the Spring Environment for use within Logback.

Which of the following file is used by Logback logging system?

properties file will be defined as properties in the logback. xml file.

What is root tag in Logback?

In a Logback. xml file, all the configuration options are enclosed within the <configuration> root element. In the root element, you can set the debug=true attribute to inspect Logback's internal status. You can also configure auto scanning of the configuration file by setting the scan=true attribute.

How do I enable debug logs in Logback?

You can now use -Dlogback. debug=true to enable debugging of the logback setup. Unfortunately, there is no way to enable debugging via a System property. You have to use <configuration debug="true"> in the logback.


2 Answers

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>
like image 90
vsminkov Avatar answered Sep 28 '22 00:09

vsminkov


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

like image 34
Triqui Avatar answered Sep 28 '22 02:09

Triqui