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

由于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:
     <!--start  log4jfilter-->
<filter>
<filter-name>log4jfilter</filter-name>
<filter-class>org.fgq.study.log4j.Log4jFilter</filter-class>
<init-param>
<param-name>sign</param-name>
<param-value>000010x</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>log4jfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--end log4jfilter-->

web.xml配置

doFilterInternal方法:
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

         String eventsign;

         if (request.getHeader("eventsign") == null || request.getHeader("eventsign").length() == 0) {
eventsign = this.sign + String.valueOf(new Date().getTime()); //计算eventID logger.error("set eventid:" + eventsign);
} else {
eventsign = request.getHeader("eventsign");//从请求端获取eventsign
logger.error("get eventid from request:" + eventsign); } MDC.put("eventid", eventsign);
response.setHeader("eventsign", eventsign);
filterChain.doFilter(request, response); }

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

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

  1. slf4j+log4j在Java中实现日志记录

    小Alan今天来跟大家聊聊开发中既简单又常用但必不可少的一样东西,那是什么呢?那就是日志记录,日志输出,日志保存. 后面就统一用日志记录四个字来形容啦. 日志记录是项目的开发中必不可少的一个环节,特别 ...

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

    一.MDC介绍 MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能.某些应用程序采用多线程的方式 ...

  3. slf4j + log4j 是如何初始化的

    SLF4J的全称是 Simple Logging Facade for Java(简单java日志门面) SLF4J自己不提供具体的日志功能实现,只是提供了一个统一的日志门面,在这个统一的门面之下,用 ...

  4. (Dubbo架构)基于MDC+Filter的跨应用分布式日志追踪解决方案

    在单体应用中,日志追踪通常的解决方案是给日志添加 tranID(追踪ID),生成规则因系统而异,大致效果如下: 查询时只要使用 grep 命令进行追踪id筛选即可查到此次调用链中所有日志,但是在 du ...

  5. 常见java日志系统的搭配详解:关于slf4j log4j log4j2 logback jul jcl commons-logging jdk-logging

    先看一张图: 是不是有点晕, 晕就对了.这个仅仅是 slf4j 的情况,实际上, 我们不仅要接触到 slf4j ,有时候还会接触其他的日志系统.且看下文分解. 1 直接使用各个日志系统 1.1 直接使 ...

  6. Java日志框架(Commons-logging,SLF4j,Log4j,Logback)

    简介 在系统开发中,日志是很重要的一个环节,日志写得好对于我们开发调试,线上问题追踪等都有很大的帮助.但记日志并不是简单的输出信息,需要考虑很多问题,比如日志输出的速度,日志输出对于系统内存,CPU的 ...

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

    需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j ...

  8. Spring Boot 整合 slf4j+log4j 实现日志管理

    一:首先新建一个jar项目,如下图: 二:添加log4j的依赖,如下pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0 ...

  9. Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)

    一.简介 JAVA日志在初期可能官方并没有提供很好且实用的规范,导致各公司或OSS作者选择自行造轮子,这也导致了目前初学者觉得市面上 Java 日志库繁杂的局面. 现在市面流行以 slf4j(Simp ...

随机推荐

  1. 【PHP 基础类库】Prototype 原型版教学文章!

    前言 大家好我是:石不易,今天我为大家带来了PHP基础类库原型版的教学文章,至此本人的作品线已分为三大类,分别是:JavaScript前端框架(封装库).PHP模板引擎.以及PHP基础类库.该类库历时 ...

  2. UVA 12345 Dynamic len(set(a[LR]))

    题意:询问区间唯一元素个数,单点修改. 分析: 借助Unique snowflakes, Can you answer these queries II的思想,唯一性可以借助元素上一次出现的位置来判断 ...

  3. Veritas NetBackup™ 状态码"十大"常见报错状态码

    我在刚开始学习Netbackup的时候,没少走弯路.经常会遇到各种稀奇古怪的 error 信息,遇到报错会很慌张,急需一个解决问题的办法.跟无头苍蝇一样,会不加思索地把错误粘到百度上,希望赶紧查找一下 ...

  4. iOS 有些库只能在真机上运行,不能在模拟器上运行的解决方式

    在开发中,多少肯定会用到第三方的东西,或许大家也和我一样遇到到这样的情况,有些库正好适合自己的需求,但是这个库却只支持真机上运行,在模拟器上编译却不通过, 一般情况下,.a静态包,你刚刚导入的时候,不 ...

  5. 重设SVN 的GNOME keyring [(null)] 的密码

    在ubuntu里如果改了登录密码,那么在使用svn是会要求GNOME keyring [(null)] 的密码: 去掉这个只需:rm -f ~/.gnome2/keyrings/login.keyri ...

  6. ajax实现分页页签

    在一些搜索列表的页面中,我们会遇到一些需要处理页签的需求,一般这样的页面,要么是在JSP中处理,每次都跳页.这样做是个很方便的方法.但是如果页面上有很多和列表无关,每次都需要重新渲染是不是显得慢了一些 ...

  7. 第49章 在SRAM中调试代码—零死角玩转STM32-F429系列

    第49章     在SRAM中调试代码 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fir ...

  8. currency 过滤器

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  9. LeetCode567. Permutation in String

    Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...

  10. C#基础-面向对象-封装

    封装 命名空间 using System; using System.Collections.Generic; using System.Text; namespace ConsoleApp6 { c ...