解决SkyWalking在gateway中logback链路丢失
type
status
date
slug
summary
tags
category
icon
password
契机场景复现版本skyWalking环境搭建agent目录配置maven依赖项目运行配置logback配置gateway模块请求日志打印代码user模块测试代码访问测试尝试解决分析问题曲线救国验证总结写到最后
契机
吴晟大佬:Why ping me? The plugin is not written by me. I don't know anything about agent running in Spring cloud.
一年半以前,公司就从单体应用逐步迁移到微服务管理。奈何业务绑定太深,一直在两边混合开发。由于迁移到微服务的进程完成了一大半了,之前在单体项目中打的链路追踪就不太好用了。随即想到了SkyWalking,随即发现了一个大坑,那就是在gateway组件中logback日志会丢失TraceId,网上搜了一圈都没有解决问题,我又跑到SkyWalking的issue中搜了一大圈,发现大佬以下回答,还是得自己想办法。
场景复现
版本
- spring-cloud-gateway-dependencies = 3.1.3
- skywalking-oap-server:9.3.0
- skywalking-ui:9.3.0
- apache-skywalking-java-agent:9.0.0
- 假设有gateway+user两个模块
skyWalking环境搭建
agent目录配置
maven依赖
项目运行配置
gateway和user模块都配上一下参数,注意SW_AGENT_NAME要变一下
logback配置
gateway模块请求日志打印代码
就是打印四条信息:请求开始,请求头,请求结束信息,请求结束返回
user模块测试代码
访问测试
通过网关访问testSkywalking测试结果如下
gateway日志
user日志
可以明显看到user模块的tid是正常输出的,可是gateway的日志死活都是N/A
尝试解决
分析问题
首先去去看看哪里输出的这个追踪码,没有找到9.0.0的源码,只找到8.7.0的源码,先搞下来研究研究:https://github.com/apache/skywalking/blob/v8.7.0/。然后定位到logback插件,去寻找tid在哪里输出的,最终找到如下:
apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/log/logback/v1/x/PrintTraceIdInterceptor.java
观察代码无非就是skyWalkingContext.getTraceId()和ContextManager.xx输出的N/A。
Reator模式又有点陌生,无从下手。无意间从另外一篇博客中发现,其实exchange中是有这个tid的
曲线救国
gateway也就拦截器打印点日志,要不然就是exceptionHandler中打印。我要不然直接把这个值传给skywalking-logback插件就完了嘛。拿什么传呢,对的,使用MDC来传,同一个线程都可以传,并且改动最小。直接修改插件中PrintTraceIdInterceptor的源码如下,然后直接打包这个8.7的skywalking-logback插件替换掉原本apm-toolkit-logback-1.x-activation-9.0.0.jar插件(完全可用)
然后再搞一个工具类
然后在gateway拦截器日志打印的地方加上以下代码,但是请求开始和请求结束是两个不同的线程啊,无法使用MDC来传递,架不住打印日志的地方都使用的一个exchange,当然为了保险你可以在每一个gatway模块的log之前加上以下语句
验证
gateway日志
user日志
确实可用,完美解决
总结
- 就是把apm-toolkit-logback-1.x-activation插件改了点代码替换掉
- 然后在gatway模块的日志前面用MDC传了点值进到插件里面
- 相当取巧,因为gatway也没啥日志
- 目前看来没什么问题
写到最后
是在往前走就好
bothsavage.github.io
Last update: 2024-01-21