Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

能否提供与LOG4J(2)中的MDC集成或增强 #49

Closed
bwzhang2011 opened this issue Jun 15, 2015 · 10 comments
Closed

能否提供与LOG4J(2)中的MDC集成或增强 #49

bwzhang2011 opened this issue Jun 15, 2015 · 10 comments
Assignees
Labels
❓question Further information is requested
Milestone

Comments

@bwzhang2011
Copy link

Hi~

注意到multiple-thread-context提供了上下文线程变量的传递,并提供了针对RunnableCallable的支持。由于上述场景中有一部分是用在日志中,当前log4j(2)提供了MDC的支持。

想问的是,能否提供一个针对其的增强支持,以log4j2为例已经提供了入口操作的类ThreadContext,若在Executor中传递则需要 使用 该类中的 getContext() and cloneStack() 方法。

此外,框架是否考虑了如何清除这些线程安全变量(以WEB为例大多数是在filter里面使用PUT然后 执行完毕后 POPCLEAR)——是否有好的建议(以multi-thread-context的使用为例)。

@bwzhang2011 bwzhang2011 changed the title 能否提供与LOG4J(2)中的MDC集成 能否提供与LOG4J(2)中的MDC集成(或增强) Jun 15, 2015
@oldratlee
Copy link
Member

LOG4J(2)的集成 想法不错,我理解和思考一下你说的实现过程。

另外,在MDC的需求说明中,关于日志场景的说明还是比较模糊的,你能给一下更明确实际些的场景说明不?这样做起来更有目标感 😸 @bwzhang2011

@bwzhang2011
Copy link
Author

@oldratlee 感谢回复。

使用MDC是用来记录跟应用上下文环境中需要保存的一些数据,比如请求类提取的、跟执行有关的跟踪信息还有当异常发生的时候提取的,这些可以在appender中的layout来指定这些信息(比如%X{key1}: %X{key2}等)。

一般场景可以是:

  1. filter类中写入parent thread的内容(MDC.put)——带有一traceId或其余标记信息(用户)
  2. 业务类中写入业务类的信息(MDC.put)——可提取跟traceId或标记有关的信息(提取),并保存其余的消息(跟本线程有关的)并进行保存保存
  3. 清空filter的线程变量,finally { ThreadContext.clearAll() }

@oldratlee
Copy link
Member

MtContextThreadLocal新加上callback方法:

    protected void beforeExecute() {
    }

    protected void afterExecute() {
    }

MtContextThreadLocal.java

可以覆盖这个方法 来完成 log4j2的设置,达到filter的效果:

    static MtContextThreadLocal<Map<String, String>> mtc = new MtContextThreadLocal<Map<String, String>>() {
        @Override
        protected void beforeExecute() {
            final Map<String, String> log4j2Context = get();
            for (Map.Entry<String, String> entry : log4j2Context.entrySet()) {
                ThreadContext.put(entry.getKey(), entry.getValue());
            }
        }

        @Override
        protected void afterExecute() {
            ThreadContext.clearAll();
        }

        @Override
        protected Map<String, String> initialValue() {
            return new HashMap<String, String>();
        }
    };

Log的代码:

    public static void main(String[] args) throws Exception {
        // Init Log Context, set MTC
        // More KV if needed
        final String TRACE_ID = "trace-id";
        final String TRACE_ID_VALUE = "XXX-YYY-ZZZ";
        ThreadContext.put(TRACE_ID, TRACE_ID_VALUE);
        mtc.get().put(TRACE_ID, TRACE_ID_VALUE);

        // Log in Main Thread
        logger.info("Log in main!");

        // Run task in thread pool
        final ExecutorService executorService = Executors.newFixedThreadPool(1);
        final Runnable task = new Runnable() {
            @Override
            public void run() {
                // Log in thread pool
                logger.info("Log in Runnable!");
            }
        };
        final Future<?> submit = executorService.submit(MtContextRunnable.get(task));
        submit.get();

        executorService.shutdown();
    }

完整示例:Log4j2ContextFilter.javalog4j2.xml

输出:

22:50:52.823 [main] INFO  log4j2.Log4j2ContextFilter XXX-YYY-ZZZ - Log in main!
22:50:52.826 [pool-2-thread-1] INFO  log4j2.Log4j2ContextFilter XXX-YYY-ZZZ - Log in Runnable!

@bwzhang2011 看看这样是不是可以解决你的问题了? 如果OK,我就发一个新版本,加上这个功能。

@oldratlee oldratlee added the ❓question Further information is requested label Jun 16, 2015
@oldratlee oldratlee self-assigned this Jun 16, 2015
@oldratlee oldratlee modified the milestone: 1.2.0 Jun 16, 2015
@oldratlee
Copy link
Member

v1.2.0 已发布。 @bwzhang2011

@bwzhang2011
Copy link
Author

@oldratlee, 我再仔细看一下,看是否能合到工程中。T.K.S

@bwzhang2011
Copy link
Author

@oldratlee SL4JMDC类依赖于MDCAdapter,个人感觉如果集成则需要提供一个针对其的实现。这样我仍然只需要操作MDC即可。

@oldratlee
Copy link
Member

相关的 SL4JMDCmultiple-thread-context的集成,涉及如果设置业务的Log Contexttrace-id,这个需要业务来完成, multi-thread-context提供能力。

个人感觉如果集成则需要提供一个针对其的实现

你说能一下 『针对其的实现』如何做,给一下示例代码?

如果你比较清楚了,能直接实现一下,给个PullRequest吗? 😸 @bwzhang2011

@oldratlee oldratlee changed the title 能否提供与LOG4J(2)中的MDC集成(或增强) 能否提供与LOG4J(2)中的MDC集成或增强 Feb 15, 2016
@jidian
Copy link

jidian commented Oct 29, 2017

很赞

@zhangshity
Copy link

@oldratlee
Copy link
Member

PS: 已提供集成库:

<dependency>
    <groupId>com.ofpay</groupId>
    <artifactId>logback-mdc-ttl</artifactId>
    <version>1.4.0</version>
</dependency>

说明参见:
https://github.com/alibaba/transmittable-thread-local/blob/master/docs/requirement-scenario.md#log4j2-mdc%E7%9A%84ttl%E9%9B%86%E6%88%90

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❓question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants