Skip to content

Commit d9ea1af

Browse files
authored
Merge branch 'master' into dougqh/client-side-stats-overhead
2 parents 419a462 + 0ce9153 commit d9ea1af

63 files changed

Lines changed: 2539 additions & 1131 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.

.claude/skills/migrate-groovy-to-java/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ When converting Groovy code to Java code, make sure that:
2121
- Do not wrap checked exceptions and throw a Runtime exception; prefer adding a throws clause at method declaration
2222
- Do not mark local variables `final`
2323
- Ensure variables are human-readable; avoid single-letter names and pre-define variables that are referenced multiple times
24+
- When translating Spock `Mock(...)` usage, use `libs.bundles.mockito` instead of writing manual recording/stub implementations

.github/g2j-migrated-modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77

88
buildSrc/call-site-instrumentation-plugin
99
components/json
10+
dd-trace-api

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ public Context startSpan(REQUEST_CARRIER carrier, Context parentContext) {
174174
extracted = startInferredProxySpan(parentContext, extracted);
175175
AgentSpan span =
176176
tracer().startSpan(instrumentationName, spanName(), extracted).setMeasured(true);
177+
// Register service-entry span with inferred proxy span (if present) so that premature
178+
// finish calls from child spans (e.g., Spring MVC handler) are deferred until the
179+
// service-entry span finishes (after the response status is known).
180+
registerServiceEntrySpanInInferredProxy(parentContext, span);
181+
// Reset service name inherited from inferred proxy parent: the inferred span uses the
182+
// gateway domain name as service name, but the service-entry span should identify
183+
// the application (configured DD_SERVICE), not the upstream gateway.
184+
resetServiceNameIfUnderInferredProxy(parentContext, span);
177185
// Apply RequestBlockingAction if any
178186
Flow<Void> flow = callIGCallbackRequestHeaders(span, carrier);
179187
if (flow.getAction() instanceof RequestBlockingAction) {
@@ -193,6 +201,20 @@ protected AgentSpanContext startInferredProxySpan(Context context, AgentSpanCont
193201
return span.start(extracted);
194202
}
195203

204+
private void registerServiceEntrySpanInInferredProxy(
205+
Context parentContext, AgentSpan serviceEntrySpan) {
206+
InferredProxySpan inferredProxy = InferredProxySpan.fromContext(parentContext);
207+
if (inferredProxy != null) {
208+
inferredProxy.registerServiceEntrySpan(serviceEntrySpan);
209+
}
210+
}
211+
212+
private void resetServiceNameIfUnderInferredProxy(Context parentContext, AgentSpan span) {
213+
if (InferredProxySpan.fromContext(parentContext) != null) {
214+
span.setServiceName(Config.get().getServiceName());
215+
}
216+
}
217+
196218
private final DataStreamsTransactionTracker.TransactionSourceReader
197219
DSM_TRANSACTION_SOURCE_READER =
198220
(source, headerName) -> {

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/jdbc/DBInfo.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.trace.bootstrap.instrumentation.jdbc;
22

3+
import datadog.trace.util.HashingUtils;
34
import java.util.Objects;
45

56
public final class DBInfo {
@@ -256,17 +257,18 @@ public boolean equals(Object o) {
256257

257258
@Override
258259
public int hashCode() {
259-
return Objects.hash(
260-
type,
261-
subtype,
262-
fullPropagationSupport,
263-
url,
264-
user,
265-
instance,
266-
db,
267-
host,
268-
port,
269-
warehouse,
270-
schema);
260+
int hash = 0;
261+
hash = HashingUtils.addToHash(hash, type);
262+
hash = HashingUtils.addToHash(hash, subtype);
263+
hash = HashingUtils.addToHash(hash, fullPropagationSupport);
264+
hash = HashingUtils.addToHash(hash, url);
265+
hash = HashingUtils.addToHash(hash, user);
266+
hash = HashingUtils.addToHash(hash, instance);
267+
hash = HashingUtils.addToHash(hash, db);
268+
hash = HashingUtils.addToHash(hash, host);
269+
hash = HashingUtils.addToHash(hash, port);
270+
hash = HashingUtils.addToHash(hash, warehouse);
271+
hash = HashingUtils.addToHash(hash, schema);
272+
return hash;
271273
}
272274
}

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/SourceFileTrackingTransformer.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,23 +98,27 @@ public byte[] transform(
9898
}
9999

100100
private void registerSourceFile(String className, byte[] classfileBuffer) {
101-
String javaClassName = Strings.getClassName(className);
102-
if (classNameFilter.isExcluded(javaClassName)) {
103-
return;
104-
}
105-
String sourceFile = ClassFileHelper.extractSourceFile(classfileBuffer);
106-
if (sourceFile == null) {
107-
return;
108-
}
109-
if (!isExtensionAllowed(sourceFile)) {
110-
return;
111-
}
112-
String simpleClassName = stripPackagePath(className);
113-
String simpleSourceFile = removeExtension(sourceFile);
114-
if (simpleClassName.equals(simpleSourceFile)) {
115-
return;
101+
try {
102+
String javaClassName = Strings.getClassName(className);
103+
if (classNameFilter.isExcluded(javaClassName)) {
104+
return;
105+
}
106+
String sourceFile = ClassFileHelper.extractSourceFile(classfileBuffer);
107+
if (sourceFile == null) {
108+
return;
109+
}
110+
if (!isExtensionAllowed(sourceFile)) {
111+
return;
112+
}
113+
String simpleClassName = stripPackagePath(className);
114+
String simpleSourceFile = removeExtension(sourceFile);
115+
if (simpleClassName.equals(simpleSourceFile)) {
116+
return;
117+
}
118+
finder.register(sourceFile, className);
119+
} catch (Exception e) {
120+
LOGGER.debug("Error registering source file {}: {}", className, e);
116121
}
117-
finder.register(sourceFile, className);
118122
}
119123

120124
private boolean isExtensionAllowed(String sourceFile) {

dd-java-agent/instrumentation/akka/akka-actor-2.5/src/akka23Test/groovy/AkkaActorTest.groovy

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import datadog.trace.agent.test.InstrumentationSpecification
2+
import datadog.trace.api.config.TraceInstrumentationConfig
23
import datadog.trace.bootstrap.instrumentation.api.Tags
34
import spock.lang.Shared
45

@@ -82,3 +83,11 @@ class AkkaActorTest extends InstrumentationSpecification {
8283
}
8384
}
8485
}
86+
87+
class AkkaActorContextSwapTest extends AkkaActorTest {
88+
@Override
89+
void configurePreAgent() {
90+
super.configurePreAgent()
91+
injectSysConfig(TraceInstrumentationConfig.LEGACY_CONTEXT_MANAGER_ENABLED, "false")
92+
}
93+
}

dd-java-agent/instrumentation/akka/akka-actor-2.5/src/main/java/datadog/trace/instrumentation/akka/concurrent/AkkaActorCellInstrumentation.java

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
44
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.checkpointActiveForRollback;
55
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.rollbackActiveToCheckpoint;
6+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext;
67
import static java.util.Collections.singletonMap;
78
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
89

910
import akka.dispatch.Envelope;
1011
import com.google.auto.service.AutoService;
12+
import datadog.context.Context;
1113
import datadog.trace.agent.tooling.Instrumenter;
1214
import datadog.trace.agent.tooling.InstrumenterModule;
15+
import datadog.trace.api.InstrumenterConfig;
1316
import datadog.trace.bootstrap.InstrumentationContext;
1417
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
1518
import datadog.trace.bootstrap.instrumentation.java.concurrent.AdviceUtils;
@@ -54,24 +57,34 @@ public void methodAdvice(MethodTransformer transformer) {
5457
*/
5558
public static class InvokeAdvice {
5659
@Advice.OnMethodEnter(suppress = Throwable.class)
57-
public static AgentScope enter(@Advice.Argument(value = 0) Envelope envelope) {
60+
public static Context enter(
61+
@Advice.Argument(value = 0) Envelope envelope,
62+
@Advice.Local("taskScope") AgentScope taskScope) {
5863

5964
// do this before checkpointing, as the envelope's task scope may already be active
60-
AgentScope taskScope =
65+
taskScope =
6166
AdviceUtils.startTaskScope(
6267
InstrumentationContext.get(Envelope.class, State.class), envelope);
6368

64-
// remember the currently active scope so we can roll back to this point
65-
checkpointActiveForRollback();
66-
67-
return taskScope;
69+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
70+
// remember the currently active scope so we can roll back to this point
71+
checkpointActiveForRollback();
72+
return null;
73+
} else {
74+
return getCurrentContext().swap();
75+
}
6876
}
6977

7078
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
71-
public static void exit(@Advice.Enter AgentScope taskScope) {
79+
public static void exit(
80+
@Advice.Local("taskScope") AgentScope taskScope, @Advice.Enter Context checkpointContext) {
7281

73-
// Clean up any leaking scopes from akka-streams/akka-http etc.
74-
rollbackActiveToCheckpoint();
82+
if (checkpointContext == null) {
83+
// Clean up any leaking scopes from akka-streams/akka-http etc.
84+
rollbackActiveToCheckpoint();
85+
} else {
86+
checkpointContext.swap();
87+
}
7588

7689
// close envelope's task scope if we previously started it
7790
if (taskScope != null) {

dd-java-agent/instrumentation/akka/akka-actor-2.5/src/main/java/datadog/trace/instrumentation/akka/concurrent/AkkaMailboxInstrumentation.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
44
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.checkpointActiveForRollback;
55
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.rollbackActiveToCheckpoint;
6+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getCurrentContext;
67
import static java.util.Collections.singletonList;
78
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
89

910
import com.google.auto.service.AutoService;
11+
import datadog.context.Context;
1012
import datadog.trace.agent.tooling.ExcludeFilterProvider;
1113
import datadog.trace.agent.tooling.Instrumenter;
1214
import datadog.trace.agent.tooling.InstrumenterModule;
15+
import datadog.trace.api.InstrumenterConfig;
1316
import datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter;
1417
import java.util.Collection;
1518
import java.util.EnumMap;
@@ -59,15 +62,24 @@ public void methodAdvice(MethodTransformer transformer) {
5962
*/
6063
public static final class SuppressMailboxRunAdvice {
6164
@Advice.OnMethodEnter(suppress = Throwable.class)
62-
public static void enter() {
63-
// remember the currently active scope so we can roll back to this point
64-
checkpointActiveForRollback();
65+
public static Context enter() {
66+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
67+
// remember the currently active scope so we can roll back to this point
68+
checkpointActiveForRollback();
69+
return null;
70+
} else {
71+
return getCurrentContext().swap();
72+
}
6573
}
6674

6775
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
68-
public static void exit() {
69-
// Clean up any leaking scopes from akka-streams/akka-http etc.
70-
rollbackActiveToCheckpoint();
76+
public static void exit(@Advice.Enter final Context checkpointContext) {
77+
if (checkpointContext == null) {
78+
// Clean up any leaking scopes from akka-streams/akka-http etc.
79+
rollbackActiveToCheckpoint();
80+
} else {
81+
checkpointContext.swap();
82+
}
7183
}
7284
}
7385
}

dd-java-agent/instrumentation/aws-java/aws-java-sqs-1.0/src/main/java/datadog/trace/instrumentation/aws/v1/sqs/TracingIterator.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateNext;
88
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closePrevious;
99
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan;
10+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getRootContext;
11+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext;
1012
import static datadog.trace.bootstrap.instrumentation.api.URIUtils.urlFileName;
1113
import static datadog.trace.instrumentation.aws.v1.sqs.MessageExtractAdapter.GETTER;
1214
import static datadog.trace.instrumentation.aws.v1.sqs.SqsDecorator.BROKER_DECORATE;
@@ -18,6 +20,7 @@
1820

1921
import com.amazonaws.services.sqs.model.Message;
2022
import datadog.trace.api.Config;
23+
import datadog.trace.api.InstrumenterConfig;
2124
import datadog.trace.api.datastreams.DataStreamsTags;
2225
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
2326
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
@@ -43,7 +46,14 @@ public boolean hasNext() {
4346
boolean moreMessages = delegate.hasNext();
4447
if (!moreMessages) {
4548
// no more messages, use this as a signal to close the last iteration scope
46-
closePrevious(true);
49+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
50+
closePrevious(true);
51+
} else {
52+
final AgentSpan previousSpan = spanFromContext(getRootContext().swap());
53+
if (previousSpan != null) {
54+
previousSpan.finishWithEndToEnd();
55+
}
56+
}
4757
}
4858
return moreMessages;
4959
}
@@ -57,7 +67,14 @@ public Message next() {
5767

5868
protected void startNewMessageSpan(Message message) {
5969
try {
60-
closePrevious(true);
70+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
71+
closePrevious(true);
72+
} else if (message == null) { // previous message span was the last
73+
final AgentSpan previousSpan = spanFromContext(getRootContext().swap());
74+
if (previousSpan != null) {
75+
previousSpan.finishWithEndToEnd();
76+
}
77+
}
6178
if (message != null) {
6279
AgentSpan queueSpan = null;
6380
if (batchContext == null) {
@@ -92,7 +109,14 @@ protected void startNewMessageSpan(Message message) {
92109

93110
CONSUMER_DECORATE.afterStart(span);
94111
CONSUMER_DECORATE.onConsume(span, queueUrl);
95-
activateNext(span);
112+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
113+
activateNext(span);
114+
} else {
115+
final AgentSpan previousSpan = spanFromContext(span.swap());
116+
if (previousSpan != null) {
117+
previousSpan.finishWithEndToEnd();
118+
}
119+
}
96120
if (queueSpan != null) {
97121
BROKER_DECORATE.beforeFinish(queueSpan);
98122
queueSpan.finish();

dd-java-agent/instrumentation/aws-java/aws-java-sqs-1.0/src/main/java/datadog/trace/instrumentation/aws/v1/sqs/TracingListIterator.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package datadog.trace.instrumentation.aws.v1.sqs;
22

33
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closePrevious;
4+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.getRootContext;
5+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext;
46

57
import com.amazonaws.services.sqs.model.Message;
8+
import datadog.trace.api.InstrumenterConfig;
9+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
610
import java.util.ListIterator;
711

812
public class TracingListIterator extends TracingIterator<ListIterator<Message>>
@@ -17,7 +21,14 @@ public boolean hasPrevious() {
1721
boolean moreMessages = delegate.hasPrevious();
1822
if (!moreMessages) {
1923
// no more messages, use this as a signal to close the last iteration scope
20-
closePrevious(true);
24+
if (InstrumenterConfig.get().isLegacyContextManagerEnabled()) {
25+
closePrevious(true);
26+
} else {
27+
final AgentSpan previousSpan = spanFromContext(getRootContext().swap());
28+
if (previousSpan != null) {
29+
previousSpan.finishWithEndToEnd();
30+
}
31+
}
2132
}
2233
return moreMessages;
2334
}

0 commit comments

Comments
 (0)