GateWay具体的使用之全链路跟踪TraceId日志

1.创建全局过滤器,在请求头上带入traceId参数,穿透到下游服务. 

package com.by.filter;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSignerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.net.URI;
import java.util.List;@Slf4j
@Component
public class TraceIdFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();List<String> traceIds = request.getHeaders().get("traceId");//判断是否有traceIdif (CollUtil.isNotEmpty(traceIds)) {// 放行return chain.filter(exchange);}//为空,生成一个traceIdString traceId = IdUtil.simpleUUID();// 创建新的请求ServerHttpRequest newRequest = request.mutate().header("traceId", traceId).build();// 创建新的exchangeServerWebExchange newExchange = exchange.mutate().request(newRequest).build();// 放行return chain.filter(newExchange);}
}

2.MDC原理


当请求来时生成一个traceId放在ThreadLocal里,然后打印时去取就行了。但在不改动原有输出语句的前提下自然需要日志框架的支持了。

MDC 介绍​ MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的Map,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。

3.下游服务如何使用全链路跟踪Id

3.1配置TraceId 过滤器

 

package com.by.filter;import org.slf4j.MDC;
import org.springframework.core.annotation.Order;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;//@Order(1)//优先级
@WebFilter//过滤器放入IOC
public class TraceIdFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;//转换 类型String traceId = httpServletRequest.getHeader("traceId");//获取请求头//将traceId放入MDCMDC.put("traceId", traceId);try {//放行chain.doFilter(request, response);}finally {//清除MDC.clear();}}
}

3.2 启动类开启ServletComponentScan扫描。 

@SpringBootApplication@ServletComponentScan
public class OpenApp {public static void main(String[] args) {SpringApplication.run(OpenApp.class, args);}}

3.3 配置文件配置日志输出格式

##日志输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%-5level) %clr([%X{traceId}]) %clr(${PID:-}) --- %clr(%logger{50}) - %m%n

4.Openfeign扩展

@Component
public class OpenFeignRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {String traceId = MDC.get(TraceIdFilter.MDC_TRACE_ID);requestTemplate.header(TraceIdFilter.MDC_TRACE_ID, traceId);}
}

5.附(Kibana日志图标)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mockito Mybatis-plus 单元测试

1. mock Mybatis-plus 自带 ServiceImpl方法问题 分析 mybatis-plus 自带的ServiceImpl&#xff0c;其实其最后执行使用的是我们所创建的Mapper&#xff0c;他最终会注入到 ServiceImpl的baseMapper中 - 示例 业务代码 // 实体 public class UtilSaleData { }// mapper public …

数据结构1(初):时间复杂度和空间复杂度

目录 1、引言 1.1、什么是数据结构&#xff1f; 1.2、什么是算法&#xff1f; 1.3、如何学好数据结构和算法 &#xff1f; 2、算法效率 2.1、如何衡量一个算法的好坏 2.2、算法的复杂度 3、时间复杂度 3.1、时间复杂度的概念 3.2、大O的渐进表示法 3.3、常见时间复杂…

C语言自定义类型【联合体与枚举】

文章目录 1.联合体1.1联合体的声明1.2联合体的特点1.3联合体的大小计算联合体的使用案例 2.枚举2.1枚举类型的声明2.2枚举类型的优点(为什么使用枚举)2.3枚举类型的使用 结语 1.联合体 1.1联合体的声明 和结构体一样&#xff0c;联合体也是由一个或多个成员构成&#xff0c;同…

2024-04-27 问AI: 在深度学习中,什么是DCGAN?

文心一言 在深度学习中&#xff0c;DCGAN&#xff08;Deep Convolutional Generative Adversarial Networks&#xff09;是生成对抗网络&#xff08;GAN&#xff09;的一种改进版本&#xff0c;它主要通过引入卷积神经网络&#xff08;CNN&#xff09;来提高生成器和判别器的性…

Python量化炒股策略(二)

日志用来记录Python量化炒股策略的状态、错误和信息消息&#xff0c;也经常作为调试程序的工具。 日志log 设定log级别 设定log级别语法格式如下&#xff1a; log.set_level(name, level)设置不同种类的log级别&#xff0c;低于这个级别的log不会输出。所有log的默认级别是…

编辑器,编译器,IDE的区别

1.编辑器,编译器 简单说编辑器是用来写代码的&#xff0c;而编译器是对现场高级语言代码翻译成相对低级语言的一段小程序/指令。 2.IDE 集成开发环境&#xff08;IDE&#xff0c;Integrated Development Environment &#xff09;是用于提供程序开发环境的应用程序&#xff…

Atcoder Beginner Contest351 A-E Solution题解

文章目录 [A - The bottom of the ninth](https://atcoder.jp/contests/abc351/tasks/abc351_a)[B - Spot the Difference ](https://atcoder.jp/contests/abc351/tasks/abc351_b)[D - Grid and Magnet](https://atcoder.jp/contests/abc351/tasks/abc351_d)E Note&#xff1a;…

NUD4700

这份文件是关于NUD4700型号电子元件的数据手册&#xff0c;由半导体元件工业公司&#xff08;Semiconductor Components Industries, LLC&#xff09;在2009年1月发布。以下是该文件的核心内容&#xff1a; 产品描述&#xff1a; NUD4700是一个电子旁路器件&#xff0c;用于在单…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属&#xff0c;而web框架一直是悬而未决&#xff0c;说到底还是因为没有官方成熟的方案指引&#xff0c;大家各玩各的&#xff0c;互不兼容&#xff0c;白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…

如何将本地Android studio项目上传到GitHub

操作步骤&#xff1a; 1、在GitHub上创建账户 2、在androd studio中添加上述创建的GitHub账号 3、在android studio上找到"share project on GitHub"&#xff0c;点击此选项上传当前项目到GitHub 上传成功后&#xff0c;会在GitHub上创建默认仓库repository 注&a…

如何实现线程的同步了?

什么是线程的同步了?就是在多个线程访问一个数据的时候,如何防止数据的一致性和避免竞争问题 1.Synchronized关键字,给线程上锁,相当于小朋友在排队玩玩具,一个玩完才能接着下一个 2.ReentrantLock:可重入锁,就是一群人在上厕所,但是厕所的开关被进入的那个人给锁住了,只有这个…

mysql-sql-练习题-2-窗口函数

窗口函数 访问量max sum建表窗口函数连接 直播间人数 第1、3名建表排名sum 访问量max sum 每个用户截止到每月为止&#xff0c;最大单月访问次数&#xff0c;累计到该月的总访问次数 建表 create table visit(uid1 varchar(5) comment 用户id,month1 varchar(10) comment 月…

阳光能源,创造永远:光模块的未来”:随着大数据、区块链、云计算和5G的发展,光模块成为满足不断增长的数据流量需求的关键技术

光模块的类型介绍&#xff1a; 为了适应不同的应用需求&#xff0c;不同参数和功能的光模块应运而生。光模块的分类方式及类型详见如下&#xff1a; &#x1f50e;封装形式&#x1f50d;&#xff1a; &#x1f4e3;&#x1f4e2;光模块按照封装形式来分有以下几种常见类型&a…

声光控路灯控制系统设计与仿真

目录 前言 一、设计任务 二、系统组成及工作原理 1、总体设计思路 2、电路各模块设计简介 &#xff08;1&#xff09;光控电路 &#xff08;2&#xff09;声控电路 (3) 逻辑控制电路 (4) 延时电路 三、系统中电源模块的设计 1、方案比较和确定 2、 设计思路 3、直流…

OpenHarmony实战开发-如何实现自定义绘制 (XComponent)

XComponent组件作为一种绘制组件&#xff0c;通常用于满足开发者较为复杂的自定义绘制需求&#xff0c;例如相机预览流的显示和游戏画面的绘制。 其可通过指定其type字段来实现不同的功能&#xff0c;主要有两个“surface”和“component”字段可供选择。 对于“surface”类型…

AcrelEMS-MH民航机场智慧能源管平台解决方案【可靠供电/降低能耗/高效运维】

民航机场行业背景 自2012年以来&#xff0c;我国民航运输规模出现了显著增长&#xff0c;旅客运输量&#xff1a;从2012年的3.19亿人次上升至2019年的6.6亿人次&#xff08;注&#xff1a;为剔除疫情影响&#xff0c;此处采取疫情前2019年的数据&#xff0c;下同&#xff09;&…

java:SpringBootWeb请求响应

Servlet 用java编写的服务器端程序 客户端发送请求至服务器 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器 服务器将响应返回给客户端 javaweb的工作原理 在SpringBoot进行web程序开发时,内置了一个核心的Servlet程序DispatcherServlet,称之…

msf渗透实验,抓取密钥及密钥生成原理所引发的问题

1、生成反向shell msfvenom --list payloads 查看某个功能模块的具体功能msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST192.168.208.128 LPORT12345 -f exe -o shell.exe 生成一个.exe的控制文件&#xff0c;反向连接的payload2、接收shell,与反向shell建立连接 …

【小迪安全2023】第59天:服务攻防-中间件安全CVE复现lSApacheTomcatNginx

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

最短路(Dijkstra, Bellman-Ford, SPFA, Floyd)

最短路 Dijkstra算法&#xff08;复杂度 O ( m l o g n ) O(mlog n) O(mlogn)/ O ( n m l o g n ) O(nmlogn) O(nmlogn)&#xff09;–不能有负权边&#xff0c;不能有负权环&#xff0c;单源最短路径( O ( m l o g n ) O(mlog n) O(mlogn))&#xff0c;多源最短路径( O ( n m…