当前位置: 首页 > news >正文

Spring boot结合SkyWalking-Trace工具类实现日志打印请求链路traceid

背景:

随着业务的复杂化、解耦化,运维人员和开发人员需要对请求链路跟踪来快速发现和定位问题,基于应用已经集成了SkyWalking的前提下,如何通过获取SkyWalking生成的统一traceId并加入打印日志中,方便开发人员能够根据链路ID快速搜索单个请求的全链路日志呢?

基本思路:

trace-id的生成:

结合apm-toolkit-trace提供的工具类获取请求的trace-id,前提是应用已经集成对接了SkyWalking

trace-id的存放:

一种轻量级的实现,通过  MDC 机制,将请求的 trace-id 放入到MDC中,在日志打印时,通过 MDC 中的 trace-id 将同一个请求的每一条日志串联起来。因为 MDC 是线程隔离且安全的。

trace-id的打印:

通过修改logback.xml配置中pattern增加输出参数%X{traceId}来控制。

trace-id存放的触发机制:

通常实现方式,采用增加日志拦截器的做法,将拦截服务所有外部请求,在请求前置处理中将生成trace-id并保存入MDC中。

代码示例:

通用做法-开发三板斧:依赖、配置、注解与编码

依赖 

<!-- skywalking依赖包 打印traceid -->
<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.7.0</version>
</dependency>

配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds"><jmxConfigurator/><contextName>logback</contextName><springProperty scope="context" name="module_name" source="spring.application.name"/><!-- 读取apollo配置中心设置的变量 --><springProperty scope="context" name="version" source="app.version"/><springProperty scope="context" name="env" source="app.env"/><timestamp key="log_date" datePattern="yyyy-MM-dd"/><!--自定义输出 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - thead=%thread - level=%-5level - class=%logger{20} - token=%X{token} - traceId=%X{traceId} - content=%msg%n</pattern></encoder></appender><!-- 日志输出级别 --><root level="debug"><appender-ref ref="STDOUT"/></root></configuration>

编码

(1) 自定义拦截器LoggerInterceptor

package com.zzia.demo.interceptor;import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.skywalking.apm.toolkit.trace.TraceContext;@Component
public class LoggerInterceptor implements HandlerInterceptor {/*** @return 返回 true 放行、放回 false 拦截*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("进入拦截器,前置通知" + request.getRequestURI());// 过滤掉确认的 options 请求if ("OPTIONS".equals(request.getMethod())) {return true;}// 单链路上下文信息存入MDC// 请求凭证String token = request.getHeader("__ub_token");MDC.put("token", token);//每次请求生成唯一的请求标识,作为内部链路的日志追踪标识MDC.put("traceId", TraceContext.traceId());// 业务身份字段可扩展加入String userId = "123456";MDC.put("userId", userId);if (token != null) {return true;}return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置通知");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("最终通知");MDC.clear();}
}

(2) 注册拦截器

package com.zzia.demo.interceptor;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MyLoggerConfigurer implements WebMvcConfigurer {@AutowiredLoggerInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor)    // 添加自定义拦截器.excludePathPatterns("/index") // 设置放行路径.addPathPatterns("/**");       // 设置拦截路径}
}

演示效果:

说明:本示例的前置准备参见文章Spring boot 集成Skywalking_幽幽之心的博客-CSDN博客 

相关文章:

Spring boot结合SkyWalking-Trace工具类实现日志打印请求链路traceid

背景&#xff1a; 随着业务的复杂化、解耦化&#xff0c;运维人员和开发人员需要对请求链路跟踪来快速发现和定位问题&#xff0c;基于应用已经集成了SkyWalking的前提下&#xff0c;如何通过获取SkyWalking生成的统一traceId并加入打印日志中&#xff0c;方便开发人员能够根据…...

精通ES=ElasticSearch

Elasticsearch 是一个分布式、高扩展、高实时的搜索与 数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平 伸缩性&#xff0c;能使数据在 生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤&#xff0c;首先用…...

RabbitMQ-扇形交换机(Fanout )

扇形交换机&#xff1a;Fanout Exchange扇形交换机是最基本的交换机类型&#xff0c;它所能做的事情非常简单———广播消息。扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要“思考”&#xff0c;所以扇形交换机处理消息的速度也是所有的交换机类…...

Python 学习曲线 从 Python 新手到 Pro

Python 学习曲线 从 Python新手到 Pro 使用代码片段介绍&#xff1a; Python 是世界上最通用和使用最广泛的编程语言之一&#xff0c;以其简单性、可读性和多功能性而闻名。 在本文中&#xff0c;我们将探讨一系列示例场景&#xff0c;其中代码由具有三个不同专业知识水平的程序…...

薪资18K需要什么水平?来看看98年测试工程师的面试全过程…

我的情况 大概介绍一下个人情况&#xff0c;男&#xff0c;本科&#xff0c;三年多测试工作经验&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能&#xff0c;然而到今天都没有收到一份offer&#xff01;从年后就开始准备简历&#xff0c;年…...

基于趋动云的 Stable Diffusion Webui 环境搭建

Stable Diffusion Webui 环境搭建&#xff0c;首先新建一个项目&#xff1a; 然后&#xff0c;选择镜像。注意点公开的&#xff0c;已近做好的这个镜像&#xff0c;superx创建&#xff0c;集成了miniconda3的镜像。 然后选择添加数据源&#xff0c;一样&#xff0c;还是点公开&…...

备忘录设计模式解读

目录 问题引进 游戏角色状态恢复问题 传统方案解决游戏角色恢复 传统的方式的问题分析 备忘录模式基本介绍 基本介绍 备忘录模式的原理类图 对原理类图的说明 游戏角色恢复状态实例 应用实例要求 思路分析和图解(类图) 代码实战 备忘录模式的注意事项和细节 问题引…...

股票期货模拟交易有用吗?股票期货模拟交易心得

股票期货市场为了满足新用户的需求&#xff0c;有专门的股票期货模拟交易平台&#xff0c;大家可以在这个平台上进行股票期货的模拟交易&#xff0c;这样可以通过不断总结&#xff0c;丰富我们的知识。下面整理的股票期货模拟交易实验心得&#xff0c;从股票期货模拟交易与实盘…...

2023年五月份图形化三级打卡试题

活动时间 从2023年5月1日至5月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…...

【华为OD机试真题】字母组合(javapython)100%通过率 详细代码注释

字母组合 知识点回溯 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 每个数字对应多个字母,对应关系如下: 0: a,b,c 1: d,e,f 2: g,hi 3: j,k,l 4: m,n,o 5: p,q,r 6: s,t 7:u,v 8: w,x 9: y,z 输入一串数字后,通过数字和字母的对应关系可以得到多个字母字符串 (要…...

精彩!openEuler 社区年度顶级会议发生了啥?

2023年4月20-21日&#xff0c;万涓汇流&#xff0c;奔涌向前&#xff0c;openEuler Developer Day2023(以下简称“ODD2023”)在上海以线上线下的方式圆满举办。 本次大会由开放原子开源基金会指导&#xff0c;中国软件行业协会、openEuler社区、边缘计算产业联盟共同主办&#…...

Confidential Containers发布0.5.0版本,龙蜥将基于八大特性构建开箱即用的机密容器解决方案

文/段勇帅 01 前言 机密容器&#xff08;Confidential Containers&#xff0c;简称CoCo&#xff09;是 Cloud Native Computing Foundation&#xff08;CNCF&#xff09;Sandbox 项目。目前机密容器项目的核心参与者包括阿里云、AMD、ARM、IBM、Intel、Microsoft、Red Hat、R…...

独立储能的现货电能量与调频辅助服务市场出清协调机制(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …...

使用 Luckysheet 可实现 Web 的 Excel

一、写在前面 工作中会遇到excel的导入和导出&#xff0c;换个角度看&#xff0c;假如有个 web 版本的excel &#xff0c;且能上传现有的&#xff0c;修改编辑后再下载也是个不错的方案。 Luckysheet 是实现 web版Excel的一个优秀的框架。 Luckysheet &#xff0c;一款纯前端类…...

时间序列预测(一)基于Prophet的销售额预测

时间序列预测&#xff08;一&#xff09;基于Prophet的销售额预测 小O&#xff1a;小H&#xff0c;有没有什么方法能快速的预测下未来的销售额啊 小H&#xff1a;Facebook曾经开源了一款时间序列预测算法fbprophet&#xff0c;简单又快速&#xff5e; 传统的时间序列算法很多&a…...

【电科复试第一名】23上交819考研经验分享

笔者来自通信考研小马哥23上交819全程班学员 819&#xff0c;上岸经验贴&#xff0c;知无不言 初试第十一&#xff0c;复试第一&#xff0c;总分第七(与第六同分) 考研经历:本科就读与湖南某末985&#xff0c;大学时间没好好学习&#xff0c;天天打王者&#xff0c;玩steam上…...

每日学术速递4.24

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Collaborative Diffusion for Multi-Modal Face Generation and Editing(CVPR 2023) 标题&#xff1a;多模态人脸生成和编辑的协同扩散 作者&#xff1a;Ziqi Huang, Kelvin C.K. …...

怎么把mkv文件转成mp4格式,3招立马处理

怎么把mkv文件转成mp4格式的方法你知道吗&#xff1f;我想很多朋友会遇到这样的情况&#xff0c;下载视频后发现无法打开。原来我们下载的视频格式是mkv&#xff0c;也许这个格式大家不是很熟悉的。那么今天就来认识一下&#xff0c;mkv是Matroska的一种媒体文件&#xff0c;mk…...

SEO机制算是让我玩明白了

获取当前时间时间戳&#xff0c;返回遵循ISO 8601扩展格式的日期 new Date(Date.now()).toISOString() 使用moment库转换回来 this.moment(new Date(Date.now()).toISOString()).format("YYYY-MM-DD") js去掉富文本中html标签和图片 filterHtmlTag(val) {if(!val){…...

JDBC连接数据库详细教程指南

目录 一、JDBC介绍 二、JDBC环境的搭建 三、JDBC的开发步骤 1、加载JDBC驱动程序 2、建立数据库连接 3、创建Statement对象 4、执行SQL语句 5、处理结果集 6、关闭连接 7、示例程序 8、注意 一、JDBC介绍...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...