日志对于一个系统来说非常重要,当系统出现了问题的时候,我们可以根据日志来排查问题所在,但是在排查日志的时候,很多日志都混合在一起,不知道哪些是一次请求的,给排查带来了不小的麻烦,今天分享一个把一次请求所有的日志串联起来的方法,抛砖引玉,如果大家还有更好的,欢迎留言。
原理: 给每次请求的所有日志都增加一个唯一的标识
技术实现: 利用slf4j的MDC 以及 jfinal handler
技术原理: 在每一次请求到来之前,我们会在ThreadLocal变量中也就是上边的MDC中添加一个标识,每次打印日志的时候这个标识会作为日志的一部分,MDC是框架支持的内容,我们只需要向里面放入标识即可,剩下打印日志和普通的打印日志一样,不需要额外的操作
用途: 在问题排查的时候我们可以根据该标识,来找到哪些日志是一次请求的,便于定位问题的所在,该标识在结合splunk等日志分析工具的时候尤为重要
代码实现
Handler 代码
REQUESTID 就是日志的标识
public class RequestIdHandler extends Handler {
private static final String REQUESTID = "REQUESTID";
@Override
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
//REQUESTID 就是日志的标识,该id可以前端传入,如果前端没有传入我们就在后端自己生成
String requestId = request.getHeader(REQUESTID);
if(StrKit.isBlank(requestId)){
requestId = StrKit.getRandomUUID();
}
MDC.put(REQUESTID, requestId);
next.handle(target, request, response, isHandled);
}
}
日志配置文件
//下边的REQUESTID就是日志的标识
log4j.appender.LogFile.layout.ConversionPattern ==%X{REQUESTID}|%d{yyyy-MM-dd HH:mm:ss,SSS} %p %l -%m%n
例子
下边的例子(高亮部分就是日志标识)就是从一个日志文件中找到了某一次请求的所有日志,从里面我们可以看出来依次执行了哪些过滤器, 哪些sql语句