File tree Expand file tree Collapse file tree 6 files changed +111
-1
lines changed
dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src
main/java/datadog/trace/instrumentation/java/lang
test/groovy/datadog/trace/instrumentation/java/lang
internal-api/src/main/java/datadog/trace/api
main/java/datadog/telemetry
test/groovy/datadog/telemetry Expand file tree Collapse file tree 6 files changed +111
-1
lines changed Original file line number Diff line number Diff line change 1+ package datadog .trace .instrumentation .java .lang ;
2+
3+ import datadog .trace .api .Config ;
4+ import net .bytebuddy .asm .Advice ;
5+
6+ class ProcessBuilderSessionIdAdvice {
7+ @ Advice .OnMethodEnter (suppress = Throwable .class )
8+ public static void beforeStart (@ Advice .This final ProcessBuilder self ) {
9+ Config config = Config .get ();
10+ String rootSessionId = config .getRootSessionId ();
11+ if (rootSessionId != null ) {
12+ self .environment ().put ("_DD_ROOT_JAVA_SESSION_ID" , rootSessionId );
13+ }
14+ }
15+ }
Original file line number Diff line number Diff line change 1+ package datadog .trace .instrumentation .java .lang ;
2+
3+ import static datadog .trace .agent .tooling .bytebuddy .matcher .NameMatchers .named ;
4+ import static net .bytebuddy .matcher .ElementMatchers .takesNoArguments ;
5+
6+ import com .google .auto .service .AutoService ;
7+ import datadog .trace .agent .tooling .Instrumenter ;
8+ import datadog .trace .agent .tooling .InstrumenterModule ;
9+ import datadog .trace .api .Platform ;
10+
11+ @ AutoService (InstrumenterModule .class )
12+ public class ProcessBuilderSessionIdInstrumentation extends InstrumenterModule .Tracing
13+ implements Instrumenter .ForSingleType , Instrumenter .HasMethodAdvice {
14+
15+ public ProcessBuilderSessionIdInstrumentation () {
16+ super ("process-session-id" );
17+ }
18+
19+ @ Override
20+ protected boolean defaultEnabled () {
21+ return super .defaultEnabled () && !Platform .isNativeImageBuilder ();
22+ }
23+
24+ @ Override
25+ public String instrumentedType () {
26+ return "java.lang.ProcessBuilder" ;
27+ }
28+
29+ @ Override
30+ public void methodAdvice (MethodTransformer transformer ) {
31+ transformer .applyAdvice (
32+ named ("start" ).and (takesNoArguments ()),
33+ packageName + ".ProcessBuilderSessionIdAdvice" );
34+ }
35+ }
Original file line number Diff line number Diff line change 1+ package datadog.trace.instrumentation.java.lang
2+
3+ import datadog.trace.agent.test.AgentTestRunner
4+ import datadog.trace.api.Config
5+
6+ class ProcessBuilderSessionIdSpecification extends AgentTestRunner {
7+
8+ def " ProcessBuilder injects root session ID into child environment" () {
9+ setup :
10+ def command = [' sh' , ' -c' , ' echo $_DD_ROOT_JAVA_SESSION_ID' ]
11+ def pb = new ProcessBuilder (command)
12+
13+ when :
14+ def process = pb. start()
15+ def output = process. inputStream. text. trim()
16+ process. waitFor()
17+
18+ then :
19+ output == Config . get(). getRootSessionId()
20+ }
21+
22+ def " child process inherits root session ID not runtime ID" () {
23+ setup :
24+ def command = [' sh' , ' -c' , ' echo $_DD_ROOT_JAVA_SESSION_ID' ]
25+ def pb = new ProcessBuilder (command)
26+
27+ when :
28+ def process = pb. start()
29+ def output = process. inputStream. text. trim()
30+ process. waitFor()
31+
32+ then :
33+ output == Config . get(). getRootSessionId()
34+ Config . get(). getRootSessionId() == Config . get(). getRuntimeId()
35+ }
36+ }
Original file line number Diff line number Diff line change 687687import static datadog .trace .util .ConfigStrings .propertyNameToEnvironmentVariableName ;
688688import static datadog .trace .util .json .JsonPathParser .parseJsonPaths ;
689689
690+ import datadog .environment .EnvironmentVariables ;
690691import datadog .environment .JavaVirtualMachine ;
691692import datadog .environment .OperatingSystem ;
692693import datadog .environment .SystemProperties ;
@@ -792,6 +793,12 @@ public class Config {
792793 */
793794 static class RuntimeIdHolder {
794795 static final String runtimeId = RandomUtils .randomUUID ().toString ();
796+ static final String rootSessionId = initRootSessionId ();
797+
798+ private static String initRootSessionId () {
799+ String inherited = EnvironmentVariables .get ("_DD_ROOT_JAVA_SESSION_ID" );
800+ return inherited != null ? inherited : runtimeId ;
801+ }
795802 }
796803
797804 static class HostNameHolder {
@@ -3123,6 +3130,10 @@ public String getRuntimeId() {
31233130 return runtimeIdEnabled ? RuntimeIdHolder .runtimeId : "" ;
31243131 }
31253132
3133+ public String getRootSessionId () {
3134+ return RuntimeIdHolder .rootSessionId ;
3135+ }
3136+
31263137 public Long getProcessId () {
31273138 return PidHelper .getPidAsLong ();
31283139 }
Original file line number Diff line number Diff line change @@ -80,6 +80,16 @@ public Request.Builder httpRequest() {
8080 builder .addHeader ("DD-Telemetry-Debug-Enabled" , "true" );
8181 }
8282
83+ Config config = Config .get ();
84+ String sessionId = config .getRuntimeId ();
85+ if (sessionId != null && !sessionId .isEmpty ()) {
86+ builder .addHeader ("DD-Session-ID" , sessionId );
87+ }
88+ String rootSessionId = config .getRootSessionId ();
89+ if (rootSessionId != null && !rootSessionId .equals (sessionId )) {
90+ builder .addHeader ("DD-Root-Session-ID" , rootSessionId );
91+ }
92+
8393 return builder ;
8494 }
8595
Original file line number Diff line number Diff line change @@ -84,7 +84,8 @@ class TestTelemetryRouter extends TelemetryRouter {
8484 ' DD-Client-Library-Language' ,
8585 ' DD-Client-Library-Version' ,
8686 ' DD-Telemetry-API-Version' ,
87- ' DD-Telemetry-Request-Type'
87+ ' DD-Telemetry-Request-Type' ,
88+ ' DD-Session-ID'
8889 ])
8990 assert this . request. header(' Content-Type' ) == ' application/json; charset=utf-8'
9091 assert this . request. header(' Content-Length' ). toInteger() > 0
@@ -94,6 +95,8 @@ class TestTelemetryRouter extends TelemetryRouter {
9495 assert this . request. header(' DD-Telemetry-Request-Type' ) == requestType. toString()
9596 def entityId = this . request. header(' Datadog-Entity-ID' )
9697 assert entityId == null || entityId. startsWith(" in-" ) || entityId. startsWith(" cin-" )
98+ def sessionId = this . request. header(' DD-Session-ID' )
99+ assert sessionId =~ / [\d a-f]{8}-([\d a-f]{4}-){3}[\d a-f]{12}/
97100 return this
98101 }
99102
You can’t perform that action at this time.
0 commit comments