11package com .datadog .debugger .codeorigin ;
22
33import static com .datadog .debugger .agent .ConfigurationAcceptor .Source .CODE_ORIGIN ;
4- import static java .util .Arrays .asList ;
54import static java .util .Arrays .stream ;
65
76import com .datadog .debugger .agent .ConfigurationUpdater ;
87import com .datadog .debugger .exception .Fingerprinter ;
98import com .datadog .debugger .probe .CodeOriginProbe ;
109import com .datadog .debugger .probe .Where ;
11- import com .datadog .debugger .util .ClassNameFiltering ;
1210import datadog .trace .api .Config ;
1311import datadog .trace .bootstrap .debugger .CapturedContext ;
1412import datadog .trace .bootstrap .debugger .DebuggerContext ;
1816import datadog .trace .bootstrap .instrumentation .api .AgentTracer ;
1917import datadog .trace .util .AgentTaskScheduler ;
2018import datadog .trace .util .stacktrace .StackWalkerFactory ;
21- import java .io .ByteArrayOutputStream ;
22- import java .io .IOException ;
23- import java .io .InputStream ;
2419import java .util .Collection ;
2520import java .util .Collections ;
2621import java .util .HashMap ;
27- import java .util .HashSet ;
2822import java .util .Map ;
2923import java .util .UUID ;
3024import java .util .concurrent .ConcurrentHashMap ;
3125import java .util .stream .Collectors ;
32- import org .objectweb .asm .ClassReader ;
33- import org .objectweb .asm .tree .ClassNode ;
3426import org .slf4j .Logger ;
3527import org .slf4j .LoggerFactory ;
3628
@@ -43,92 +35,30 @@ public class DefaultCodeOriginRecorder implements CodeOriginRecorder {
4335
4436 private final Map <String , CodeOriginProbe > probes = new ConcurrentHashMap <>();
4537
46- private final AgentTaskScheduler taskScheduler ;
47-
4838 private final int maxUserFrames ;
4939
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-
8240 public DefaultCodeOriginRecorder (Config config , ConfigurationUpdater configurationUpdater ) {
8341 this .configurationUpdater = configurationUpdater ;
8442 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 ;
9343 }
9444
9545 @ Override
9646 public String captureCodeOrigin (String signature ) {
9747 StackTraceElement element = findPlaceInStack ();
9848 String fingerprint = Fingerprinter .fingerprint (element );
99- if (fingerprint == null ) {
100- LOG .debug ("Unable to fingerprint stack trace" );
101- return null ;
102- }
10349 CodeOriginProbe probe ;
10450
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 )) {
13152 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 ())));
13262 }
13363
13464 return probe .getId ();
@@ -142,30 +72,42 @@ public String captureCodeOrigin(
14272 if (isAlreadyInstrumented (name )) {
14373 probe = fingerprints .get (name );
14474 } else {
145- Where where =
146- Where .of (
147- target .getName (),
148- method ,
149- stream (types ).map (Class ::getTypeName ).collect (Collectors .joining (", " , "(" , ")" )));
150-
15175 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 (", " , "(" , ")" ))));
16484 }
16585
16686 return probe .getId ();
16787 }
16888
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+
169111 private StackTraceElement findPlaceInStack () {
170112 return StackWalkerFactory .INSTANCE .walk (
171113 stream ->
@@ -187,7 +129,8 @@ public String installProbe(CodeOriginProbe probe) {
187129 CodeOriginProbe installed = probes .putIfAbsent (probe .getId (), probe );
188130 if (installed == null ) {
189131 if (configurationUpdater != null ) {
190- taskScheduler .execute (() -> configurationUpdater .accept (CODE_ORIGIN , getProbes ()));
132+ AgentTaskScheduler .INSTANCE .execute (
133+ () -> configurationUpdater .accept (CODE_ORIGIN , getProbes ()));
191134 }
192135 return probe .getId ();
193136 }
@@ -201,24 +144,4 @@ public CodeOriginProbe getProbe(String probeId) {
201144 public Collection <CodeOriginProbe > getProbes () {
202145 return probes .values ();
203146 }
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- }
224147}
0 commit comments