首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用了Logback这么多年,连它的MDC功能都没听说过?

做积极的人,而不是积极废人!

每天更新文章,每天掉亿点点头发...

Logback日志系统是SLF4J的原生实现。同时,Logback也是Log4j的继任者,补全了Log4j的不足。

1、Logback的模块组成

logback-core,其他模块的功能基础

logback-classic

可以看作Log4j的增强版实现。

实现了SLF4J API,能够在部署的时候提供给应用日志功能。

logback-access

集成了Servlet容器(Tomcat,Jetty),提供以HTTP方式访问日志的功能。

2、Logback在Maven项目中的应用

在应用中使用兼容SLF4J的日志系统,无需在构建时依赖任何具体的日志系统,而只需要依赖SLF4J API,POM配置示例如下:

而对于实际部署时使用的日志系统,无需在POM中配置,只需将日志系统的jar文件置于应用部署环境的classpath中即可。

但是为了部署方便,可以直接在POM中给出对日志系统的依赖。例如,应用中使用Logback日志系统,配置POM如下即可:

3、Logback的MDC功能概述

Logback的设计目标就是审计、调试复杂的分布式应用。

在分布式应用中,为了区分不同客户端的日志输出,往往为每个客户端实例化一个单独的logger,但是这样将导致大量日志的产生,而且增加了日志管理的负担。

为此,Logback采用了更轻量级的技术,为一个客户端的每一个日志请求打上唯一识别的时间戳,而这是通过SLF4J的MDC实现的。

为了给每个日志请求打上唯一识别的时间戳,必须利用请求的上下文信息,即将请求的上下文信息装入MDC,并在需要的时候被Logback的日志组件提取。

4、Logback的MDC功能实现

Logback是在logback-classic模块中实现了SLF4J的MDC功能。

MDC中管理的数据(简称MDC数据)是以单个线程为单位进行访问的,即对MDC数据的操作(如put, get)只对当前线程有效,所以也永远是线程安全的。

在服务端,为每个请求分配一个线程进行处理,所以每个服务端线程处理的请求,都具有唯一的MDC上下文数据。

子线程不会自动继承父线程的MDC数据,所以在创建子线程时,可以先调用MDC的getCopyOfContextMap()方法以返回一个Map对象,从而获取父线程的MDC数据,然后再在子线程的开始处,最先调用MDC的setContextMap()方法为子线程设置父线程的MDC数据,从而能够在子线程中访问父线程的MDC数据。

但是,在Web应用中,一个请求可能在不同的阶段被多个线程处理。这时,只是在服务端的处理线程中设置MDC数据,并不能保证请求的某些信息(如用户的认证信息等)总是能够被处理线程访问到。

为了在处理一个请求时能够保证某些信息总是可访问,建议使用Servlet Filter,在请求到来时就将信息装入到MDC中,在完成所有的后续处理后,再次通过过滤器时将MDC数据移除。

参考链接:

https://logback.qos.ch/index.html

http://logback.qos.ch/manual/mdc.html

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20221201A00RNR00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券