Skip to content

Commit e497ad0

Browse files
authored
Merge branch 'master' into dougqh/cache-span-kind-ordinal
2 parents 0913173 + ca32af7 commit e497ad0

18 files changed

Lines changed: 468 additions & 356 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
@@ -20,6 +20,7 @@ When converting Groovy code to Java code, make sure that:
2020
- `@TableTest` and `@MethodSource` may be combined on the same `@ParameterizedTest` when most cases are tabular but a few cases require programmatic setup.
2121
- In combined mode, keep table-friendly cases in `@TableTest`, and put only non-tabular/complex cases in `@MethodSource`.
2222
- If `@TableTest` is not viable for the test at all, use `@MethodSource` only.
23+
- If `@TableTest` was successfully used and if the `@ParameterizedTest` is not used to specify the test name, `@ParameterizedTest` can then be removed as `@TableTest` replace it fully.
2324
- For `@MethodSource`, name the arguments method `<testMethodName>Arguments` (camelCase, e.g. `testMethodArguments`) and return `Stream<Arguments>` using `Stream.of(...)` and `arguments(...)` with static import.
2425
- Ensure parameterized test names are human-readable (i.e. no hashcodes); instead add a description string as the first `Arguments.arguments(...)` value or index the test case
2526
- When converting tuples, create a light dedicated structure instead to keep the typing system

dd-java-agent/agent-aiguard/src/main/java/com/datadog/aiguard/AIGuardInternal.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public BadConfigurationException(final String message) {
6969
static final String ACTION_TAG = "ai_guard.action";
7070
static final String REASON_TAG = "ai_guard.reason";
7171
static final String BLOCKED_TAG = "ai_guard.blocked";
72+
static final String EVENT_TAG = "ai_guard.event";
7273
static final String META_STRUCT_TAG = "ai_guard";
7374
static final String META_STRUCT_MESSAGES = "messages";
7475
static final String META_STRUCT_CATEGORIES = "attack_categories";
@@ -227,6 +228,7 @@ public Evaluation evaluate(final List<Message> messages, final Options options)
227228
final AgentSpan localRootSpan = span.getLocalRootSpan();
228229
if (localRootSpan != null) {
229230
localRootSpan.setTag(Tags.AI_GUARD_KEEP, true);
231+
localRootSpan.setTag(EVENT_TAG, true);
230232
}
231233
try (final AgentScope scope = tracer.activateSpan(span)) {
232234
final Message last = messages.get(messages.size() - 1);

dd-java-agent/agent-aiguard/src/test/groovy/com/datadog/aiguard/AIGuardInternalTests.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class AIGuardInternalTests extends DDSpecification {
190190
then:
191191
1 * span.setTag(AIGuardInternal.TARGET_TAG, suite.target)
192192
1 * localRootSpan.setTag(Tags.AI_GUARD_KEEP, true)
193+
1 * localRootSpan.setTag(AIGuardInternal.EVENT_TAG, true)
193194
if (suite.target == 'tool') {
194195
1 * span.setTag(AIGuardInternal.TOOL_TAG, 'calc')
195196
}

dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseClientInstrumentation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
2525
import net.bytebuddy.asm.Advice;
2626
import org.apache.axis2.context.MessageContext;
27+
import org.apache.http.HttpInetConnection;
2728
import org.apache.http.HttpResponse;
2829
import org.apache.http.nio.NHttpClientConnection;
2930
import org.apache.synapse.transport.passthru.TargetContext;
@@ -107,6 +108,13 @@ public static void requestSubmitted(
107108
// populate span using details from the submitted HttpRequest (resolved URI, etc.)
108109
AgentSpan span = spanFromContext(scope.context());
109110
DECORATE.onRequest(span, TargetContext.getRequest(connection).getRequest());
111+
112+
// set peer info from the connection since request URIs are relative paths
113+
if (connection instanceof HttpInetConnection) {
114+
HttpInetConnection inetConn = (HttpInetConnection) connection;
115+
DECORATE.onPeerConnection(span, inetConn.getRemoteAddress());
116+
DECORATE.setPeerPort(span, inetConn.getRemotePort());
117+
}
110118
scope.close();
111119
}
112120
}

dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapsePassthruInstrumentation.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
44
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
5+
import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext;
6+
import static datadog.trace.instrumentation.synapse3.SynapseClientDecorator.SYNAPSE_CONTEXT_KEY;
57
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
68
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
79

810
import com.google.auto.service.AutoService;
11+
import datadog.context.Context;
912
import datadog.trace.agent.tooling.Instrumenter;
1013
import datadog.trace.agent.tooling.InstrumenterModule;
1114
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
@@ -14,6 +17,7 @@
1417
import java.util.Map;
1518
import net.bytebuddy.asm.Advice;
1619
import org.apache.axis2.context.MessageContext;
20+
import org.apache.http.nio.NHttpServerConnection;
1721

1822
/** Helps propagate parent spans over 'passthru' mechanism to synapse-client instrumentation. */
1923
@AutoService(InstrumenterModule.class)
@@ -53,10 +57,26 @@ public static void submit(@Advice.Argument(0) final MessageContext message) {
5357
}
5458
}
5559

56-
// use message context to propagate active spans across Synapse's 'passthru' mechanism
57-
AgentSpan span = activeSpan();
60+
// Propagate the server span to the client via the message context.
61+
// Prefer reading the span directly from the source connection's context (where
62+
// SynapseServerInstrumentation stored it) over activeSpan(). SourceHandler dispatches
63+
// request processing to a worker thread pool, and while java-concurrent instrumentation
64+
// normally propagates context across ThreadPoolExecutor, the connection-based lookup is
65+
// more robust as it doesn't depend on automatic context propagation.
66+
AgentSpan span = null;
67+
Object sourceConn = message.getProperty("pass-through.Source-Connection");
68+
if (sourceConn instanceof NHttpServerConnection) {
69+
Object ctx =
70+
((NHttpServerConnection) sourceConn).getContext().getAttribute(SYNAPSE_CONTEXT_KEY);
71+
if (ctx instanceof Context) {
72+
span = spanFromContext((Context) ctx);
73+
}
74+
}
75+
if (null == span) {
76+
span = activeSpan();
77+
}
5878
if (null != span) {
59-
message.setNonReplicableProperty("dd.trace.synapse.span", span);
79+
message.setNonReplicableProperty(SYNAPSE_CONTEXT_KEY, span);
6080
}
6181
}
6282
}

dd-java-agent/instrumentation/synapse-3.0/src/test/groovy/datadog/trace/instrumentation/synapse3/SynapseTest.groovy

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ abstract class SynapseTest extends VersionedNamingTestBase {
247247
"$Tags.SPAN_KIND" Tags.SPAN_KIND_SERVER
248248
"$Tags.PEER_HOST_IPV4" "127.0.0.1"
249249
"$Tags.PEER_PORT" Integer
250-
"$Tags.HTTP_URL" "/services/SimpleStockQuoteService"
250+
"$Tags.HTTP_URL" query ? "/services/SimpleStockQuoteService?${query}" : "/services/SimpleStockQuoteService"
251251
"$DDTags.HTTP_QUERY" query
252252
"$Tags.HTTP_METHOD" method
253253
"$Tags.HTTP_STATUS" statusCode
@@ -302,6 +302,9 @@ abstract class SynapseTest extends VersionedNamingTestBase {
302302
tags {
303303
"$Tags.COMPONENT" "synapse-client"
304304
"$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT
305+
"$Tags.PEER_HOSTNAME" String
306+
"$Tags.PEER_HOST_IPV4" "127.0.0.1"
307+
"$Tags.PEER_PORT" Integer
305308
"$Tags.HTTP_URL" "/services/SimpleStockQuoteService"
306309
"$Tags.HTTP_METHOD" method
307310
"$Tags.HTTP_STATUS" statusCode
@@ -311,7 +314,6 @@ abstract class SynapseTest extends VersionedNamingTestBase {
311314
}
312315
}
313316

314-
@Flaky("Occasionally times out when receiving traces")
315317
class SynapseV0ForkedTest extends SynapseTest implements TestingGenericHttpNamingConventions.ClientV0 {
316318

317319

@@ -321,7 +323,6 @@ class SynapseV0ForkedTest extends SynapseTest implements TestingGenericHttpNamin
321323
}
322324
}
323325

324-
@Flaky("Occasionally times out when receiving traces")
325326
class SynapseV1ForkedTest extends SynapseTest implements TestingGenericHttpNamingConventions.ClientV1 {
326327

327328
@Override

dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package datadog.smoketest
22

3+
import com.google.common.collect.ImmutableSet
34
import datadog.trace.agent.test.utils.PortUtils
45
import java.nio.file.Files
56
import java.nio.file.Paths
@@ -15,6 +16,7 @@ abstract class ProcessManager extends Specification {
1516
public static final String SERVICE_NAME = "smoke-test-java-app"
1617
public static final String ENV = "smoketest"
1718
public static final String VERSION = "99"
19+
public static final Set<String> NOISY_ENVIRONMENT_VARIABLES = ImmutableSet.of('CI_COMMIT_MESSAGE')
1820

1921
@Shared
2022
protected String buildDirectory = System.getProperty("datadog.smoketest.builddir")
@@ -77,8 +79,10 @@ abstract class ProcessManager extends Specification {
7779
(0..<numberOfProcesses).each { idx ->
7880
ProcessBuilder processBuilder = createProcessBuilder(idx)
7981

80-
processBuilder.environment().put("JAVA_HOME", System.getProperty("java.home"))
81-
processBuilder.environment().put("DD_API_KEY", apiKey())
82+
Map<String, String> env = processBuilder.environment()
83+
env.put("JAVA_HOME", System.getProperty("java.home"))
84+
env.put("DD_API_KEY", apiKey())
85+
muteNoisyEnvironmentVariables(env)
8286

8387
processBuilder.redirectErrorStream(true)
8488

@@ -191,6 +195,14 @@ abstract class ProcessManager extends Specification {
191195
|| line.contains("Failed to handle exception in instrumentation")
192196
}
193197

198+
/**
199+
* Some variable can be printed in smoke application logs and result into false-positive test result.
200+
* @param env environment variables to process.
201+
*/
202+
void muteNoisyEnvironmentVariables(Map<String, String> env) {
203+
env.keySet().removeAll(NOISY_ENVIRONMENT_VARIABLES)
204+
}
205+
194206
/**
195207
* Asserts that there are no errors printed by the application to the log.
196208
* This should usually be called after the process exits, otherwise it's not guaranteed that reading the log file will

dd-trace-core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ dependencies {
107107
testImplementation group: 'com.amazonaws', name: 'aws-lambda-java-events', version:'3.11.0'
108108
testImplementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.14.0'
109109
testImplementation libs.testcontainers
110+
testImplementation project(':utils:junit-utils')
110111

111112
traceAgentTestImplementation libs.testcontainers
112113
}

dd-trace-core/src/main/java/datadog/trace/core/LongRunningTracesTracker.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,14 @@ private void flushStats() {
139139
write = 0;
140140
expired = 0;
141141
}
142+
143+
// @VisibleForTesting
144+
int trackedCount() {
145+
return traceArray.size();
146+
}
147+
148+
// @VisibleForTesting
149+
int getDropped() {
150+
return dropped;
151+
}
142152
}

dd-trace-core/src/main/java/datadog/trace/core/PendingTrace.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,16 @@ boolean compareAndSetLongRunningState(int expected, int newState) {
223223
return LONG_RUNNING_STATE.compareAndSet(this, expected, newState);
224224
}
225225

226+
// @VisibleForTesting
227+
int getLongRunningTrackedState() {
228+
return longRunningTrackedState;
229+
}
230+
231+
// @VisibleForTesting
232+
void setLongRunningTrackedState(int state) {
233+
LONG_RUNNING_STATE.set(this, state);
234+
}
235+
226236
boolean empty() {
227237
return 0 >= COMPLETED_SPAN_COUNT.get(this) + PENDING_REFERENCE_COUNT.get(this);
228238
}

0 commit comments

Comments
 (0)