MDC(Mapped Diagnostic Context)

lxf2023-12-20 17:20:02

一、简述

在微服务上,服务项目链接启用比较多,假如日志没有明显标志,难以清查关联日志信息内容,所以在日志文档中,针对同一个要求,必须要有同一个日志跟踪ID(常称之为traceId)。这儿有两种层级的规定,第一个是同一个微服务架构中同一个请求的日志包括同样的traceId;第二个不一样微服务架构间的同一个要求,traceId也要保持一致。

二、MDC介绍

MDC(Mapped Diagnostic Context,投射调节前后文)是 log4j 和 logback 所提供的一种便于在线程同步环境下纪录日志的作用。我使用的是log4j2,还支持这类作用。微服务架构也是一个线程同步的使用,在MDC中加入每一个进程(要求)的独特主要参数,即traceId,可以区别不一样进程的日志信息内容,有益于查找问题。

三、网关ip完成

在SpringGateWay中以添加一个全局性TraceInfoFilter,根据MDC真正实现。留意这儿要把该Filter的Order设定低一些,那样它的优先会比较高,其它的领域模型解决都必须要在他之后,才可以使用这儿设定的traceId特性。

/**
 * 形成日志唯一ID,并放进请求头内容中,及其集成化slf4j
 */
@Component
public class TraceInfoFilter implements GlobalFilter, Ordered {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("====== TraceInfoFilter start ======");
        String traceId = TraceIdUtil.shortUUID();
        // 1.将traceId传达给微服务架构
        ServerHttpRequest request = exchange.getRequest().mutate().header("traceId", traceId).build();
        // 2.将traceId设定到slf4j中,日志打印模板配备打印出traceId
        MDC.put("traceId", traceId);
        return chain.filter(exchange.mutate().request(request).build());
    }

    @Override
    public int getOrder() {
        return WRITE_RESPONSE_FILTER_ORDER - 2;
    }
}

第二步需要调整log4j2.xml的键入模版配备,这里要加上traceId特性,我这个案例只更改了控制台输出。留意traceId是自定义属性,其书写为%X{traceId}

<configuration status="INFO" monitorInterval="30">
    <properties>

        <Property name="log_path">${sys:user.home}/logs</Property>
    </properties>
    <!--先界定每一个appender -->
    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <!--导出日志的文件格式 -->
            <PatternLayout charset="UTF-8" pattern="[%d][%-5p][%t][%c:%L][%X{traceId}] %m%n"/>
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>
    </appenders>
    <!--随后界定logger,仅有重新定义了logger并引入的appender,appender才能起效 -->
    <loggers>
        <!--滤掉spring和mybatis的一些无意义的DEBUG信息内容 -->
        <logger name="org.springframework" level="INFO"></logger>
        <!--<root level="all">-->
        <root level="ALL">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>

检测如下所示,翠绿色部分就是增大的traceId打印出

MDC(Mapped Diagnostic Context)

四、微服务架构完成

这儿思路并不是更改原先的请求参数,传达给微服务架构的链接主要参数放到header里边。

// 1.将traceId传达给微服务架构
ServerHttpRequest request = exchange.getRequest().mutate().header("traceId", traceId).build();
// 2.将traceId设定到slf4j中,日志打印模板配备打印出traceId
MDC.put("traceId", traceId);
return chain.filter(exchange.mutate().request(request).build());

微服务架构也要进行一定的更新改造,必须添加一个RequestInterceptor,用以解决traceId

/**
 * 要求回调函数
 */
public class RequestInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String traceId = request.getHeader("traceId");
        MDC.put("traceId", traceId);
        return super.preHandle(request, response, handler);
    }

}

在原有业务代码中打印出日志,调节后,就能发现,gateway里的traceId传达到微服务架构中,同时对业务代码并没有进入。

MDC(Mapped Diagnostic Context)

五、汇总

  • 工程项目启动日志并没有traceId,由于以上控制方式是要求类信息内容才会有加上traceId
  • traceId是UUID,能够改进下再加上时间格式、系统数据等,提高易读性
  • 正中间出现一个小意外,在网关设置特性不正确造成微服务架构未获取traceId

六、源代码

gitee.com/animal-fox_…

本站是一个以CSS、JavaScript、Vue、HTML为中心的前端开发技术网址。我们的使命是为众多前端工程师者提供全方位、全方位、好用的前端工程师专业知识和技术服务。 在网站上,大家可以学到最新前端开发技术,掌握前端工程师最新发布的趋势和良好实践。大家提供大量实例教程和实例,让大家可以快速上手前端工程师的关键技术和程序。 本站还提供了一系列好用的工具软件,帮助你更高效地开展前端工程师工作中。公司提供的一种手段和软件都要经过精心策划和改进,能够帮助你节约时间精力,提高研发效率。 此外,本站还拥有一个有活力的小区,你可以在社区里与其它前端工程师者沟通交流技术性、交流经验、处理问题。我们坚信,街道的能量能够帮助你能够更好地进步与成长。 在网站上,大家可以寻找你需要的一切前端工程师网络资源,使您成为一名更加出色的网页开发者。欢迎你添加我们的大家庭,一起探索前端工程师的无限潜能!