SpringBoot增加全局traceId日志追踪

这篇具有很好参考价值的文章主要介绍了SpringBoot增加全局traceId日志追踪。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现思路

  1. 增加Filter处理请求,生成traceId保存到TreadLocal中(slf4j的MDC)
  2. 增加返回AOP切面,返回数据之前把traceId写到返回实体里
  3. 日志logback.xml文件配置增加traceId打印

注意:线程池执行和其他服务请求会丢失traceId,需要再做包装,这里不实现文章来源地址https://www.toymoban.com/news/detail-824242.html

定义过滤器

/**
 * @author lenjor
 * @description requst包装类,构建可重复读取inputStream的request
 * @date 2024-01-24 11:13
 */
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public RepeatedlyRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = HttpHelper.getBodyString(request).getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public int available() throws IOException {
                return body.length;
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }
}


/**
 * @author lenjor
 * @Description 全局请求增加traceId日志追踪,保存到ThreadLocal的MDC中
 * @Date 2024-01-24 15:29
 */
public class TraceIdFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String oldTraceId = httpRequest.getHeader("traceId");

            if(!StringUtils.isEmpty(oldTraceId)){
                MDC.put("traceId",oldTraceId);
            }else {
                // 生成唯一的traceId
                MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
            }
            if (request instanceof HttpServletRequest && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
                ServletRequest requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request);
                chain.doFilter(requestWrapper, response);
            }else {
                chain.doFilter(request, response);
            }
        } finally {
            // 清除MDC的traceId值,确保在请求结束后不会影响其他请求的日志
            MDC.remove("traceId");
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

/**
 * @author lenjor
 * @Description web请求全局traceId处理
 * @Date 2024-01-24 15:35
 */
@Configuration
public class GlobalWebTraceIdConfig {
    @Bean
    public FilterRegistrationBean<TraceIdFilter> loggingFilter() {
        FilterRegistrationBean<TraceIdFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TraceIdFilter());
        registrationBean.addUrlPatterns("/*"); // 设置过滤的URL模式
        return registrationBean;
    }
}

返回参数增加traceId

/**
 * @author lenjor
 * @Description 请求返回AOP切面增强,增加traceId返回
 * @Date 2024-01-24 16:06
 */
@ControllerAdvice(basePackages = "com.yingzi.idp.edge.app.v2.interfaces.rest")
public class TraceIdResponseAdvice implements ResponseBodyAdvice<ResultDTO> {
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return returnType.getMethod().getReturnType().isAssignableFrom(ResultDTO.class);
    }

    @Override
    public ResultDTO beforeBodyWrite(ResultDTO body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (Objects.nonNull(body)) {
            body.setTraceId(MDC.get("traceId"));
        }
        return body;
    }
}

logback.xml增加traceId

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]{traceId: %X{traceId}}::: %class{0}.%method\(%line\)
                %msg%n
            </pattern>
        </encoder>

到了这里,关于SpringBoot增加全局traceId日志追踪的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】Spring Boot 日志文件

    日志是程序的重要组成部分,想象一下,如果程序报错了,不让你打开控制台看日志,那么你能找到报错的原因吗。 日志对于我们来说,最主要的用途就是排除和定位问题。除了发现和定位问题之外,我们还可以通过日志实现以下功能: 记录用户登录日志,方便分析用户是

    2024年02月01日
    浏览(43)
  • Java EE 突击 9 - Spring Boot 日志文件

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月13日
    浏览(39)
  • Java实战:Spring Boot实现AOP记录操作日志

    本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例来演示整个实现过程。本文适合已经具备Spring Boot基础

    2024年02月22日
    浏览(41)
  • Kafka增加安全验证安全认证,SASL认证,并通过spring boot-Java客户端连接配置

    公司Kafka一直没做安全验证,由于是诱捕程序故需要面向外网连接,需要增加Kafka连接验证,保证Kafka不被非法连接,故开始研究Kafka安全验证 使用Kafka版本为2.4.0版本,主要参考官方文档 官网对2.4版本安全验证介绍以及使用方式地址: https://kafka.apache.org/24/documentation.html#secu

    2024年02月01日
    浏览(45)
  • 【全链路追踪】XXL-JOB添加TraceID

    首先这个项目属于小型项目,由于人手以及时间限制,并未引入Skywalking等中间件来做调用链路追踪。Skywalking不在此次的讨论范围中。 其次介绍一下项目的相关背景 项目中主要有两种调用路径 Web请求走统一的网关入口,调用后端服务 XXL-JOB定时任务执行调度 Kubernetes 走统一网

    2024年02月11日
    浏览(24)
  • Spring Cloud Gateway日志级别链路追踪设计

    ​ 为了配合日志分析系统ELK(ElasticSearch,Logstash,Kibana)方便解析日志文件,需要对日志文件的输出格式进行JSON格式化,我这里使用的日志工具是logback(幸运的躲过了log4j的漏洞)+logstash-encoder包进行的封装的一个日志插件,该插件实现了日志JSON格式化,适配了多种中间件的链

    2024年02月11日
    浏览(32)
  • springboot增加logback日志记录ip

    1、增加logback配置文件: 2、增加获取ip工具类: 3、增加logbackxml配置  完整xml:

    2024年02月11日
    浏览(36)
  • Spring Boot中集成各种日志框架Logback、Log4j2和Java Util Logging

    Spring Boot支持多种日志框架,包括Logback、Log4j2和Java Util Logging(JUL)。在Spring Boot中,可以通过简单的配置来集成这些热门的日志框架。 下面将详细说明如何集成Logback、Log4j2和Java Util Logging,并提供相应的源代码示例。 集成Logback: Logback是Spring Boot默认的日志框架,它提供了高

    2024年02月05日
    浏览(42)
  • dubbo3+sleuth+brave实现链路追踪及traceId未传递或不对应的原因分析

    笔者之前一直使用SpringCloud Alibaba + dubbo2 + nacos1.4进行开发,但是目前naocs2、dubbo3也已经推出有一段时间并逐渐达到生产环境可用状态,所以笔者也希望用最新版本的nacos2及dubbo3尝尝鲜。但在搭建框架的过程中遇到了链路追踪的问题,所以在这里详细记录一下。 笔者基于dubbo

    2024年02月10日
    浏览(30)
  • SpringCloudGateway使用Skywalking时日志打印traceId

    Skywalking oap 与 agent部署 https://blog.csdn.net/kismet2399/article/details/131560171 spring-cloud-starter-gateway:3.1.4 Skywalking Agent:8.14.0 SpringCloudGateway集成Skywalking后无法打印traceId 目前没有找到logback的解决方式,所以日志打印改用log4j2 mvn添加配置 让日志获取到traceId 插件添加 将skywalking-agent下opt

    2024年02月13日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包