Skip to content

Commit ae6cf51

Browse files
authored
Merge branch 'master' into dougqh/lazy-error-latencies
2 parents 07bb401 + 6a6eab7 commit ae6cf51

61 files changed

Lines changed: 2069 additions & 527 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ variables:
4949
BUILD_JOB_NAME: "build"
5050
DEPENDENCY_CACHE_POLICY: pull
5151
BUILD_CACHE_POLICY: pull
52-
GRADLE_VERSION: "8.14.5" # must match gradle-wrapper.properties
52+
GRADLE_VERSION: "9.5.1" # must match gradle-wrapper.properties
5353
MASS_READ_URL: "https://mass-read.us1.ddbuild.io"
5454
MAVEN_REPOSITORY_PROXY: "https://depot-read-api-java.us1.ddbuild.io/magicmirror/magicmirror/@current/"
5555
GRADLE_PLUGIN_PROXY: "https://depot-read-api-java.us1.ddbuild.io/magicmirror/magicmirror/@current/"

buildSrc/src/main/kotlin/dd-trace-java.configure-tests.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ tasks.withType<Test>().configureEach {
6363
onlyIf("skipForkedTests are undefined or false") { !skipForkedTestsProvider.isPresent }
6464
} else {
6565
exclude("**/*ForkedTest*")
66+
// Starting from Gradle 9.3, Gradle will fail if a test task has no discovered tests.
67+
// While this can be a misconfiguration, dd-trace-java test suite conventions allow suites
68+
// to contain abstract base classes that are extended by concrete forked test suites.
69+
//
70+
// Many instrumentation suites indeed only ship *ForkedTest concrete classes
71+
// (the non-forked peer task created by `addTestSuiteExtendingForDir` exists only
72+
// to host shared configurations/sources). Those test tasks won't have executable tests
73+
// by design under the `**/*ForkedTest*` exclude rule above. So let's allow them.
74+
//
75+
// Related but not the issue here https://github.com/gradle/gradle/issues/36508
76+
failOnNoDiscoveredTests = false
6677
}
6778

6879
// Set test timeout for 20 minutes. Default job timeout is 1h (configured on CI level).

communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ private static class State {
101101
String version;
102102
String telemetryProxyEndpoint;
103103
Set<String> peerTags = emptySet();
104+
String orgPropagationMarker;
104105
long lastTimeDiscovered;
105106
}
106107

@@ -316,6 +317,8 @@ private boolean processInfoResponse(State newState, String response) {
316317
? unmodifiableSet(new HashSet<>((List<String>) peer_tags))
317318
: emptySet();
318319
}
320+
Object opm = map.get("org_prop_marker");
321+
newState.orgPropagationMarker = (opm instanceof String) ? (String) opm : null;
319322
try {
320323
newState.state = Strings.sha256(response);
321324
} catch (Throwable ex) {
@@ -403,6 +406,10 @@ public Set<String> peerTags() {
403406
return discoveryState.peerTags;
404407
}
405408

409+
public String getOrgPropagationMarker() {
410+
return discoveryState.orgPropagationMarker;
411+
}
412+
406413
public String getMetricsEndpoint() {
407414
return discoveryState.metricsEndpoint;
408415
}

communication/src/test/groovy/datadog/communication/ddagent/DDAgentFeaturesDiscoveryTest.groovy

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class DDAgentFeaturesDiscoveryTest extends DDSpecification {
5050
static final String INFO_WITH_LONG_RUNNING_SPANS = loadJsonFile("agent-info-with-long-running-spans.json")
5151
static final String INFO_WITH_TELEMETRY_PROXY_RESPONSE = loadJsonFile("agent-info-with-telemetry-proxy.json")
5252
static final String INFO_WITH_OLD_EVP_PROXY = loadJsonFile("agent-info-with-old-evp-proxy.json")
53+
static final String INFO_WITH_OPM = loadJsonFile("agent-info-with-opm.json")
5354
static final String PROBE_STATE = "probestate"
5455

5556
def "test parse /info response"() {
@@ -209,6 +210,34 @@ class DDAgentFeaturesDiscoveryTest extends DDSpecification {
209210
0 * _
210211
}
211212

213+
def "test parse /info response with org propagation marker"() {
214+
setup:
215+
OkHttpClient client = Mock(OkHttpClient)
216+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, V0_5, true, false)
217+
218+
when: "/info available"
219+
features.discover()
220+
221+
then:
222+
1 * client.newCall(_) >> { Request request -> infoResponse(request, INFO_WITH_OPM) }
223+
features.getOrgPropagationMarker() == "abc123def0"
224+
0 * _
225+
}
226+
227+
def "test parse /info response without org propagation marker"() {
228+
setup:
229+
OkHttpClient client = Mock(OkHttpClient)
230+
DDAgentFeaturesDiscovery features = new DDAgentFeaturesDiscovery(client, monitoring, agentUrl, V0_5, true, false)
231+
232+
when: "/info available"
233+
features.discover()
234+
235+
then:
236+
1 * client.newCall(_) >> { Request request -> infoResponse(request, INFO_RESPONSE) }
237+
features.getOrgPropagationMarker() == null
238+
0 * _
239+
}
240+
212241
def "test fallback when /info empty"() {
213242
setup:
214243
OkHttpClient client = Mock(OkHttpClient)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"version": "7.67.0",
3+
"git_commit": "bdf863ccc9",
4+
"endpoints": [
5+
"/v0.3/traces",
6+
"/v0.4/traces",
7+
"/v0.5/traces",
8+
"/v0.6/stats",
9+
"/v0.1/pipeline_stats",
10+
"/telemetry/proxy/",
11+
"/evp_proxy/v4/",
12+
"/debugger/v1/input"
13+
],
14+
"client_drop_p0s": true,
15+
"long_running_spans": true,
16+
"config": {
17+
"statsd_port": 8125
18+
},
19+
"org_prop_marker": "abc123def0"
20+
}

dd-java-agent/instrumentation/graal/graal-native-image-20.0/src/main/java/datadog/trace/instrumentation/graal/nativeimage/NativeImageGeneratorRunnerInstrumentation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public static void onEnter(@Advice.Argument(value = 0, readOnly = false) String[
9292
+ "datadog.trace.api.GenericClassValue:build_time,"
9393
+ "datadog.trace.api.GlobalTracer:build_time,"
9494
+ "datadog.trace.api.GlobalTracer$1:build_time,"
95+
+ "datadog.trace.api.IdGenerationStrategy:build_time,"
9596
+ "datadog.trace.api.MethodFilterConfigParser:build_time,"
9697
+ "datadog.trace.api.WithGlobalTracer:build_time,"
9798
+ "datadog.trace.api.ProductActivation:build_time,"

dd-java-agent/instrumentation/java/java-concurrent/java-concurrent-1.8/src/main/java/datadog/trace/instrumentation/java/concurrent/AsyncPropagatingDisableInstrumentation.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public AsyncPropagatingDisableInstrumentation() {
4545
nameEndsWith("io.grpc.internal.ManagedChannelImpl");
4646
private static final ElementMatcher<TypeDescription> REACTOR_DISABLED_TYPE_INITIALIZERS =
4747
namedOneOf("reactor.core.scheduler.SchedulerTask", "reactor.core.scheduler.WorkerTask");
48+
private static final ElementMatcher<TypeDescription> RXJAVA2_DISABLED_TYPE_INITIALIZERS =
49+
named("io.reactivex.internal.schedulers.AbstractDirectTask");
4850

4951
@Override
5052
public boolean onlyMatchKnownTypes() {
@@ -77,7 +79,8 @@ public String[] knownMatchingTypes() {
7779
"net.sf.ehcache.store.disk.DiskStorageFactory",
7880
"org.springframework.jms.listener.DefaultMessageListenerContainer",
7981
"org.apache.activemq.broker.TransactionBroker",
80-
"com.mongodb.internal.connection.DefaultConnectionPool$AsyncWorkManager"
82+
"com.mongodb.internal.connection.DefaultConnectionPool$AsyncWorkManager",
83+
"io.reactivex.internal.schedulers.AbstractDirectTask"
8184
};
8285
}
8386

@@ -88,7 +91,10 @@ public String hierarchyMarkerType() {
8891

8992
@Override
9093
public ElementMatcher<TypeDescription> hierarchyMatcher() {
91-
return RX_WORKERS.or(GRPC_MANAGED_CHANNEL).or(REACTOR_DISABLED_TYPE_INITIALIZERS);
94+
return RX_WORKERS
95+
.or(GRPC_MANAGED_CHANNEL)
96+
.or(REACTOR_DISABLED_TYPE_INITIALIZERS)
97+
.or(RXJAVA2_DISABLED_TYPE_INITIALIZERS);
9298
}
9399

94100
@Override
@@ -172,6 +178,8 @@ public void methodAdvice(MethodTransformer transformer) {
172178
advice);
173179
transformer.applyAdvice(
174180
isTypeInitializer().and(isDeclaredBy(REACTOR_DISABLED_TYPE_INITIALIZERS)), advice);
181+
transformer.applyAdvice(
182+
isTypeInitializer().and(isDeclaredBy(RXJAVA2_DISABLED_TYPE_INITIALIZERS)), advice);
175183
}
176184

177185
public static class DisableAsyncAdvice {

dd-java-agent/instrumentation/rxjava/rxjava-2.0/src/test/groovy/RxJava2Test.groovy

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ class RxJava2Test extends InstrumentationSpecification {
2020

2121
public static final String EXCEPTION_MESSAGE = "test exception"
2222

23-
@Override
24-
boolean useStrictTraceWrites() {
25-
// TODO fix this by making sure that spans get closed properly
26-
return false
27-
}
28-
2923
@Shared
3024
def addOne = { i ->
3125
addOneFunc(i)

dd-java-agent/instrumentation/scala/scala-2.10.7/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ final testTasks = scalaVersions.collect { scalaLibrary ->
6868
}
6969

7070
return tasks.register("test$version", Test) {
71-
classpath = classpath
71+
testClassesDirs = sourceSets.test.output.classesDirs
72+
.minus(files(sourceSets.test.scala.classesDirectory))
73+
classpath = sourceSets.test.runtimeClasspath
7274
.filter { !it.toString().contains('scala-library') } // exclude default scala-library
7375
.minus(files(sourceSets.test.scala.classesDirectory)) // exclude default /build/classes/scala/test folder
7476
.plus(customSourceSet.output.classesDirs) // add /build/classes/scala/${version} folder
@@ -83,4 +85,3 @@ tasks.named('test', Test) {
8385
systemProperty('uses.java.concat', false) // version 2.10.7 does not use java concatenation
8486
finalizedBy(testTasks)
8587
}
86-

dd-java-agent/instrumentation/servlet/javax-servlet/javax-servlet-3.0/src/main/java/datadog/trace/instrumentation/servlet3/Servlet3Advice.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,19 +158,19 @@ public static void stopSpan(
158158

159159
final AgentSpan span = spanFromContext(scope.context());
160160

161-
if (request.isAsyncStarted()) {
161+
if (DECORATE.safeIsAsyncStarted(request)) {
162162
AtomicBoolean activated = new AtomicBoolean();
163163
FinishAsyncDispatchListener asyncListener =
164164
new FinishAsyncDispatchListener(scope, activated, !isDispatch);
165165
// Jetty doesn't always call the listener, if the request ends before
166166
request.setAttribute(DD_FIN_DISP_LIST_SPAN_ATTRIBUTE, asyncListener);
167167
try {
168168
request.getAsyncContext().addListener(asyncListener);
169-
} catch (final IllegalStateException e) {
169+
} catch (final IllegalStateException | AbstractMethodError ignored) {
170170
// org.eclipse.jetty.server.Request may throw an exception here if request became
171171
// finished after check above. We just ignore that exception and move on.
172172
}
173-
if (!request.isAsyncStarted() && activated.compareAndSet(false, true)) {
173+
if (!DECORATE.safeIsAsyncStarted(request) && activated.compareAndSet(false, true)) {
174174
if (!isDispatch) {
175175
DECORATE.onResponse(span, resp);
176176
}

0 commit comments

Comments
 (0)