通过slf4j/log4j的MDC/NDC 实现日志追踪

在分布式系统或者较为复杂的系统中,我们希望可以看到一个客户请求的处理过程所涉及到的所有子系统\模块的处理日志。

由于slf4j/log4j基本是日志记录的标准组件,所以slf4j/log4j成为了我的重点研究对象。

slf4j/log4j支持MDC,可以实现同一请求的日志追踪功能。

基本思路是:

实现自定义Filter,在接受到http请求时,计算eventID并存储在MDC中。如果涉及分布式多系统,那么向其他子系统发送请求时,需要携带此eventID。

源代码:https://github.com/athinboy/studyjava.git

其中:

response.setHeader("eventsign", eventsign);很有用,返回的response中,将有httpheader:eventsign:000010x1489108079237

log4j日志格式配置为:
log4j.appender.stdout.layout.ConversionPattern=%d  %logger-%5p - %X{eventid} - %m%n

在web.xml中配置自定义filter:

 1     <!--start  log4jfilter-->
 2     <filter>
 3         <filter-name>log4jfilter</filter-name>
 4         <filter-class>org.fgq.study.log4j.Log4jFilter</filter-class>
 5         <init-param>
 6             <param-name>sign</param-name>
 7             <param-value>000010x</param-value>
 8         </init-param>
 9      </filter>
10     <filter-mapping>
11         <filter-name>log4jfilter</filter-name>
12         <url-pattern>/*</url-pattern>
13     </filter-mapping>
14     <!--end  log4jfilter-->

web.xml配置

doFilterInternal方法:

 1     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
 2
 3         String eventsign;
 4
 5         if (request.getHeader("eventsign") == null || request.getHeader("eventsign").length() == 0) {
 6             eventsign = this.sign + String.valueOf(new Date().getTime()); //计算eventID
 7
 8             logger.error("set eventid:" + eventsign);
 9         } else {
10             eventsign = request.getHeader("eventsign");//从请求端获取eventsign
11             logger.error("get eventid from request:" + eventsign);
12
13         }
14
15         MDC.put("eventid",  eventsign);
16         response.setHeader("eventsign", eventsign);
17         filterChain.doFilter(request, response);
18
19
20     }

Log4jFilter-doFilterInternal

测试结果:

1、

Request URL:http://localhost:8084/spmvc/index.html
Request Method:GET
Status Code:304 Not Modified
Remote Address:[::1]:8084

Response Headers
Date:Fri, 10 Mar 2017 03:20:01 GMT
ETag:W/"660-1489115626000"
eventsign:000010x1489116001756

服务器端日志:
2017-03-10 11:20:01,756 org.fgq.study.log4j.Log4jFilter.doFilterInternal(Log4jFilter.java:59)ogger-ERROR - - set eventid:000010x1489116001756

2、
Request URL:http://localhost:8084/spmvc/mv/mvc/time?id=1
Request Method:GET
Status Code:200 OK
Remote Address:[::1]:8084

Response Headers
Content-Language:zh-CN
Content-Type:text/html;charset=utf-8
Date:Fri, 10 Mar 2017 03:21:02 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked

Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Cookie:eryewrhuewr
eventsign:eventsignOfQequest

服务器端日志:
2017-03-10 11:21:02,378 org.fgq.study.log4j.Log4jFilter.doFilterInternal(Log4jFilter.java:62)ogger-ERROR - - get eventid from request:eventsignOfQequest
2017-03-10 11:21:02,555 org.fgq.study.controller.TimeController.ShowTime(TimeController.java:34)ogger- WARN - 000010xeventsignOfQequest - get eventid:eventsignOfQequest, send request to other sub system ,and with the eventid!

返回内容:the eventsign is : eventsignOfQequest

参考: https://logback.qos.ch/manual/mdc.html

时间: 2024-08-01 19:21:15

通过slf4j/log4j的MDC/NDC 实现日志追踪的相关文章

log4j MDC用户操作日志追踪配置

https://blog.csdn.net/userwyh/article/details/52862216 一.MDC介绍 MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能.某些应用程序采用多线程的方式来处理多个用户的请求.在一个用户的使用过程中,可能有多个不同的线程来进行处理.典型的例子是 Web 应用服务器.当用户访问某个页面时,应用服务器可能会创建一个新的线程来处理该请求,也可能从线

日志slf4j+log4j配置问题

简介slf4j  相当于抽象类log4j 相当于实现,当然还有其他的实现,如logback,jdk自带的logging等 具体配置maven 配置 pom.xml加入 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.6</version> </dependency> <dep

在android中配置 slf4j + log4j 日志记录框架

需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j 框架来实现.slf4j 是日志记录的一个facade,支持多种日志框架.log4j是个很优秀的日志记录框架. 实现: 下载类库: 先到各主站点下载类库 slf4j 网址 :http://www.slf4j.org/download.html log4j网址: http://logging.apach

SLF4J 的几种实际应用模式一:SLF4J+Log4J

转载:http://zyjustin9.iteye.com/blog/2028936 SLF4J(Simple Logging Facade for Java) 是一个通用的日志框架,谓之 Facade(门面),所扮眼的角色相当于 Jakarta Commons Logging.就像 JCL 需要底层的日志实现,如 Log4J.java.util.logging.Simple Logger 等来完成具体的信息输出,事实上基本总是 JCL+Log4J 那么一个绝配.SLF4J 的原旨也是能支持多种

Spring中配置使用slf4j + log4j

本人也是查看别人博客获得的方法,详细讲解请参照 https://www.cnblogs.com/yuxiaole/p/9297266.html 下面进入正题: 1.在pom.xml中注入相关的依赖 <!-- slf4j + log4j 日志 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version&g

【转】 log4j输出多个自定义日志文件

原文链接 http://blog.csdn.net/janestone/article/details/1862678 log4j的强大功能无可置疑,但实际应用中免不了遇到某个功能需要输出独立的日志文件的情况, 怎样才能把所需的内容从原有日志中分离,形成单独的日志文件呢?其实只要在 现有的log4j基础上稍加配置即可轻松实现这一功能. 先看一个常见的log4j.properties文件,它是在控制台和myweb.log文件中记录日志: log4j.rootLogger=DEBUG, stdout

log4j程序遇到错误打印日志到文件中

log4j.properties: # 定义 DEBUG 优先级, R 为日志输出目的的 log4j.rootLogger= DEBUG, R # 设置日志输出类型 , 为文件类型 log4j.appender.R= org.apache.log4j.FileAppender # 设置日志文件的位置 log4j.appender.R.file=../visitemanage/logs/logRecord.log # 每次在文件尾写入新的日志信息 log4j.appender.R.Append=

log4j删除N天前日志实现

基于Log4j完成定时创建和删除日志的方法 1.     背景 最近要实现定期删除N天前的日志需求: Log4j作为常用的日志生成工具,其清除日志的策略却十分有限.只有在RollingFileAppender中可以通过设置MaxFileSize和maxBackupIndex属性来指定要保留的日志文件大小以及个数,从而实现自动清除. 但是实际生产中,我们的真实的需求常常是定时每天生成一个日志文件,然后保留最近几天或近几个月的日志,历史日志需要及时清理.可是Log4j中的DailyRollingFi

Java中使用Log4j记录错误、输出日志

简介: Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. 官方站点:http://logging.apache.org/log4j/ Log4j配置: 第一步: