Bootstrap

Java如何通过日志排查问题

问题:

大家有没有遇到过这样一种场景,在一个接口或者方法当中,业务逻辑很复杂,方法嵌套调用层级很深,此时要定位业务流程的走向,是不是要在每个方法中打日志,而这些日志是不串联的,比如,一个接口调用下来,程序没有报错,但没有按预期执行,怎么排查,就得翻这个方法调用时的每一条记录日志,而代码是并行执行的,程序中不可能只有这一个方法调用,那就会有其它日志夹杂在我们希望查看的日志中间。影响我们的定位。如何解决?

方法一:

最先想到的方法就是在这个方法的每个日志当中都加一个标志,这样通过日志来过滤不就可以了吗?这也许是一个方法,但在一个大方法里面,要在每一处记日志的地方都增加标记,一来繁琐,二来要在日志中定位也很麻烦。

方法二:

本文就提供一个使用Java中的ThreadLocal方法来记录日志的方案,大家知道ThreadLocal可以跨方法获取,只要在同一个线程当中执行,每个方法都可以获取ThreadLocal对象,Spring中的@Transactional注解就是通过ThreadLocal来存储数据源的,这里我们通过ThreadLocal来存储日志,在方法的最后,我们统一记录一条日志,在这一条日志当中,可以清楚地看到每一条记录的执行步骤。缺点就是在多线程当中会有问题。

下面我们看看是如何实现的。

package com.zhixinyi.job.common;

import com.zhixinyi.job.util.LogUtils;

import java.util.ArrayList;
import java.util.List;

public class TraceContext {
    private static class TraceContent {
        private String key;
        private String value;
        private long currentMills;

        public TraceContent(String key, String value) {
            this.key = key;
            this.value = value;
            this.currentMills = System.currentTimeMillis();
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

       
;