-
Notifications
You must be signed in to change notification settings - Fork 335
Expand file tree
/
Copy pathThrowableInstanceAdvice.java
More file actions
56 lines (53 loc) · 2.13 KB
/
ThrowableInstanceAdvice.java
File metadata and controls
56 lines (53 loc) · 2.13 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
package datadog.exceptions.instrumentation;
import static datadog.trace.util.AgentThreadFactory.AGENT_THREAD_GROUP;
import datadog.trace.api.Config;
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
import datadog.trace.bootstrap.instrumentation.jfr.InstrumentationBasedProfiling;
import datadog.trace.bootstrap.instrumentation.jfr.exceptions.ExceptionProfiling;
import datadog.trace.bootstrap.instrumentation.jfr.exceptions.ExceptionSampleEvent;
import net.bytebuddy.asm.Advice;
public class ThrowableInstanceAdvice {
@Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit(@Advice.This final Object t) {
if (ExceptionProfiling.Exclusion.isEffective()) {
return;
}
/*
* This instrumentation handler is sensitive to any throwables thrown from its body -
* it will go into infinite loop of trying to handle the new throwable instance and generating
* another instance while doing so.
*
* The solution is to keep a TLS flag and just skip the handler if it was invoked as a result of handling
* a previous throwable instance (on the same thread).
*/
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Throwable.class);
if (callDepth > 0) {
return;
}
try {
/*
* We may get into a situation when this is called before exception sampling is active.
*/
if (!InstrumentationBasedProfiling.isJFRReady()) {
return;
}
/*
* Exclude internal agent threads from exception profiling.
*/
if (Config.get().isProfilingExcludeAgentThreads()
&& AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) {
return;
}
/*
* JFR will assign the stacktrace depending on the place where the event is committed.
* Therefor we need to commit the event here, right in the 'Exception' constructor
*/
final ExceptionSampleEvent event = ExceptionProfiling.getInstance().process((Throwable) t);
if (event != null && event.shouldCommit()) {
event.commit();
}
} finally {
CallDepthThreadLocalMap.reset(Throwable.class);
}
}
}