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.
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.
properties file will be defined as properties in the logback. xml file.
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.
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.
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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With