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

时间:2016-04-02 21:29:03

标签: java asynchronous logging log4j log4j2

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

使用log4j2 2.4.1,这可以通过自定义AsyncLogger来覆盖logMessage方法。

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是包私有的。 我知道我可以使用反射,但我想有更好的方法。

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

1 个答案:

答案 0 :(得分:2)

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

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