分布式日志设计,Java代码实现

业务开发中,日志的收集极为重要,特别是在进行故障分析时,日志记录得好,可以帮我们快速定位问题原因。

Linux日志查看命令:tail、cat、head、more

tail 和 head 命令
tail 查看日志尾部最后几行的日志,一般会结合 grep 进行搜索应用:
tail -n 10 test.log tail -fn 1000 test.log | grep 'test'

head 和 tail,查看日志文件的前几行日志,其他应用和 tail 类似:
head -n 10 test.log

more 和 less
more 命令可以按照分页的方式现实日志内容,并且可以进行快速地翻页操作,除了 more 命令以外,常用的还有 less 命令,和 more 的应用类似。

cat
cat 命令用于查看全部文件,是由第一行到最后一行连续显示在屏幕上,一次显示整个文件。

在分布式系统下,用户一个请求通常需要先后调用(rpc、http)多个工程模块,依次处理数据,才能返回正确结果。日志变得越来越分散,如何更好地收集和分析日志,就变成了一个特别重要的问题。

存在的问题:如何对日志文件之间的关系进行聚合,从全局上梳理日志,从而进行调用链路的分析。

考虑到上述问题,我在工作中设计了一个分布式链路日志方案:

  1. 通过aop切面思想,对每个工程设计一个日志拦截器,并统一日志key名。
  2. 拦截器内部对于每个请求,先检查key对应的value是否为空,如果为空则自己生产一个唯一日志id放入请求头。
  3. 对于所有产生的日志,直接丢入消息队列。
  4. 利用es异步收集统计所有队列中日志。

根据该方案,即可通过请求附带server_request_id实现日志链路调用分析,具体判断哪个工程模块出现了异常。

具体代码如下:

@Component
@Slf4j
@Order(1)
public class LogFilter implements Filter {
    private static final String REQUEST_ID = "server_request_id";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String requestId = httpRequest.getHeader(REQUEST_ID);
        if (requestId == null) {
            requestId = UUID.randomUUID().toString();
        }

        log.info("requestId is: {}", requestId);
        MDC.put(REQUEST_ID, requestId);
        httpResponse.setHeader(REQUEST_ID, requestId);

        try {
            chain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }

}

你可能感兴趣的:(Springboot,Java,Java面试,java,分布式,开发语言)