Java框架篇spring sleuth分布式日志查询
发布日期:2021-06-30 16:19:32 浏览次数:2 分类:技术文章

本文共 3578 字,大约阅读时间需要 11 分钟。

前言

随着微服务数量不断增长,需要跟踪一个请求从一个微服务到下一个微服务的传播过程, Spring Cloud Sleuth 正是解决这个问题,它在日志中引入唯一ID,以保证微服务调用之间的一致性,这样你就能跟踪某个请求是如何从一个微服务传递到下一个。

  如果你有使用AOP拦截Servlet的经验,做一个基于AOP的简单服务统计和跟踪很容易。但要像Zipkin那样能够跟踪服务调用链就比较困难了。所谓调用链,就是A服务调用B服务,B服务又调用了C、D服务。这样一个链要想统计跟踪,要写不少代码。而Spring Cloud Sleuth能让你不写一行代码的情况下完成这些。

应用

1 增加依赖

org.springframework.cloud
spring-cloud-starter-sleuth
2.0.1.RELEASE

2 配置logback

logback众所周知可以输出到console,file和远程服务器,我们项目中定义输入到统一的服务器:

https://api.puhuifinance.com/log-server/log
@project.artifactId@
@config.branch@
ERROR
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} | %clr(${LOG_LEVEL_PATTERN:-%5p}){magenta} |[%X{X-B3-TraceId:-}]| [%X{token}] | %clr(---){faint}| %clr([%15.15t]){faint} | %clr(%-40.40logger{39}){cyan} | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

pattern的含义:

  • 时间,加颜色clr
  • 日志级别
  • TraceId
  • 自定义输出属性token,token在filter中存入MDC即可,代码:
    MDC.put("token", "111888");
  • 分隔符----
  • thread
  • logger内容 也就是包路径,类
  • 信息,包括异常

3. 日志查询

  • 每个请求都会生成一个traceid
  • spanId在跨微服务的时候发生变化,微服务内不变化
  • 查询条件区分大小写,比如AND,不能写成and

4 问题

一开始调试的时候,在logback增加了自定义属性token,但是本地调试就是不输出,后来发现我改动的logback的appender是输出到远程服务器到,本地当然不会修改,部署到云平台后,日志系统可以正常输出,没有问题。

5 自定义key

除了traceid和spanid等四个默认属性,可以自定义属性,只要存入MDC就可以,代码如下:

写一个拦截器:

package com.puhui.goosecard.bank.interceptor;import com.alibaba.fastjson.JSONObject;import com.puhui.goosecard.bank.controller.BindCardController;import com.puhui.goosecard.common.model.bank.shyk.BindCardCheckReq;import org.slf4j.MDC;import org.springframework.stereotype.Component;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedReader;/** * 2 * @Author: kerry * 3 * @Date: 2018/9/19 16:52 * 4 */@Component(value = "handlerInterceptor")public class MDCInterceptor implements HandlerInterceptor {    private String getBody(HttpServletRequest request) {        String wholeStr = "";        try {            BufferedReader br = request.getReader();            String str = "";            while ((str = br.readLine()) != null) {                wholeStr += str;            }        } catch (Exception e) {        }        return wholeStr;    }    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        String body = getBody(request);        if (((HandlerMethod) handler).getBean() instanceof BindCardController) {            BindCardCheckReq bindCardCheckReq = JSONObject.parseObject(body, BindCardCheckReq.class);            MDC.put("outTradeNo", bindCardCheckReq.getOutTradeNo());        }        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {    }}

注册拦截器:

@Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(handlerInterceptor);    }}

 

转载地址:https://kerry.blog.csdn.net/article/details/82777223 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java算法篇KMP算法及应用
下一篇:java算法篇给定一个数组找出第一个重复(不重复)的元素

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月16日 00时15分34秒