Skip to content

Commit a926b1c

Browse files
Mute tracing for subprocesses executed by bootstrap telemetry logic. (#9005)
1 parent 5d247c5 commit a926b1c

File tree

17 files changed

+233
-139
lines changed

17 files changed

+233
-139
lines changed

dd-java-agent/build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def sharedShadowJar = tasks.register('sharedShadowJar', ShadowJar) {
174174
// Put the jar in a different directory so we don't overwrite the normal shadow jar and
175175
// break caching, and also to not interfere with CI scripts that copy everything in the
176176
// libs directory
177-
it.destinationDirectory.set(file("${project.buildDir}/shared-lib"))
177+
it.destinationDirectory.set(project.layout.buildDirectory.dir("shared-lib"))
178178
// Add a classifier so we don't confuse the jar file with the normal shadow jar
179179
archiveClassifier = 'shared'
180180
it.dependencies {
@@ -192,7 +192,7 @@ includeShadowJar(sharedShadowJar, 'shared')
192192
// place the tracer in its own shadow jar separate to instrumentation
193193
def traceShadowJar = tasks.register('traceShadowJar', ShadowJar) {
194194
configurations = [project.configurations.traceShadowInclude]
195-
it.destinationDirectory.set(file("${project.buildDir}/trace-lib"))
195+
it.destinationDirectory.set(project.layout.buildDirectory.dir("trace-lib"))
196196
archiveClassifier = 'trace'
197197
it.dependencies deps.excludeShared
198198
}
@@ -265,6 +265,9 @@ dependencies {
265265
testImplementation project(':dd-trace-core')
266266
testImplementation project(':utils:test-utils')
267267

268+
testImplementation group: 'com.squareup.okhttp3', name: 'mockwebserver', version: libs.versions.okhttp.legacy.get()
269+
testImplementation project(':utils:test-agent-utils:decoder')
270+
268271
testImplementation libs.bundles.test.logging
269272
testImplementation libs.guava
270273
testImplementation libs.okhttp

dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datadog.json.JsonWriter;
44
import de.thetaphi.forbiddenapis.SuppressForbidden;
5+
import java.io.Closeable;
56
import java.io.OutputStream;
67
import java.util.ArrayList;
78
import java.util.List;
@@ -211,7 +212,8 @@ public ForwarderJsonSenderThread(String forwarderPath, byte[] payload) {
211212
public void run() {
212213
ProcessBuilder builder = new ProcessBuilder(forwarderPath, "library_entrypoint");
213214

214-
try {
215+
// Run forwarder and mute tracing for subprocesses executed in by dd-java-agent.
216+
try (final Closeable ignored = muteTracing()) {
215217
Process process = builder.start();
216218
try (OutputStream out = process.getOutputStream()) {
217219
out.write(payload);
@@ -221,5 +223,19 @@ public void run() {
221223
System.err.println("Failed to send telemetry: " + e.getMessage());
222224
}
223225
}
226+
227+
@SuppressForbidden
228+
private Closeable muteTracing() {
229+
try {
230+
Class<?> agentTracerClass =
231+
Class.forName("datadog.trace.bootstrap.instrumentation.api.AgentTracer");
232+
Object tracerAPI = agentTracerClass.getMethod("get").invoke(null);
233+
Object scope = tracerAPI.getClass().getMethod("muteTracing").invoke(tracerAPI);
234+
return (Closeable) scope;
235+
} catch (Throwable e) {
236+
// Ignore all exceptions and fallback to No-Op Closable.
237+
return () -> {};
238+
}
239+
}
224240
}
225241
}

dd-java-agent/src/test/groovy/datadog/trace/agent/AgentLoadedIntoBootstrapTest.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class AgentLoadedIntoBootstrapTest extends Specification {
1313
def "Agent loads in when separate jvm is launched"() {
1414
expect:
1515
IntegrationTestUtils.runOnSeparateJvm(AgentLoadedChecker.getName()
16-
, "" as String[]
17-
, "" as String[]
16+
, []
17+
, []
1818
, [:]
1919
, true) == 0
2020
}
@@ -28,8 +28,8 @@ class AgentLoadedIntoBootstrapTest extends Specification {
2828

2929
expect:
3030
IntegrationTestUtils.runOnSeparateJvm(mainClassName
31-
, "" as String[]
32-
, "" as String[]
31+
, []
32+
, []
3333
, [:]
3434
, pathToJar as String
3535
, true) == 0

dd-java-agent/src/test/groovy/datadog/trace/agent/CustomLogManagerTest.groovy

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class CustomLogManagerTest extends Specification {
2020
"-Ddd.jmxfetch.refresh-beans-period=1",
2121
"-Ddd.profiling.enabled=true",
2222
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL"
23-
] as String[]
24-
, "" as String[]
23+
]
24+
, []
2525
, [:]
2626
, true) == 0
2727
}
@@ -36,8 +36,8 @@ class CustomLogManagerTest extends Specification {
3636
"-Ddd.profiling.enabled=true",
3737
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
3838
"-Djava.util.logging.manager=jvmbootstraptest.CustomLogManager"
39-
] as String[]
40-
, "" as String[]
39+
]
40+
, []
4141
, [:]
4242
, true) == 0
4343
}
@@ -52,8 +52,8 @@ class CustomLogManagerTest extends Specification {
5252
"-Ddd.profiling.enabled=true",
5353
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
5454
"-Djava.util.logging.manager=jvmbootstraptest.MissingLogManager"
55-
] as String[]
56-
, "" as String[]
55+
]
56+
, []
5757
, [:]
5858
, true) == 0
5959
}
@@ -68,8 +68,8 @@ class CustomLogManagerTest extends Specification {
6868
"-Ddd.profiling.enabled=true",
6969
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
7070
"-Ddd.app.customlogmanager=true"
71-
] as String[]
72-
, "" as String[]
71+
]
72+
, []
7373
, [:]
7474
, true) == 0
7575
}
@@ -84,8 +84,8 @@ class CustomLogManagerTest extends Specification {
8484
"-Ddd.profiling.enabled=true",
8585
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
8686
"-Ddd.app.customjmxbuilder=false"
87-
] as String[]
88-
, "" as String[]
87+
]
88+
, []
8989
, ["JBOSS_HOME": "/"]
9090
, true) == 0
9191
}
@@ -102,8 +102,8 @@ class CustomLogManagerTest extends Specification {
102102
"-Ddd.app.customlogmanager=false",
103103
"-Ddd.app.customjmxbuilder=false",
104104
"-Djava.util.logging.manager=jvmbootstraptest.CustomLogManager"
105-
] as String[]
106-
, "" as String[]
105+
]
106+
, []
107107
, ["JBOSS_HOME": "/"]
108108
, true) == 0
109109
}

dd-java-agent/src/test/groovy/datadog/trace/agent/CustomMBeanServerBuilderTest.groovy

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class CustomMBeanServerBuilderTest extends Specification {
2121
"-Ddd.profiling.enabled=true",
2222
"-Ddd.instrumentation.telemetry.enabled=false",
2323
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL"
24-
] as String[]
25-
, "" as String[]
24+
]
25+
, []
2626
, [:]
2727
, true) == 0
2828
}
@@ -38,8 +38,8 @@ class CustomMBeanServerBuilderTest extends Specification {
3838
"-Ddd.instrumentation.telemetry.enabled=false",
3939
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
4040
"-Djavax.management.builder.initial=jvmbootstraptest.CustomMBeanServerBuilder"
41-
] as String[]
42-
, "" as String[]
41+
]
42+
, []
4343
, [:]
4444
, true) == 0
4545
}
@@ -55,8 +55,8 @@ class CustomMBeanServerBuilderTest extends Specification {
5555
"-Ddd.instrumentation.telemetry.enabled=false",
5656
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
5757
"-Djavax.management.builder.initial=jvmbootstraptest.MissingMBeanServerBuilder"
58-
] as String[]
59-
, "" as String[]
58+
]
59+
, []
6060
, [:]
6161
, true) == 0
6262
}
@@ -72,8 +72,8 @@ class CustomMBeanServerBuilderTest extends Specification {
7272
"-Ddd.instrumentation.telemetry.enabled=false",
7373
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
7474
"-Ddd.app.customjmxbuilder=true"
75-
] as String[]
76-
, "" as String[]
75+
]
76+
, []
7777
, [:]
7878
, true) == 0
7979
}
@@ -90,8 +90,8 @@ class CustomMBeanServerBuilderTest extends Specification {
9090
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL",
9191
"-Ddd.app.customjmxbuilder=false",
9292
"-Djavax.management.builder.initial=jvmbootstraptest.CustomMBeanServerBuilder"
93-
] as String[]
94-
, "" as String[]
93+
]
94+
, []
9595
, [:]
9696
, true) == 0
9797
}

dd-java-agent/src/test/groovy/datadog/trace/agent/InitializationTelemetryTest.groovy

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package datadog.trace.agent
22

3-
import spock.lang.Specification
4-
import spock.lang.Timeout
5-
import spock.lang.IgnoreIf
3+
import datadog.test.SimpleAgentMock
64
import datadog.trace.api.Platform
7-
85
import jvmbootstraptest.InitializationTelemetryCheck
6+
import spock.lang.IgnoreIf
7+
import spock.lang.Specification
8+
import spock.lang.Timeout
99

1010
@Timeout(30)
1111
@IgnoreIf(reason = "SecurityManager is permanently disabled as of JDK 24", value = {
@@ -26,19 +26,39 @@ class InitializationTelemetryTest extends Specification {
2626

2727
def "normal start-up"() {
2828
when:
29-
def result = InitializationTelemetryCheck.runTestJvm(null, false, "sleep")
29+
def result = InitializationTelemetryCheck.runTestJvm(null)
30+
31+
then:
32+
result.exitCode == 0
33+
result.telemetryJson.contains('library_entrypoint.complete')
34+
}
35+
36+
def "test initial telemetry forwarder trace muted"() {
37+
when:
38+
def agent = new SimpleAgentMock().start()
39+
def result = InitializationTelemetryCheck.runTestJvm(null, agent.port)
3040

3141
then:
3242
result.exitCode == 0
3343
result.telemetryJson.contains('library_entrypoint.complete')
44+
45+
// Check that we have only one span related to sub-process execution,
46+
// and it is not initial telemetry forwarder.
47+
agent.spans.size() == 1
48+
def span = agent.spans.get(0)
49+
span.name == 'command_execution'
50+
span.resource == 'echo'
51+
52+
cleanup:
53+
agent.close()
3454
}
3555

3656
def "incomplete agent start-up"() {
3757
// In this case, the SecurityManager blocks a custom permission that is checked by bytebuddy causing
3858
// agent initialization to fail. However, we should catch the exception allowing the application
3959
// to run normally.
4060
when:
41-
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockByteBuddy, false, "sleep")
61+
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockByteBuddy)
4262

4363
then:
4464
result.exitCode == 0
@@ -50,7 +70,7 @@ class InitializationTelemetryTest extends Specification {
5070
// In this case, the SecurityManager blocks access to the forwarder environment variable,
5171
// so the tracer is unable to report initialization telemetry
5272
when:
53-
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockForwarderEnvVar, true)
73+
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockForwarderEnvVar)
5474

5575
then:
5676
result.exitCode == 0
@@ -62,7 +82,7 @@ class InitializationTelemetryTest extends Specification {
6282
// In this case, the SecurityManager blocks access to process execution, so the tracer is
6383
// unable to invoke the forwarder executable
6484
when:
65-
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockForwarderExecution, true)
85+
def result = InitializationTelemetryCheck.runTestJvm(InitializationTelemetryCheck.BlockForwarderExecution)
6686

6787
then:
6888
result.exitCode == 0

dd-java-agent/src/test/groovy/datadog/trace/agent/InstrumenterUnloadTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class InstrumenterUnloadTest extends Specification {
2121
, [
2222
"-verbose:class",
2323
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=$DEFAULT_LOG_LEVEL"
24-
] as String[]
25-
, "" as String[]
24+
]
25+
, []
2626
, ["DD_API_KEY": API_KEY]
2727
, new PrintStream(testOutput))
2828

dd-java-agent/src/test/groovy/datadog/trace/agent/JMXFetchTest.groovy

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ class JMXFetchTest extends Specification {
2828
"-Ddd.jmxfetch.start-delay=0",
2929
"-Ddd.jmxfetch.statsd.port=${jmxStatsSocket.localPort}",
3030
"-Ddd.writer.type=DDAgentWriter"
31-
] as String[]
32-
, ["30000"] as String[]
31+
]
32+
, ["30000"]
3333
, [:]
3434
, System.getProperty("java.class.path"))
3535

@@ -64,8 +64,8 @@ class JMXFetchTest extends Specification {
6464
"-Ddd.jmxfetch.start-delay=0",
6565
"-Ddd.jmxfetch.statsd.host=example.local",
6666
"-Ddd.writer.type=DDAgentWriter"
67-
] as String[]
68-
, "" as String[]
67+
]
68+
, []
6969
, [:]
7070
, true)
7171

@@ -89,8 +89,8 @@ class JMXFetchTest extends Specification {
8989
"-Ddd.trace.debug=true",
9090
"-Ddd.writer.type=DDAgentWriter"
9191
]
92-
+ configSettings as String[]
93-
, "" as String[]
92+
+ configSettings as List<CharSequence>
93+
, []
9494
, [:]
9595
, new PrintStream(testOutput))
9696

dd-java-agent/src/test/groovy/datadog/trace/agent/ListIntegrationsTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class ListIntegrationsTest extends Specification {
1313
def testOutput = new ByteArrayOutputStream()
1414
expect:
1515
IntegrationTestUtils.runOnSeparateJvm(AgentJar.name
16-
, [] as String[]
17-
, ["-li"] as String[]
16+
, []
17+
, ["-li"]
1818
, [:]
1919
, new PrintStream(testOutput)) == 0
2020
!new String(testOutput.toByteArray()).contains("ERROR")

0 commit comments

Comments
 (0)