在 log4j2 AsyncLogger 中传递 threadId 的最佳方式

Best way to pass threadId in log4j2 AsyncLogger

我想使用 log4j2 异步日志记录将线程 ID 作为日志消息的一部分进行记录。

log4j2 2.4.1 中,这可以通过覆盖 logMessage 方法的自定义 AsyncLogger 实现。

public class ThreadIdAsyncLogger extends AsyncLogger {
    private static final long serialVersionUID = 1L;

    private static final ThreadLocal<Boolean> THREAD_CONTEXT_SETUP = new ThreadLocal<Boolean>() {
        @Override
        protected Boolean initialValue() {
            return false;
        }
    };

    public ThreadIdAsyncLogger(final LoggerContext context, final String name, final MessageFactory messageFactory) {
        super(context, name, messageFactory);
    }

    @Override
    public void logMessage(final String fqcn,
                           final Level level,
                           final Marker marker,
                           final Message message,
                           final Throwable thrown) {
        if (!THREAD_CONTEXT_SETUP.get()) {
            // it is enough to set it once per thread
            ThreadContext.put(Constants.ContextMapKeys.THREAD_ID, String.valueOf(Thread.currentThread().getId()));
            THREAD_CONTEXT_SETUP.set(true);
        }

        super.logMessage(fqcn, level, marker, message, thrown);
    }
}

我刚刚尝试更新到版本 2.5.0,现在我似乎无法再创建自己的 AsyncLogger,因为 AsyncLoggerDisruptor 是包私有的。 我知道我可以使用反射,但我想有更好的方法。

实现相同功能的最佳实践(设计和性能方面)是什么?

正在进行此工作:https://issues.apache.org/jira/browse/LOG4J2-1270

同时,您可以使用 ThreadLocal 映射或堆栈方法来完成此操作。在性能方面,ThreadLocal 堆栈比我认为的地图便宜一些。