Skip to content

Commit e947d7d

Browse files
authored
Merge branch 'master' into mhlidd/run_spock_with_strict
2 parents 64af647 + aa7c70f commit e947d7d

File tree

128 files changed

+4507
-1395
lines changed

Some content is hidden

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

128 files changed

+4507
-1395
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ tasks.withType<Test>().configureEach {
4646
// Use a task-specific user prefs directory
4747
systemProperty("java.util.prefs.userRoot", layout.buildDirectory.dir("tmp/userPrefs/$name").get().asFile.absolutePath)
4848

49+
// Enable JUnit 5 auto-detection so ConfigInversionExtension (STRICT mode) is loaded automatically
50+
systemProperty("junit.jupiter.extensions.autodetection.enabled", "true")
51+
4952
// Split up tests that want to run forked in their own separate JVM for generated tasks
5053
if (name.startsWith("forkedTest") || name.endsWith("ForkedTest")) {
5154
setExcludes(emptyList())

communication/src/main/java/datadog/communication/http/OkHttpUtils.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.net.InetSocketAddress;
1616
import java.net.Proxy;
1717
import java.nio.ByteBuffer;
18+
import java.util.Arrays;
1819
import java.util.Collections;
1920
import java.util.List;
2021
import java.util.Map;
@@ -27,6 +28,7 @@
2728
import okhttp3.HttpUrl;
2829
import okhttp3.MediaType;
2930
import okhttp3.OkHttpClient;
31+
import okhttp3.Protocol;
3032
import okhttp3.Request;
3133
import okhttp3.RequestBody;
3234
import okhttp3.Response;
@@ -62,7 +64,7 @@ public static OkHttpClient buildHttpClient(final HttpUrl url, final long timeout
6264
}
6365

6466
public static OkHttpClient buildHttpClient(
65-
final boolean isHttp,
67+
final boolean isPlainHttp,
6668
final String unixDomainSocketPath,
6769
final String namedPipe,
6870
final long timeoutMillis) {
@@ -71,7 +73,30 @@ public static OkHttpClient buildHttpClient(
7173
Config.get().isJdkSocketEnabled(),
7274
namedPipe,
7375
null,
74-
isHttp,
76+
isPlainHttp,
77+
false,
78+
null,
79+
null,
80+
null,
81+
null,
82+
null,
83+
null,
84+
timeoutMillis,
85+
Config.get().isAgentConfiguredUsingDefault());
86+
}
87+
88+
public static OkHttpClient buildHttp2Client(
89+
final boolean isPlainHttp,
90+
final String unixDomainSocketPath,
91+
final String namedPipe,
92+
final long timeoutMillis) {
93+
return buildHttpClient(
94+
unixDomainSocketPath,
95+
Config.get().isJdkSocketEnabled(),
96+
namedPipe,
97+
null,
98+
isPlainHttp,
99+
true,
75100
null,
76101
null,
77102
null,
@@ -99,6 +124,7 @@ public static OkHttpClient buildHttpClient(
99124
config.getAgentNamedPipe(),
100125
dispatcher,
101126
isPlainHttp(url),
127+
false,
102128
retryOnConnectionFailure,
103129
maxRunningRequests,
104130
proxyHost,
@@ -116,7 +142,8 @@ private static OkHttpClient buildHttpClient(
116142
final boolean useJdkUnixDomainSocket,
117143
final String namedPipe,
118144
final Dispatcher dispatcher,
119-
final boolean isHttp,
145+
final boolean isPlainHttp,
146+
final boolean isHttp2,
120147
final Boolean retryOnConnectionFailure,
121148
final Integer maxRunningRequests,
122149
final String proxyHost,
@@ -159,11 +186,19 @@ private static OkHttpClient buildHttpClient(
159186
log.debug("Using NamedPipe as http transport");
160187
}
161188

162-
if (isHttp) {
189+
if (isPlainHttp) {
163190
// force clear text when using http to avoid failures for JVMs without TLS
164191
builder.connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT));
165192
}
166193

194+
if (isHttp2) {
195+
if (isPlainHttp) {
196+
builder.protocols(Collections.singletonList(Protocol.H2_PRIOR_KNOWLEDGE));
197+
} else {
198+
builder.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1));
199+
}
200+
}
201+
167202
if (retryOnConnectionFailure != null) {
168203
builder.retryOnConnectionFailure(retryOnConnectionFailure);
169204
}

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/AsyncResultDecorator.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@
1111
*/
1212
public abstract class AsyncResultDecorator extends BaseDecorator {
1313

14-
private static final ClassValue<AsyncResultExtension> EXTENSION_CLASS_VALUE =
15-
new ClassValue<AsyncResultExtension>() {
16-
@Override
17-
protected AsyncResultExtension computeValue(Class<?> type) {
18-
return AsyncResultExtensions.registered().stream()
19-
.filter(extension -> extension.supports(type))
20-
.findFirst()
21-
.orElse(null);
22-
}
23-
};
24-
2514
/**
2615
* Look for asynchronous result and decorate it with span finisher. If the result is not
2716
* asynchronous, it will be return unmodified and span will be finished.
@@ -33,12 +22,9 @@ protected AsyncResultExtension computeValue(Class<?> type) {
3322
*/
3423
public Object wrapAsyncResultOrFinishSpan(
3524
final Object result, final Class<?> methodReturnType, final AgentSpan span) {
36-
AsyncResultExtension extension;
37-
if (result != null && (extension = EXTENSION_CLASS_VALUE.get(methodReturnType)) != null) {
38-
Object applied = extension.apply(result, span);
39-
if (applied != null) {
40-
return applied;
41-
}
25+
Object applied = AsyncResultExtensions.wrapAsyncResult(result, methodReturnType, span);
26+
if (applied != null) {
27+
return applied;
4228
}
4329
// If no extension was applied, immediately finish the span and return the original result
4430
span.finish();

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/AsyncResultExtensions.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@ public final class AsyncResultExtensions {
1616
private static final List<AsyncResultExtension> EXTENSIONS =
1717
new CopyOnWriteArrayList<>(singletonList(new CompletableAsyncResultExtension()));
1818

19+
private static final ClassValue<AsyncResultExtension> EXTENSION_CLASS_VALUE =
20+
new ClassValue<AsyncResultExtension>() {
21+
@Override
22+
protected AsyncResultExtension computeValue(Class<?> type) {
23+
return EXTENSIONS.stream()
24+
.filter(extension -> extension.supports(type))
25+
.findFirst()
26+
.orElse(null);
27+
}
28+
};
29+
30+
/**
31+
* Wraps a supported async result so the span is finished when the async computation completes.
32+
*
33+
* @return the wrapped async result, or {@code null} if the result type is unsupported or no
34+
* wrapping is applied
35+
*/
36+
public static Object wrapAsyncResult(
37+
final Object result, final Class<?> resultType, final AgentSpan span) {
38+
AsyncResultExtension extension;
39+
if (result != null && (extension = EXTENSION_CLASS_VALUE.get(resultType)) != null) {
40+
return extension.apply(result, span);
41+
}
42+
return null;
43+
}
44+
1945
/**
2046
* Registers an extension to add supported async types.
2147
*
@@ -36,11 +62,6 @@ public static void register(AsyncResultExtension extension) {
3662
}
3763
}
3864

39-
/** Returns the list of currently registered extensions. */
40-
public static List<AsyncResultExtension> registered() {
41-
return EXTENSIONS;
42-
}
43-
4465
static final class CompletableAsyncResultExtension implements AsyncResultExtension {
4566
@Override
4667
public boolean supports(Class<?> result) {
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package datadog.trace.bootstrap.instrumentation.java.lang;
22

3+
/** This class is a helper for the java-lang-21.0 {@code VirtualThreadInstrumentation}. */
34
public final class VirtualThreadHelper {
45
public static final String VIRTUAL_THREAD_CLASS_NAME = "java.lang.VirtualThread";
56

67
/**
7-
* {@link datadog.trace.bootstrap.instrumentation.api.AgentScope} class name as string literal.
8-
* This is mandatory for {@link datadog.trace.bootstrap.ContextStore} API call.
8+
* {@link VirtualThreadState} class name as string literal. This is mandatory for {@link
9+
* datadog.trace.bootstrap.ContextStore} API call.
910
*/
10-
public static final String AGENT_SCOPE_CLASS_NAME =
11-
"datadog.trace.bootstrap.instrumentation.api.AgentScope";
11+
public static final String VIRTUAL_THREAD_STATE_CLASS_NAME =
12+
"datadog.trace.bootstrap.instrumentation.java.lang.VirtualThreadState";
1213
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package datadog.trace.bootstrap.instrumentation.java.lang;
2+
3+
import datadog.context.Context;
4+
import datadog.trace.bootstrap.instrumentation.api.AgentScope.Continuation;
5+
6+
/**
7+
* This class holds the saved context and scope continuation for a virtual thread.
8+
*
9+
* <p>Used by java-lang-21.0 {@code VirtualThreadInstrumentation} to swap the entire scope stack on
10+
* mount/unmount.
11+
*/
12+
public final class VirtualThreadState {
13+
/** The virtual thread's saved context (scope stack snapshot). */
14+
private Context context;
15+
16+
/** Prevents the enclosing context scope from completing before the virtual thread finishes. */
17+
private final Continuation continuation;
18+
19+
/** The carrier thread's saved context, set between mount and unmount. */
20+
private Context previousContext;
21+
22+
public VirtualThreadState(Context context, Continuation continuation) {
23+
this.context = context;
24+
this.continuation = continuation;
25+
}
26+
27+
/** Called on mount: swaps the virtual thread's context into the carrier thread. */
28+
public void onMount() {
29+
this.previousContext = this.context.swap();
30+
}
31+
32+
/** Called on unmount: restores the carrier thread's original context. */
33+
public void onUnmount() {
34+
if (this.previousContext != null) {
35+
this.context = this.previousContext.swap();
36+
this.previousContext = null;
37+
}
38+
}
39+
40+
/** Called on termination: releases the trace continuation. */
41+
public void onTerminate() {
42+
if (this.continuation != null) {
43+
this.continuation.cancel();
44+
}
45+
}
46+
}

dd-java-agent/agent-crashtracking/src/main/java/datadog/crashtracking/ConfigManager.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static class StoredConfig {
3535
final String reportUUID;
3636
final boolean agentless;
3737
final boolean sendToErrorTracking;
38+
final boolean extendedInfoEnabled;
3839

3940
StoredConfig(
4041
String reportUUID,
@@ -45,7 +46,8 @@ public static class StoredConfig {
4546
String processTags,
4647
String runtimeId,
4748
boolean agentless,
48-
boolean sendToErrorTracking) {
49+
boolean sendToErrorTracking,
50+
boolean extendedInfoEnabled) {
4951
this.service = service;
5052
this.env = env;
5153
this.version = version;
@@ -55,6 +57,11 @@ public static class StoredConfig {
5557
this.reportUUID = reportUUID;
5658
this.agentless = agentless;
5759
this.sendToErrorTracking = sendToErrorTracking;
60+
this.extendedInfoEnabled = extendedInfoEnabled;
61+
}
62+
63+
public CrashUploaderSettings toCrashUploaderSettings() {
64+
return new CrashUploaderSettings(extendedInfoEnabled);
5865
}
5966

6067
public static class Builder {
@@ -67,6 +74,7 @@ public static class Builder {
6774
String reportUUID;
6875
boolean agentless;
6976
boolean sendToErrorTracking;
77+
boolean extendedInfoEnabled;
7078

7179
public Builder(Config config) {
7280
// get sane defaults
@@ -77,6 +85,7 @@ public Builder(Config config) {
7785
this.reportUUID = RandomUtils.randomUUID().toString();
7886
this.agentless = config.isCrashTrackingAgentless();
7987
this.sendToErrorTracking = config.isCrashTrackingErrorsIntakeEnabled();
88+
this.extendedInfoEnabled = config.isCrashTrackingExtendedInfoEnabled();
8089
}
8190

8291
public Builder service(String service) {
@@ -119,6 +128,11 @@ public Builder agentless(boolean agentless) {
119128
return this;
120129
}
121130

131+
public Builder extendedInfoEnabled(boolean extendedInfoEnabled) {
132+
this.extendedInfoEnabled = extendedInfoEnabled;
133+
return this;
134+
}
135+
122136
// @VisibleForTesting
123137
Builder reportUUID(String reportUUID) {
124138
this.reportUUID = reportUUID;
@@ -135,7 +149,8 @@ public StoredConfig build() {
135149
processTags,
136150
runtimeId,
137151
agentless,
138-
sendToErrorTracking);
152+
sendToErrorTracking,
153+
extendedInfoEnabled);
139154
}
140155
}
141156
}
@@ -194,6 +209,8 @@ static void writeConfigToFile(Config config, Path cfgPath, String... additionalE
194209
writeEntry(bw, "java_home", SystemProperties.get("java.home"));
195210
writeEntry(bw, "agentless", Boolean.toString(config.isCrashTrackingAgentless()));
196211
writeEntry(bw, "upload_to_et", Boolean.toString(config.isCrashTrackingErrorsIntakeEnabled()));
212+
writeEntry(
213+
bw, "extended_info", Boolean.toString(config.isCrashTrackingExtendedInfoEnabled()));
197214

198215
Runtime.getRuntime()
199216
.addShutdownHook(
@@ -257,6 +274,9 @@ public static StoredConfig readConfig(Config config, Path scriptPath) {
257274
case "upload_to_et":
258275
cfgBuilder.sendToErrorTracking(Boolean.parseBoolean(value));
259276
break;
277+
case "extended_info":
278+
cfgBuilder.extendedInfoEnabled(Boolean.parseBoolean(value));
279+
break;
260280
default:
261281
// ignore
262282
break;

dd-java-agent/agent-crashtracking/src/main/java/datadog/crashtracking/CrashUploader.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public void onResponse(Call call, Response response) throws IOException {
113113

114114
private final Config config;
115115
private final ConfigManager.StoredConfig storedConfig;
116+
private final CrashUploaderSettings uploaderSettings;
116117

117118
private final HttpUrl telemetryUrl;
118119
private final HttpUrl errorTrackingUrl;
@@ -131,6 +132,7 @@ public CrashUploader(@Nonnull final ConfigManager.StoredConfig storedConfig) {
131132
@NonNull final Config config, @Nonnull final ConfigManager.StoredConfig storedConfig) {
132133
this.config = config;
133134
this.storedConfig = storedConfig;
135+
this.uploaderSettings = storedConfig.toCrashUploaderSettings();
134136
this.telemetryUrl = HttpUrl.get(config.getFinalCrashTrackingTelemetryUrl());
135137
this.errorTrackingUrl = HttpUrl.get(config.getFinalCrashTrackingErrorTrackingUrl());
136138
this.agentless = config.isCrashTrackingAgentless();
@@ -525,7 +527,7 @@ private RequestBody makeErrorTrackingRequestBody(@Nonnull CrashLog payload, bool
525527
}
526528
writer.name("type").value(payload.error.kind);
527529
writer.name("message").value(payload.error.message);
528-
if (payload.error.threadName != null) {
530+
if (uploaderSettings.isExtendedInfoEnabled() && payload.error.threadName != null) {
529531
writer.name("thread_name").value(payload.error.threadName);
530532
}
531533
writer.name("source_type").value("Crashtracking");
@@ -588,7 +590,8 @@ private RequestBody makeErrorTrackingRequestBody(@Nonnull CrashLog payload, bool
588590
}
589591
writer.endObject();
590592
}
591-
if (payload.experimental.runtimeArgs != null) {
593+
if (uploaderSettings.isExtendedInfoEnabled()
594+
&& payload.experimental.runtimeArgs != null) {
592595
writer.name("runtime_args");
593596
writer.beginArray();
594597
for (String arg : payload.experimental.runtimeArgs) {
@@ -599,7 +602,7 @@ private RequestBody makeErrorTrackingRequestBody(@Nonnull CrashLog payload, bool
599602
writer.endObject();
600603
}
601604
// files (e.g. /proc/self/maps or dynamic_libraries)
602-
if (payload.files != null) {
605+
if (uploaderSettings.isExtendedInfoEnabled() && payload.files != null) {
603606
writer.name("files");
604607
writer.beginObject();
605608
writer.name(payload.files.name);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package datadog.crashtracking;
2+
3+
/** Immutable settings that control what data {@link CrashUploader} includes in uploaded reports. */
4+
public final class CrashUploaderSettings {
5+
final boolean extendedInfoEnabled;
6+
7+
CrashUploaderSettings(boolean extendedInfoEnabled) {
8+
this.extendedInfoEnabled = extendedInfoEnabled;
9+
}
10+
11+
boolean isExtendedInfoEnabled() {
12+
return extendedInfoEnabled;
13+
}
14+
}

0 commit comments

Comments
 (0)