Skip to content

Commit 42b4b7e

Browse files
authored
Merge branch 'master' into dougqh/collection-benchmarks
2 parents 43f7eaf + 0ce9153 commit 42b4b7e

31 files changed

Lines changed: 1042 additions & 604 deletions

File tree

.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/jdbc/src/test/groovy/JDBCInstrumentationTestBase.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ abstract class JDBCInstrumentationTest extends VersionedNamingTestBase {
135135
config.addDataSourceProperty("prepStmtCacheSize", "250")
136136
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048")
137137
config.setMaximumPoolSize(1)
138-
config.setConnectionTimeout(1000)
138+
config.setConnectionTimeout(5000)
139139

140140
return new HikariDataSource(config)
141141
}
@@ -948,7 +948,7 @@ abstract class JDBCInstrumentationTest extends VersionedNamingTestBase {
948948
connectionPoolName | exhaustPoolForMillis | expectException
949949
"hikari" | 500 | false
950950
"dbcp2" | 500 | false
951-
"hikari" | 1500 | true
951+
"hikari" | 6000 | true
952952
"dbcp2" | 1500 | true
953953
}
954954

dd-java-agent/instrumentation/jms/javax-jms-1.1/src/main/java/datadog/trace/instrumentation/jms/JMSMessageConsumerInstrumentation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public static MessageConsumerState beforeReceive(@Advice.This final MessageConsu
9898
} else {
9999
final AgentSpan previousSpan = spanFromContext(getRootContext().swap());
100100
if (previousSpan != null) {
101+
CONSUMER_DECORATE.beforeFinish(previousSpan);
101102
previousSpan.finishWithEndToEnd();
102103
}
103104
}
@@ -178,6 +179,7 @@ public static void afterReceive(
178179
} else {
179180
final AgentSpan previousSpan = spanFromContext(span.swap());
180181
if (previousSpan != null) {
182+
CONSUMER_DECORATE.beforeFinish(previousSpan);
181183
previousSpan.finishWithEndToEnd();
182184
}
183185
}

0 commit comments

Comments
 (0)