最新要闻
- 【世界报资讯】河南省通许县:“中国酸辣粉之都”正式揭牌
- 天天热门:微信下重拳:上万个群被封杀 此类行为千万别做
- 环球微头条丨程序员20年喝近2吨可乐屡患结石 几乎天天喝
- 联想推ThinkPad Z16 Gen 2笔记本:锐龙7000系列 可选4K+屏
- 双子姐妹、冰箱很带感 《原子之心》游戏已被破解:俄罗斯自己黑客干的
- 还敢生吃?日本即将核污水倒入大海 降低水产品氚活度分析精度
- 世界观天下!老外首次用上徕卡影像!小米13/Pro国际版发布:999欧元起
- 全球看热讯:9岁女演员获柏林电影节最佳主角:史上最年轻获奖者
- 今日热门!高三女生因百日誓师热血发言表情被网暴 父亲怒回应:我们的骄傲 请尊重
- 《流浪地球2》导演郭帆让学生们不要用ChatGPT写作业:老师分辨不出来
- 美国铁路烂到家:“毒列车公司”再次发生脱轨事故 问题没法解决
- 【世界速看料】昔日手机巨头换新!诺基亚换全新Logo 刷新认识:网友直呼爷青结
- 每日热议!残损货币及不宜流通货币常识_不宜流通人民币与残损币区别
- AMD RX 7900显卡价格在中国崩盘了!两个月暴跌1400元
- 世界滚动:不完整的爱情
- 每日动态!怎样提高空间想象能力 如何提高空间想象能力
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球短讯!Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
来源:blog.csdn.net/qq_35387940/article/details/125062368
前言
从文章标题就知道,这篇文章是介绍些什么。
【资料图】
这是我一位朋友的问题反馈:
好像是的,确实这种现象是普遍存在的。
有时候一个业务调用链场景,很长,调了各种各样的方法,看日志的时候,各个接口的日志穿插,确实让人头大。
模糊匹配搜索日志能解决吗? 能解决一点点。 但是不能完全呈现出整个链路相关的日志。
那要做到方便,很显然,我们需要的是把同一次的业务调用链上的日志串起来。
什么效果? 先看一个实现后的效果图:
这样下来,我们再配合模糊匹配查找日志,效果不就刚刚的了。
cat -n info.log |grep "a415ad50dbf84e99b1b56a31aacd209c"
或者
grep -10 "a415ad50dbf84e99b1b56a31aacd209c" info.log (10是指上下10行)
不多说,开整。
正文
惯例,先看一眼这次实战最终工程的结构:
Spring Boot 基础就不介绍了,推荐看这个免费教程:
https://github.com/javastacks/spring-boot-best-practice
①pom.xml 依赖
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-logging org.projectlombok lombok 1.16.10
②整合logback,打印日志,logback-spring.xml (简单配置下)
[%X{TRACE_ID}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n ${log}/%d{yyyy-MM-dd}.log 30 [%X{TRACE_ID}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 10MB
application.yml
server: port: 8826logging: config: classpath:logback-spring.xml
③自定义日志拦截器 LogInterceptor.java
用途:每一次链路,线程维度,添加最终的链路ID TRACE_ID。
import org.slf4j.MDC;import org.springframework.lang.Nullable;import org.springframework.util.StringUtils;import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.UUID; /** * @Author: JCccc * @Date: 2022-5-30 10:45 * @Description: */public class LogInterceptor implements HandlerInterceptor { private static final String TRACE_ID = "TRACE_ID"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String tid = UUID.randomUUID().toString().replace("-", ""); //可以考虑让客户端传入链路ID,但需保证一定的复杂度唯一性;如果没使用默认UUID自动生成 if (!StringUtils.isEmpty(request.getHeader("TRACE_ID"))){ tid=request.getHeader("TRACE_ID"); } MDC.put(TRACE_ID, tid); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) { MDC.remove(TRACE_ID); } }
MDC(Mapped Diagnostic Context)诊断上下文映射,是@Slf4j提供的一个支持动态打印日志信息的工具。
WebConfigurerAdapter.java 添加拦截器
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @Author: JCccc * @Date: 2022-5-30 10:47 * @Description: */@Configurationpublic class WebConfigurerAdapter implements WebMvcConfigurer { @Bean public LogInterceptor logInterceptor() { return new LogInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logInterceptor()); //可以具体制定哪些需要拦截,哪些不拦截,其实也可以使用自定义注解更灵活完成// .addPathPatterns("/**")// .excludePathPatterns("/testxx.html"); }}
ps: 其实这个拦截的部分改为使用自定义注解+aop也是很灵活的。
到这时候,其实已经完成,就是这么简单。
我们写个测试接口,看下效果:
@PostMapping("doTest")public String doTest(@RequestParam("name") String name) throws InterruptedException { log.info("入参 name={}",name); testTrace(); log.info("调用结束 name={}",name); return "Hello,"+name;}private void testTrace(){ log.info("这是一行info日志"); log.error("这是一行error日志"); testTrace2();}private void testTrace2(){ log.info("这也是一行info日志");}
效果(OK的):
还没完。
接下来看一个场景, 使用子线程的场景:
故意写一个异步线程,加入这个调用里面:
再次执行看开效果,显然子线程丢失了trackId:
所以我们需要针对子线程使用情形,做调整,思路: 将父线程的trackId传递下去给子线程即可。
①ThreadPoolConfig.java 定义线程池,交给spring管理
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import java.util.concurrent.Executor; /** * @Author: JCccc * @Date: 2022-5-30 11:07 * @Description: */@Configuration@EnableAsyncpublic class ThreadPoolConfig { /** * 声明一个线程池 * * @return 执行器 */ @Bean("MyExecutor") public Executor asyncExecutor() { MyThreadPoolTaskExecutor executor = new MyThreadPoolTaskExecutor(); //核心线程数5:线程池创建时候初始化的线程数 executor.setCorePoolSize(5); //最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程 executor.setMaxPoolSize(5); //缓冲队列500:用来缓冲执行任务的队列 executor.setQueueCapacity(500); //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁 executor.setKeepAliveSeconds(60); //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池 executor.setThreadNamePrefix("asyncJCccc"); executor.initialize(); return executor; }}
② MyThreadPoolTaskExecutor.java 是我们自己写的,重写了一些方法:
import org.slf4j.MDC;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Callable;import java.util.concurrent.Future; /** * @Author: JCccc * @Date: 2022-5-30 11:13 * @Description: */public final class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { public MyThreadPoolTaskExecutor() { super(); } @Override public void execute(Runnable task) { super.execute(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap())); } @Override public Future submit(Callable task) { return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap())); } @Override public Future> submit(Runnable task) { return super.submit(ThreadMdcUtil.wrap(task, MDC.getCopyOfContextMap())); }}
③ThreadMdcUtil.java
import org.slf4j.MDC; import java.util.Map;import java.util.UUID;import java.util.concurrent.Callable; /** * @Author: JCccc * @Date: 2022-5-30 11:14 * @Description: */public final class ThreadMdcUtil { private static final String TRACE_ID = "TRACE_ID"; // 获取唯一性标识 public static String generateTraceId() { return UUID.randomUUID().toString(); } public static void setTraceIdIfAbsent() { if (MDC.get(TRACE_ID) == null) { MDC.put(TRACE_ID, generateTraceId()); } } /** * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程 * * @param callable * @param context * @param * @return */ public static Callable wrap(final Callable callable, final Map context) { return () -> { if (context == null) { MDC.clear(); } else { MDC.setContextMap(context); } setTraceIdIfAbsent(); try { return callable.call(); } finally { MDC.clear(); } }; } /** * 用于父线程向线程池中提交任务时,将自身MDC中的数据复制给子线程 * * @param runnable * @param context * @return */ public static Runnable wrap(final Runnable runnable, final Map context) { return () -> { if (context == null) { MDC.clear(); } else { MDC.setContextMap(context); } setTraceIdIfAbsent(); try { runnable.run(); } finally { MDC.clear(); } }; }}
OK,重启服务,再看看效果:
可以看的,子线程的日志也被串起来了。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
5.《Java开发手册(嵩山版)》最新发布,速速下载!
觉得不错,别忘了随手点赞+转发哦!
-
全球短讯!Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
来源:blog csdn net qq_35387940 article details 125062368前言从文章标题就知道,这篇文章是介...
来源: 全球短讯!Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
代理设计模式还不会?2分钟搞定
【世界报资讯】河南省通许县:“中国酸辣粉之都”正式揭牌
天天热门:微信下重拳:上万个群被封杀 此类行为千万别做
环球微头条丨程序员20年喝近2吨可乐屡患结石 几乎天天喝
联想推ThinkPad Z16 Gen 2笔记本:锐龙7000系列 可选4K+屏
双子姐妹、冰箱很带感 《原子之心》游戏已被破解:俄罗斯自己黑客干的
还敢生吃?日本即将核污水倒入大海 降低水产品氚活度分析精度
世界观天下!老外首次用上徕卡影像!小米13/Pro国际版发布:999欧元起
全球看热讯:9岁女演员获柏林电影节最佳主角:史上最年轻获奖者
今日热门!高三女生因百日誓师热血发言表情被网暴 父亲怒回应:我们的骄傲 请尊重
《流浪地球2》导演郭帆让学生们不要用ChatGPT写作业:老师分辨不出来
读Java性能权威指南(第2版)笔记03_ Java SE API技巧中
美国铁路烂到家:“毒列车公司”再次发生脱轨事故 问题没法解决
【世界速看料】昔日手机巨头换新!诺基亚换全新Logo 刷新认识:网友直呼爷青结
每日热议!残损货币及不宜流通货币常识_不宜流通人民币与残损币区别
AMD RX 7900显卡价格在中国崩盘了!两个月暴跌1400元
世界滚动:不完整的爱情
每日动态!怎样提高空间想象能力 如何提高空间想象能力
全球速看:量化交易基础 - 10 - 拟合
全球速读:Kafka简单介绍和安装
当前快讯:委员蒋胜男建议对8小时工作制加强监督:你一天干几小时?
CentOS7安装nvm和node
局域网实现PC、Pad、Android互联
世界速讯:三大范式
项目中并发修改可能存在的问题
环球快资讯:暴力涡轮风扇RTX 4090再次现身:噪音令人崩溃
全球快讯:国产本田E?众泰江南U2纯电轿车正式上市:5.88万起
今亮点!“中国蛇王”凉了?老牌国货隆力奇人去楼空”上热搜 曾连续11年全国销量第一
今日热闻!Java面向对象进阶第四天(常用API)
Codeforces Global Round 15 CF1552 A~G 题解
每日热文:八方点赞!姆巴佩、莫德里奇等多人点赞C罗社媒动态
世界快报:零下50℃室外玩电脑 显卡都冻傻了:核心温度167万摄氏度
【速看料】能用沐浴露洗头吗?可以是可以 但最好别
天天动态:国内首个类ChatGPT模型:复旦大学团队称MOSS将于三月底开源
观速讯丨国产八核CPU!诺基亚发布G22:小白都能自己修
全球快看:解决IDEA无法识别SpringBoot项目
方敏仪
享年86岁 电影美术大师杨占家去世 手绘媲美CAD制图
世界快资讯:《流浪地球》地下城成真?我国地下基础设施监测技术实现新突破
【环球时快讯】易烊千玺 我们还会在一起吗?_对于易烊千玺 我们还会在一起吗?简单介绍
世界观察:卡罗拉车主试驾完比亚迪唐DM-i之后 丰田信仰瞬间崩塌
80后夫妻攒300万“提前退休” 不生孩子这些钱够了?网友吵翻
一加Buds Pro 2新配色“云峰白”亮相:打磨难度拉满
头条:Linux极简入门系列(二):Linux的目录结构和常用操作
【速看料】Linux vim
当前动态:Vue2 里如何优雅的清除一个定时器
天天通讯!推特进一步削减开支:马斯克挥刀裁掉50名员工
快播:上映10天:《中国乒乓》票房终于破9000万大关
关于数据分析中的绘图分析的学习报告
LWIP学习记录---ARP协议(2)ARP数据包发送过程
go A*寻路记录
59.类的自动转换和强制类型转换
不是“空中楼阁”:努比亚Pad 3D搭载全球最大Leia 3D内容生态
【报资讯】男子车停路边去吃烧烤 回来瞬间崩溃:路边已装上护栏
【独家焦点】作文游西湖300字(精选40篇)
千里托运奔驰GLC被淋满牛粪 女子崩溃:花1900元洗了5遍
【世界速看料】情侣打车3小时后跑单拉黑司机 司机:246元车费没了
世界资讯:微软承认向无法升级的设备推荐Win11:已进行修复
环球即时:压水堆
当前滚动:这些“领导”短信收到没?专门针对iPhone用户诈骗:全国多地预警
环球精选!王一博、梁朝伟《无名》北美院线扩映!豆瓣降至6.7分
当前简讯:大爷怒斥夜市挂日本元素油纸伞:主办方回应令人不解
环球头条:导演新海诚:中国动画电影迟早会超过日本
天天最资讯丨pat乙级链表问题
LWIP学习记录------ARP协议(1)
天天热文:开办以来首位!跨性别演员柏林电影节获奖
微速讯:长城放出王炸?长城水平对置八缸发动机摩托曝光 真猛兽
环球热头条丨可以两天一充的骁龙8 Gen2手机:出现了
每日热讯!马里肯涅巴地区发生武装抢劫 中使馆提醒关注当地安全情况
威马汽车再发内部信:部分员工复工 其余人员无薪休假
【全球热闻】视觉四边等宽!魅族20系列边框仅1.57mm:比iPhone 14 Pro都窄
全球热点!Go编程实战:博客备份
Markdown简明教程
《使命召唤》前景动荡
世界新资讯:上海一高校推出高启强同款猪脚面:师生直呼“舌尖上的《狂飙》”
乌苏啤酒大促:立减64元 折合3元/瓶到手
信息:女子考研期间生娃初试395分 回应外界好奇:多亏家人替自己分担很多
每日焦点!高德、百度地图红绿灯读秒很神奇 接入交管平台?真相并非如此
【天天新要闻】《我们的日子》里,不要忽视这些法律问题
天天资讯:俄州“毒火车”引发环境灾难后 美国又一货运列车脱轨
中兴通
全球热讯:读Java性能权威指南(第2版)笔记02_ Java SE API技巧上
世界动态:你昨晚关注的那个福利姬 可能是假的
世界即时看!国产新能源疯狂内卷!哈弗H6 PHEV官降1.5万 配置全系顶配
【世界报资讯】iPhone 15 Pro Max渲染图出炉:对比14 Pro Max边框更窄、机身更厚
对接水仙后台(支持AndLua+、FA、FA2、AIDE lua、Simple Lua等)
【全球报资讯】Golang基于Mysql分布式锁实现集群主备
世界观热点:薪资4K-5K!公司招聘财务要求做饭被吐槽像保姆
天天百事通!男子长期高血糖导致视网膜病变:不可逆
热头条丨不愧是万元机皇!酷安网友给三星Galaxy S23 Ultra打最高分
当前聚焦:《蚁人3》上映9天中国内地票房破2亿 网友:回到小众也挺好
世界微资讯!如何给公众号投稿赚钱_怎样给公众号投稿赚钱
双亲委派机制
天天微动态丨中国教师队伍建设研究/京师教师教育论丛
当前视讯!即将让核污水倒入大海!日本港口大量有毒海胆聚集 或出现爆发式增长
三星降低QD-OLED面板成本!让电视更具竞争力
世界关注:努比亚Z50新版下周首销:骁龙8 Gen2旗舰焊门员 性价比无敌
最新:python实现客户端和服务端的UDP相互通信
【报资讯】hbuilderx打正式包所需的私钥证书的创建方法