当网络中存在故障时,我们通常需要在请求过程中获取所有日志。如果请求仅在一个线程中处理,我们可以通过线程ID过滤日志,但是如果请求包含处理异步线的处理,然后螺纹ID由线程ID拉伸。
华为IoT平台提供了在接收设备上报告数据的能力。当数据到达平台时,平台将执行一些复杂的业务逻辑处理,例如数据存储,规则引擎,数据推,命令等。由于此逻辑之间没有强大的耦合关系,通常是异步的。在本文中介绍了数据请求中包含的所有业务日志。
SLF4J日志框架提供了MDC(映射诊断上下文)工具类。Google被翻译为映射的诊断和上下文。从字面意义上很难理解。我们可以首先对抗它。
我们在主函数的输入调用方法中传递请求ID,并在Exit Call方法中删除请求ID。配置了Log4j2.xml文件后,运行主函数,您可以在控制台上看到以下日志输出:
从日志中可以清楚地看到(映射)请求ID(requestID)包含(映射),这实际上是我们定位(诊断)问题的关键字(上下文)。只要我们植入MDC工具,和界面或剪切表面中的代码,当当前网络定位问题时,我们可以快速过滤特定请求要求的所有日志。
但是,MDC工具真的很方便我们的想法吗?回到我们开始,一个请求可能涉及多线程异步治疗,因此在多线程异步方案中,它仍然可以正常运作吗?谈话很便宜吗?代码。
在代码中,我们有一个新的异步线程,并打印匿名对象可运行的方法的日志方法。run主函数,您可以在控制台上看到以下日志输出:
不幸的是,请求ID未在异步线程中打印出来。要解决此问题,我们必须知道MDC的实现原理。到有限的空间,此处不会详细介绍。MDC在异步线程中不生效的原因是,底层使用ThreadLocal作为数据结构。我们称之为的请求ID仅在当前线程中有效。感兴趣的朋友可以自己加深代码详细信息。
如果您知道原则,那么解决此问题就很容易。我们可以使用装饰模式来编写新的装饰层。避免创建过程中当前线程的MDC值,然后在执行执行方法时将保存的MDC值复制到异步线程。代码实现如下。:
然后,我们需要装饰主要功能中创建的可运行实现类:
执行主函数,将输出以下日志:
Consess!在我们努力之后,在异步线和线程池中打印了RequestID!
本文讲述了如何使用MDC工具快速过滤一次请求一次的所有日志,并使MDC工具通过装饰模式在异步线程中生效。,您可以过滤整个系统的任何过程的日志。
使用MDC工具,在自我测试的开发中,它可以大大节省定位问题并提高发展效率;在操作和维护阶段,它可以快速收集相关的日志信息并加快分析。
资料来源:wudashan.com/2018/02/15/log-request-in-mutithread