1
1
package com .datadog .debugger .codeorigin ;
2
2
3
3
import static com .datadog .debugger .agent .ConfigurationAcceptor .Source .CODE_ORIGIN ;
4
- import static java .util .Arrays .asList ;
5
4
import static java .util .Arrays .stream ;
6
5
7
6
import com .datadog .debugger .agent .ConfigurationUpdater ;
8
7
import com .datadog .debugger .exception .Fingerprinter ;
9
8
import com .datadog .debugger .probe .CodeOriginProbe ;
10
9
import com .datadog .debugger .probe .Where ;
11
- import com .datadog .debugger .util .ClassNameFiltering ;
12
10
import datadog .trace .api .Config ;
13
11
import datadog .trace .bootstrap .debugger .CapturedContext ;
14
12
import datadog .trace .bootstrap .debugger .DebuggerContext ;
18
16
import datadog .trace .bootstrap .instrumentation .api .AgentTracer ;
19
17
import datadog .trace .util .AgentTaskScheduler ;
20
18
import datadog .trace .util .stacktrace .StackWalkerFactory ;
21
- import java .io .ByteArrayOutputStream ;
22
- import java .io .IOException ;
23
- import java .io .InputStream ;
24
19
import java .util .Collection ;
25
20
import java .util .Collections ;
26
21
import java .util .HashMap ;
27
- import java .util .HashSet ;
28
22
import java .util .Map ;
29
23
import java .util .UUID ;
30
24
import java .util .concurrent .ConcurrentHashMap ;
31
25
import java .util .stream .Collectors ;
32
- import org .objectweb .asm .ClassReader ;
33
- import org .objectweb .asm .tree .ClassNode ;
34
26
import org .slf4j .Logger ;
35
27
import org .slf4j .LoggerFactory ;
36
28
@@ -43,92 +35,30 @@ public class DefaultCodeOriginRecorder implements CodeOriginRecorder {
43
35
44
36
private final Map <String , CodeOriginProbe > probes = new ConcurrentHashMap <>();
45
37
46
- private final AgentTaskScheduler taskScheduler ;
47
-
48
38
private final int maxUserFrames ;
49
39
50
- // this really should only be used for testing
51
- public DefaultCodeOriginRecorder () {
52
- maxUserFrames = 8 ;
53
- configurationUpdater = null ;
54
- DebuggerContext .initClassNameFilter (
55
- new ClassNameFiltering (
56
- new HashSet <>(
57
- asList (
58
- "sun" ,
59
- "org.junit" ,
60
- "java." ,
61
- "org.gradle" ,
62
- "com.sun" ,
63
- "worker.org.gradle" ,
64
- "datadog" ,
65
- "com.datadog.debugger.probe" ,
66
- "com.datadog.debugger.codeorigin" ))));
67
- new ClassNameFiltering (
68
- new HashSet <>(
69
- asList (
70
- "sun" ,
71
- "org.junit" ,
72
- "java." ,
73
- "org.gradle" ,
74
- "com.sun" ,
75
- "worker.org.gradle" ,
76
- "datadog" ,
77
- "com.datadog.debugger.probe" ,
78
- "com.datadog.debugger.codeorigin" )));
79
- taskScheduler = AgentTaskScheduler .INSTANCE ;
80
- }
81
-
82
40
public DefaultCodeOriginRecorder (Config config , ConfigurationUpdater configurationUpdater ) {
83
41
this .configurationUpdater = configurationUpdater ;
84
42
maxUserFrames = config .getDebuggerCodeOriginMaxUserFrames ();
85
- taskScheduler = AgentTaskScheduler .INSTANCE ;
86
- }
87
-
88
- public DefaultCodeOriginRecorder (
89
- Config config , ConfigurationUpdater configurationUpdater , AgentTaskScheduler taskScheduler ) {
90
- this .configurationUpdater = configurationUpdater ;
91
- maxUserFrames = config .getDebuggerCodeOriginMaxUserFrames ();
92
- this .taskScheduler = taskScheduler ;
93
43
}
94
44
95
45
@ Override
96
46
public String captureCodeOrigin (String signature ) {
97
47
StackTraceElement element = findPlaceInStack ();
98
48
String fingerprint = Fingerprinter .fingerprint (element );
99
- if (fingerprint == null ) {
100
- LOG .debug ("Unable to fingerprint stack trace" );
101
- return null ;
102
- }
103
49
CodeOriginProbe probe ;
104
50
105
- AgentSpan span = AgentTracer .activeSpan ();
106
- if (!isAlreadyInstrumented (fingerprint )) {
107
- Where where =
108
- Where .of (
109
- element .getClassName (),
110
- element .getMethodName (),
111
- signature ,
112
- String .valueOf (element .getLineNumber ()));
113
-
114
- probe =
115
- new CodeOriginProbe (
116
- new ProbeId (UUID .randomUUID ().toString (), 0 ),
117
- where .getSignature (),
118
- where ,
119
- maxUserFrames );
120
- addFingerprint (fingerprint , probe );
121
-
122
- installProbe (probe );
123
- if (span != null ) {
124
- // committing here manually so that first run probe encounters decorate the span until the
125
- // instrumentation gets installed
126
- probe .commit (
127
- CapturedContext .EMPTY_CONTEXT , CapturedContext .EMPTY_CONTEXT , Collections .emptyList ());
128
- }
129
-
130
- } else {
51
+ if (isAlreadyInstrumented (fingerprint )) {
131
52
probe = fingerprints .get (fingerprint );
53
+ } else {
54
+ probe =
55
+ createProbe (
56
+ signature ,
57
+ Where .of (
58
+ element .getClassName (),
59
+ element .getMethodName (),
60
+ signature ,
61
+ String .valueOf (element .getLineNumber ())));
132
62
}
133
63
134
64
return probe .getId ();
@@ -142,30 +72,42 @@ public String captureCodeOrigin(
142
72
if (isAlreadyInstrumented (name )) {
143
73
probe = fingerprints .get (name );
144
74
} else {
145
- Where where =
146
- Where .of (
147
- target .getName (),
148
- method ,
149
- stream (types ).map (Class ::getTypeName ).collect (Collectors .joining (", " , "(" , ")" )));
150
-
151
75
probe =
152
- new CodeOriginProbe (
153
- new ProbeId (UUID .randomUUID ().toString (), 0 ),
154
- where .getSignature (),
155
- where ,
156
- maxUserFrames );
157
- addFingerprint (name , probe );
158
-
159
- installProbe (probe );
160
- // committing here manually so that first run probe encounters decorate the span until the
161
- // instrumentation gets installed
162
- probe .commit (
163
- CapturedContext .EMPTY_CONTEXT , CapturedContext .EMPTY_CONTEXT , Collections .emptyList ());
76
+ createProbe (
77
+ name ,
78
+ Where .of (
79
+ target .getName (),
80
+ method ,
81
+ stream (types )
82
+ .map (Class ::getTypeName )
83
+ .collect (Collectors .joining (", " , "(" , ")" ))));
164
84
}
165
85
166
86
return probe .getId ();
167
87
}
168
88
89
+ private CodeOriginProbe createProbe (String fingerPrint , Where where ) {
90
+ CodeOriginProbe probe ;
91
+ AgentSpan span = AgentTracer .activeSpan ();
92
+
93
+ probe =
94
+ new CodeOriginProbe (
95
+ new ProbeId (UUID .randomUUID ().toString (), 0 ),
96
+ where .getSignature (),
97
+ where ,
98
+ maxUserFrames );
99
+ addFingerprint (fingerPrint , probe );
100
+
101
+ installProbe (probe );
102
+ // committing here manually so that first run probe encounters decorate the span until the
103
+ // instrumentation gets installed
104
+ if (span != null ) {
105
+ probe .commit (
106
+ CapturedContext .EMPTY_CONTEXT , CapturedContext .EMPTY_CONTEXT , Collections .emptyList ());
107
+ }
108
+ return probe ;
109
+ }
110
+
169
111
private StackTraceElement findPlaceInStack () {
170
112
return StackWalkerFactory .INSTANCE .walk (
171
113
stream ->
@@ -187,7 +129,8 @@ public String installProbe(CodeOriginProbe probe) {
187
129
CodeOriginProbe installed = probes .putIfAbsent (probe .getId (), probe );
188
130
if (installed == null ) {
189
131
if (configurationUpdater != null ) {
190
- taskScheduler .execute (() -> configurationUpdater .accept (CODE_ORIGIN , getProbes ()));
132
+ AgentTaskScheduler .INSTANCE .execute (
133
+ () -> configurationUpdater .accept (CODE_ORIGIN , getProbes ()));
191
134
}
192
135
return probe .getId ();
193
136
}
@@ -201,24 +144,4 @@ public CodeOriginProbe getProbe(String probeId) {
201
144
public Collection <CodeOriginProbe > getProbes () {
202
145
return probes .values ();
203
146
}
204
-
205
- private ClassNode parseClassFile (String className ) {
206
- byte [] bytes = new byte [8192 ];
207
- try (InputStream inputStream =
208
- getClass ()
209
- .getClassLoader ()
210
- .getResourceAsStream (String .format ("%s.class" , className .replace ('.' , '/' )))) {
211
- ByteArrayOutputStream bao = new ByteArrayOutputStream ();
212
- int bytesRead ;
213
- while ((bytesRead = inputStream .read (bytes )) != -1 ) {
214
- bao .write (bytes , 0 , bytesRead );
215
- }
216
- ClassNode classNode = new ClassNode ();
217
- new ClassReader (bao .toByteArray ()).accept (classNode , ClassReader .SKIP_FRAMES );
218
- return classNode ;
219
- } catch (IOException e ) {
220
- LOG .error ("Can't read class file information for {}" , className );
221
- return null ;
222
- }
223
- }
224
147
}
0 commit comments