-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
99 lines (95 loc) · 5.52 KB
/
atom.xml
File metadata and controls
99 lines (95 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://sruby.github.io</id>
<title>Coder</title>
<updated>2023-02-21T11:35:07.166Z</updated>
<generator>https://github.com/jpmonette/feed</generator>
<link rel="alternate" href="https://sruby.github.io"/>
<link rel="self" href="https://sruby.github.io/atom.xml"/>
<subtitle>Try again,fail again,fail better</subtitle>
<logo>https://sruby.github.io/images/avatar.png</logo>
<icon>https://sruby.github.io/favicon.ico</icon>
<rights>All rights reserved 2023, Coder</rights>
<entry>
<title type="html"><![CDATA[Spring Cloud Gateway日志无法记录SkyWalking的TID]]></title>
<id>https://sruby.github.io/post/spring-cloud-gateway-ri-zhi-wu-fa-ji-lu-skywalking-de-tid/</id>
<link href="https://sruby.github.io/post/spring-cloud-gateway-ri-zhi-wu-fa-ji-lu-skywalking-de-tid/">
</link>
<updated>2023-02-20T05:58:10.000Z</updated>
<content type="html"><![CDATA[<h1 id="问题">问题</h1>
<p>在继承了SkyWalking日志工具的情况下,Spring Cloud Gateway的日志中TID为N/A,其他服务的日志均能够正常记录TID。<br>
SkyWalking UI可以正常记录包括Spring Cloud Gateway在内的各个服务的TID。</p>
<h1 id="原因">原因</h1>
<p>SkyWalking agent plugin只保证将TID传递给OAP,而不保证一定把TID输出到日志。<br>
如果需要支持,则需要使用方增加此特性。</p>
<h1 id="agent-plugin源码分析">Agent plugin源码分析</h1>
<p>Spring Cloud Gateway对应的plugin源码如下:<br>
Agent plugin:spring-webflux-5.x-plugin<br>
类:DispatcherHandlerHandleMethodInterceptor</p>
<pre><code class="language-java">@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
EnhancedInstance instance = getInstance(allArguments[0]);
ServerWebExchange exchange = (ServerWebExchange) allArguments[0];
ContextCarrier carrier = new ContextCarrier();
CarrierItem next = carrier.items();
HttpHeaders headers = exchange.getRequest().getHeaders();
while (next.hasNext()) {
next = next.next();
List<String> header = headers.get(next.getHeadKey());
if (header != null && header.size() > 0) {
next.setHeadValue(header.get(0));
}
}
AbstractSpan span = ContextManager.createEntrySpan(exchange.getRequest().getURI().getPath(), carrier);
if (instance != null && instance.getSkyWalkingDynamicField() != null) {
ContextManager.continued((ContextSnapshot) instance.getSkyWalkingDynamicField());
}
span.setComponent(ComponentsDefine.SPRING_WEBFLUX);
SpanLayer.asHttp(span);
Tags.URL.set(span, exchange.getRequest().getURI().toString());
HTTP.METHOD.set(span, exchange.getRequest().getMethodValue());
instance.setSkyWalkingDynamicField(ContextManager.capture());
span.prepareForAsync();
ContextManager.stopSpan(span);
//SKYWALING_SPAN保存到exchange
exchange.getAttributes().put("SKYWALING_SPAN", span);
}
</code></pre>
<h1 id="solution">Solution</h1>
<h1 id="solution-1">Solution 1</h1>
<ul>
<li>只需要在filter中记录TID,便于排查问题,而不保存到日志框架的MDC种。</li>
<li>根据源码分析部分可以得知plugin会把SKYWALING_SPAN保存到exchange<br>
中,所以我们可以在exchange中获取SKYWALING_SPAN。</li>
<li>从exchange中获取到Span对象后,需要通过反射的方式一层层获取到traceid,因为无法直接依赖包含这些类的agent-core包,会跟agent本身发生冲突。</li>
</ul>
<pre><code class="language-java">String traceId = "N/A";
Object skywalingSpanObject = exchange.getAttributes().get("SKYWALING_SPAN");
if (ObjectUtils.isNotEmpty(skywalingSpanObject)) {
try {
Field owner = FieldUtils.getField(skywalingSpanObject.getClass(), "owner", true);
Object tracingContext = owner.get(skywalingSpanObject);
Field segmentField = FieldUtils.getField(tracingContext.getClass(), "segment", true);
Object segment = segmentField.get(tracingContext);
Field relatedGlobalTraceIdField = FieldUtils.getField(segment.getClass(), "relatedGlobalTraceId", true);
Object relatedGlobalTraceId = relatedGlobalTraceIdField.get(segment);
String traceIdObject = relatedGlobalTraceId.toString();
traceId = Stringutils.substrΩingBetween(traceIdObject, "=", ")");
} catch (Exception e) {
log.warn("get TID failed", e);
}
</code></pre>
<h1 id="reference">Reference</h1>
<blockquote>
<p><a href="https://github.com/apache/skywalking/discussions/9232">SpringCloudGateway3.1.3, With apm-log4j2-2.x:8.10.0, does not display the real traceId, always display 'TID: N/A' · Discussion #9232 · apache/skywalking (github.com)</a><br>
<a href="https://github.com/apache/skywalking/issues/5268">My log can't get traceId when I use Spring Cloud Gateway in my project ,all traceId in my log is "[traceId:TID:N/A]" · Issue #5268 · apache/skywalking (github.com)</a><br>
<a href="https://www.jianshu.com/p/40727a0b9604">SpringCloudGateway使用Skywalking时日志打印traceId - 简书 (jianshu.com)</a></p>
</blockquote>
<p>#SkyWalking<br>
#SpringCloudGateway<br>
#MDC<br>
#TracdID</p>
]]></content>
</entry>
</feed>