Logging the PID in log4j2 without using thread con

2019-07-16 06:51发布

问题:

I need to include the PID in my log4js logs. I see many examples which use the thread context. However, these need to be set on each individual thread created. I am constrained against doing this.

I need a solution that, either, does not use the thread context, or, can set the PID on all thread contexts, for any thread that may be created, from any arbitrary class.

回答1:

Please create a feature request on the Log4j2 issue tracker to make this a built-in feature.

For now, you can create a custom plugin. See code below. This will allow you to specify %pid in the pattern layout (similar to %m for the message).

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;

@Plugin(name = "ProcessIdPatternConverter", category = "Converter")
@ConverterKeys({ "pid", "processId" })
public final class ProcessIdPatternConverter extends LogEventPatternConverter {
    private final String pid;

    private ProcessIdPatternConverter(String[] options) {
        super("Process ID", "pid");
        String temp = options.length > 0 ? options[0] : "???";
        try {
            // likely works on most platforms
            temp = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        } catch (final Exception ex) {
            try {
                // try a Linux-specific way
                temp = new File("/proc/self").getCanonicalFile().getName();
            } catch (final IOException ignoredUseDefault) {}
        }
        pid = temp;
    }

    /**
     * Obtains an instance of ProcessIdPatternConverter.
     *
     * @param options users may specify a default like {@code %pid{NOPID} }
     * @return instance of ProcessIdPatternConverter.
     */
    public static ProcessIdPatternConverter newInstance(final String[] options) {
        return new ProcessIdPatternConverter(options);
    }

    @Override
    public void format(final LogEvent event, final StringBuilder toAppendTo) {
        toAppendTo.append(pid);
    }
}

See the manual for more details on how Log4j2 plugins work.

One way to let Log4j2 recognize your plugin is by specifying the package name of the plugin class in the packages attribute of the configuration:

<Configuration status="trace" 
     packages="com.myorg.mypluginpackage">

(Trace switches on Log4j2 internal debugging to help with troubleshooting.)