forked from alibaba/jvm-sandbox-repeater
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tracer.java
107 lines (94 loc) · 3.46 KB
/
Tracer.java
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
100
101
102
103
104
105
106
107
package com.alibaba.jvm.sandbox.repeater.plugin.core.trace;
import com.alibaba.jvm.sandbox.repeater.plugin.core.model.ApplicationModel;
import com.alibaba.jvm.sandbox.repeater.plugin.domain.RepeaterConfig;
import com.alibaba.ttl.TransmittableThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link Tracer} 应用内部全局跟踪能力
* <p>
* 非常核心的能力;全局的信息需要利用它来串联
* <p>
* 如果不开启{@link RepeaterConfig#useTtl},只能录制到单线程的子调用信息
* <p>
* 由于上下文信息是从entrance插件开启{@code Tracer.start()},必须在entrance插件进行关闭({@code Tracer.end()}),否则会出现上下文错乱问题
* </p>
*
* @author zhaoyb1990
* @since 1.0.0
*/
public class Tracer {
private final static Logger log = LoggerFactory.getLogger(Tracer.class);
private static ThreadLocal<TraceContext> ttlContext = new TransmittableThreadLocal<TraceContext>();
private static ThreadLocal<TraceContext> normalContext = new ThreadLocal<TraceContext>();
/**
* 开启追踪一次调用,非线程安全
*
* @return 调用上下文
*/
public static TraceContext start() {
return start(null);
}
/**
* 开启追踪一次调用,非线程安全
*
* @param traceId 调用唯一
* @return 调用上下文
*/
public static TraceContext start(String traceId) {
TraceContext context = Tracer.getContextCarrie().get();
if (context != null) {
return context;
}
if (!TraceGenerator.isValid(traceId)) {
traceId = TraceGenerator.generate();
}
context = new TraceContext(traceId);
if(log.isDebugEnabled()){
log.debug("[Tracer] start trace success,traceId={},timestamp={}", context.getTraceId(), context.getTimestamp());
}
Tracer.getContextCarrie().set(context);
return context;
}
/**
* 获取当前上下文
*
* @return TraceContext
*/
public static TraceContext getContext() {
return Tracer.getContextCarrie().get();
}
public static String getExtra(String key) {
return getContext() == null ? null : getContext().getExtra(key);
}
public static String putExtra(String key, String value) {
return getContext() == null ? null : getContext().putExtra(key, value);
}
/**
* 获取当前上下文的追踪ID,未开启追踪情况下返回空
*
* @return 调用追踪ID
*/
public static String getTraceId() {
return Tracer.getContextCarrie().get() == null ? null : Tracer.getContextCarrie().get().getTraceId();
}
/**
* 结束追踪一次调用,清理上下文
*/
public static void end() {
final TraceContext context = getContext();
if (context != null && log.isDebugEnabled()) {
log.debug("[Tracer] stop trace success,type={},traceId={},cost={}ms", context.getInvokeType(), context.getTraceId(), System.currentTimeMillis() - context.getTimestamp());
}
getContextCarrie().remove();
}
/**
* 根据用户是否开启ttl选择合适的载体
*
* @return 上下文threadLocal载体
* @see com.alibaba.jvm.sandbox.repeater.plugin.domain.RepeaterConfig#useTtl
*/
private static ThreadLocal<TraceContext> getContextCarrie() {
return ApplicationModel.instance().getConfig().isUseTtl() ? ttlContext : normalContext;
}
}