Skip to content

Commit 516cb80

Browse files
authored
Migrate certain instrumentations to use closeActive() to close outstanding spans (#8503)
* Migrate CI-Vis to use closeActive() to close outstanding spans * Migrate AWS SDKv1 to use closeActive() to close outstanding spans * Migrate Karate to use closeActive() to close outstanding spans * Migrate Undertow to use closeActive() to close outstanding spans * Migrate AWS SDKv2 to use closeActive() to close outstanding spans * Update Google HttpClient to avoid activeScope()
1 parent 039404d commit 516cb80

File tree

8 files changed

+75
-79
lines changed

8 files changed

+75
-79
lines changed

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestImpl.java

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import datadog.trace.api.civisibility.telemetry.tag.SkipReason;
3030
import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation;
3131
import datadog.trace.api.gateway.RequestContextSlot;
32-
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
3332
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
3433
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
3534
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -230,23 +229,22 @@ public void setSkipReason(String skipReason) {
230229
public void end(@Nullable Long endTime) {
231230
closeOutstandingSpans();
232231

233-
final AgentScope scope = AgentTracer.activeScope();
234-
if (scope == null) {
232+
final AgentSpan activeSpan = AgentTracer.activeSpan();
233+
if (activeSpan == null) {
235234
throw new IllegalStateException(
236-
"No active scope present, it is possible that end() was called multiple times");
235+
"No active span present, it is possible that end() was called multiple times");
237236
}
238237

239-
AgentSpan scopeSpan = scope.span();
240-
if (scopeSpan != span) {
238+
if (activeSpan != this.span) {
241239
throw new IllegalStateException(
242-
"Active scope does not correspond to the finished test, "
240+
"Active span does not correspond to the finished test, "
243241
+ "it is possible that end() was called multiple times "
244242
+ "or an operation that was started by the test is still in progress; "
245-
+ "active scope span is: "
246-
+ scopeSpan
243+
+ "active span is: "
244+
+ activeSpan
247245
+ "; "
248246
+ "expected span is: "
249-
+ span);
247+
+ this.span);
250248
}
251249

252250
InstrumentationTestBridge.fireBeforeTestEnd(context);
@@ -263,7 +261,7 @@ public void end(@Nullable Long endTime) {
263261
}
264262
}
265263

266-
scope.close();
264+
AgentTracer.closeActive();
267265

268266
onSpanFinish.accept(span);
269267

@@ -310,18 +308,17 @@ public void end(@Nullable Long endTime) {
310308
* spans stack until it encounters a CI Visibility span or the stack is empty.
311309
*/
312310
private void closeOutstandingSpans() {
313-
AgentScope scope;
314-
while ((scope = AgentTracer.activeScope()) != null) {
315-
AgentSpan span = scope.span();
311+
AgentSpan activeSpan;
312+
while ((activeSpan = AgentTracer.activeSpan()) != null) {
316313

317-
if (span == this.span || span.getTag(Tags.TEST_SESSION_ID) != null) {
314+
if (activeSpan == this.span || activeSpan.getTag(Tags.TEST_SESSION_ID) != null) {
318315
// encountered this span or another CI Visibility span (test, suite, module, session)
319316
break;
320317
}
321318

322-
log.debug("Closing outstanding span: {}", span);
323-
scope.close();
324-
span.finish();
319+
log.debug("Closing outstanding span: {}", activeSpan);
320+
AgentTracer.closeActive();
321+
activeSpan.finish();
325322
}
326323
}
327324
}

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestSuiteImpl.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector;
1212
import datadog.trace.api.civisibility.telemetry.tag.EventType;
1313
import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation;
14-
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
1514
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
1615
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
1716
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -193,26 +192,25 @@ public void setSkipReason(String skipReason) {
193192
@Override
194193
public void end(@Nullable Long endTime) {
195194
if (!parallelized) {
196-
final AgentScope scope = AgentTracer.activeScope();
197-
if (scope == null) {
195+
final AgentSpan activeSpan = AgentTracer.activeSpan();
196+
if (activeSpan == null) {
198197
throw new IllegalStateException(
199-
"No active scope present, it is possible that end() was called multiple times");
198+
"No active span present, it is possible that end() was called multiple times");
200199
}
201200

202-
AgentSpan scopeSpan = scope.span();
203-
if (scopeSpan != span) {
201+
if (activeSpan != this.span) {
204202
throw new IllegalStateException(
205-
"Active scope does not correspond to the finished suite, "
203+
"Active span does not correspond to the finished suite, "
206204
+ "it is possible that end() was called multiple times "
207205
+ "or an operation that was started by the suite is still in progress; "
208-
+ "active scope span is: "
209-
+ scopeSpan
206+
+ "active span is: "
207+
+ activeSpan
210208
+ "; "
211209
+ "expected span is: "
212-
+ span);
210+
+ this.span);
213211
}
214212

215-
scope.close();
213+
AgentTracer.closeActive();
216214
}
217215

218216
onSpanFinish.accept(span);

dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/AWSHttpClientInstrumentation.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package datadog.trace.instrumentation.aws.v0;
22

33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
4+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
5+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closeActive;
56
import static datadog.trace.instrumentation.aws.v0.OnErrorDecorator.DECORATE;
67
import static datadog.trace.instrumentation.aws.v0.OnErrorDecorator.SPAN_CONTEXT_KEY;
78
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@@ -10,7 +11,6 @@
1011
import com.amazonaws.Request;
1112
import com.amazonaws.handlers.RequestHandler2;
1213
import datadog.trace.agent.tooling.Instrumenter;
13-
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
1414
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
1515
import net.bytebuddy.asm.Advice;
1616

@@ -45,12 +45,12 @@ public static void methodExit(
4545
@Advice.Argument(value = 0, optional = true) final Request<?> request,
4646
@Advice.Thrown final Throwable throwable) {
4747

48-
final AgentScope scope = activeScope();
48+
final AgentSpan activeSpan = activeSpan();
4949
// check name in case TracingRequestHandler failed to activate the span
50-
if (scope != null
51-
&& (AwsNameCache.spanName(request).equals(scope.span().getSpanName())
52-
|| !scope.span().isValid())) {
53-
scope.close();
50+
if (activeSpan != null
51+
&& (AwsNameCache.spanName(request).equals(activeSpan.getSpanName())
52+
|| !activeSpan.isValid())) {
53+
closeActive();
5454
}
5555

5656
if (throwable != null && request != null) {

dd-java-agent/instrumentation/aws-java-sdk-1.11.0/src/main/java/datadog/trace/instrumentation/aws/v0/RequestExecutorInstrumentation.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package datadog.trace.instrumentation.aws.v0;
22

33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
4+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
5+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closeActive;
56
import static datadog.trace.instrumentation.aws.v0.OnErrorDecorator.DECORATE;
67
import static datadog.trace.instrumentation.aws.v0.OnErrorDecorator.SPAN_CONTEXT_KEY;
78
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
89

910
import com.amazonaws.Request;
1011
import datadog.trace.agent.tooling.Instrumenter;
11-
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
1212
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
1313
import net.bytebuddy.asm.Advice;
1414

@@ -42,12 +42,12 @@ public static void methodExit(
4242
@Advice.FieldValue("request") final Request<?> request,
4343
@Advice.Thrown final Throwable throwable) {
4444

45-
final AgentScope scope = activeScope();
45+
final AgentSpan activeSpan = activeSpan();
4646
// check name in case TracingRequestHandler failed to activate the span
47-
if (scope != null
48-
&& (AwsNameCache.spanName(request).equals(scope.span().getSpanName())
49-
|| !scope.span().isValid())) {
50-
scope.close();
47+
if (activeSpan != null
48+
&& (AwsNameCache.spanName(request).equals(activeSpan.getSpanName())
49+
|| !activeSpan.isValid())) {
50+
closeActive();
5151
}
5252

5353
if (throwable != null) {

dd-java-agent/instrumentation/aws-java-sdk-2.2/src/main/java/datadog/trace/instrumentation/aws/v2/AwsHttpClientInstrumentation.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
66
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf;
77
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
8-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
8+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
9+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closeActive;
910
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopSpan;
1011
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
1112
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
@@ -14,7 +15,9 @@
1415
import com.google.auto.service.AutoService;
1516
import datadog.trace.agent.tooling.Instrumenter;
1617
import datadog.trace.agent.tooling.InstrumenterModule;
17-
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
18+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
19+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
20+
import datadog.trace.context.TraceScope;
1821
import net.bytebuddy.asm.Advice;
1922
import net.bytebuddy.description.type.TypeDescription;
2023
import net.bytebuddy.matcher.ElementMatcher;
@@ -69,27 +72,29 @@ public static class AwsHttpClientAdvice {
6972
* stored in channel attributes.
7073
*/
7174
@Advice.OnMethodEnter(suppress = Throwable.class)
72-
public static AgentScope methodEnter(
75+
public static TraceScope methodEnter(
7376
@Advice.This final Object thiz,
7477
@Advice.Argument(1) final RequestExecutionContext requestExecutionContext) {
75-
final AgentScope scope = activeScope();
78+
final AgentSpan activeSpan = activeSpan();
7679
// check name in case TracingExecutionInterceptor failed to activate the span
77-
if (scope != null
78-
&& ((!scope.span().isValid())
80+
if (activeSpan != null
81+
&& ((!activeSpan.isValid())
7982
|| AwsSdkClientDecorator.DECORATE
8083
.spanName(requestExecutionContext.executionAttributes())
81-
.equals(scope.span().getSpanName()))) {
84+
.equals(activeSpan.getSpanName()))) {
8285
if (thiz instanceof MakeAsyncHttpRequestStage) {
83-
scope.close(); // close async legacy HTTP span to avoid Netty leak
86+
// close async legacy HTTP span to avoid Netty leak...
87+
closeActive(); // then drop-through and activate no-op span
8488
} else {
85-
return scope; // keep sync legacy HTTP span alive for duration of call
89+
// keep sync legacy HTTP span alive for duration of call
90+
return AgentTracer::closeActive;
8691
}
8792
}
8893
return activateSpan(noopSpan());
8994
}
9095

9196
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
92-
public static void methodExit(@Advice.Enter final AgentScope scope) {
97+
public static void methodExit(@Advice.Enter final TraceScope scope) {
9398
scope.close();
9499
}
95100

dd-java-agent/instrumentation/google-http-client/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
44
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
5-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
5+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
66
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan;
77
import static datadog.trace.instrumentation.googlehttpclient.GoogleHttpClientDecorator.DECORATE;
88
import static datadog.trace.instrumentation.googlehttpclient.GoogleHttpClientDecorator.HTTP_REQUEST;
@@ -60,17 +60,16 @@ public void methodAdvice(MethodTransformer transformer) {
6060
public static class GoogleHttpClientAdvice {
6161
@Advice.OnMethodEnter(suppress = Throwable.class)
6262
public static AgentScope methodEnter(
63-
@Advice.This HttpRequest request, @Advice.Local("inherited") boolean inheritedScope) {
64-
AgentScope scope = activeScope();
65-
// detect if scope was propagated here by java-concurrent handling
63+
@Advice.This HttpRequest request, @Advice.Local("inherited") AgentSpan inheritedSpan) {
64+
AgentSpan activeSpan = activeSpan();
65+
// detect if span was propagated here by java-concurrent handling
6666
// of async requests
67-
if (null != scope) {
68-
AgentSpan span = scope.span();
67+
if (null != activeSpan) {
6968
// reference equality to check this instrumentation created the span,
7069
// not some other HTTP client
71-
if (HTTP_REQUEST == span.getOperationName()) {
72-
inheritedScope = true;
73-
return scope;
70+
if (HTTP_REQUEST == activeSpan.getOperationName()) {
71+
inheritedSpan = activeSpan;
72+
return null;
7473
}
7574
}
7675
return activateSpan(DECORATE.prepareSpan(startSpan(HTTP_REQUEST), request));
@@ -79,18 +78,18 @@ public static AgentScope methodEnter(
7978
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
8079
public static void methodExit(
8180
@Advice.Enter AgentScope scope,
82-
@Advice.Local("inherited") boolean inheritedScope,
81+
@Advice.Local("inherited") AgentSpan inheritedSpan,
8382
@Advice.Return final HttpResponse response,
8483
@Advice.Thrown final Throwable throwable) {
8584
try {
86-
AgentSpan span = scope.span();
85+
AgentSpan span = scope != null ? scope.span() : inheritedSpan;
8786
DECORATE.onError(span, throwable);
8887
DECORATE.onResponse(span, response);
8988

9089
DECORATE.beforeFinish(span);
9190
span.finish();
9291
} finally {
93-
if (!inheritedScope) {
92+
if (scope != null) {
9493
scope.close();
9594
}
9695
}

dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateTracingHook.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,7 @@ public void afterStep(StepResult result, ScenarioRuntime sr) {
221221
return;
222222
}
223223

224-
AgentScope scope = AgentTracer.activeScope();
225-
if (scope != null) {
226-
scope.close();
227-
}
228-
224+
AgentTracer.closeActive();
229225
span.finish();
230226
}
231227

dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/HttpRequestParserInstrumentation.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass;
44
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
55
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
6-
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
6+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
7+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.closeActive;
78
import static datadog.trace.instrumentation.undertow.UndertowDecorator.DECORATE;
89
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
910
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
@@ -71,12 +72,10 @@ public static void afterRequestParse(
7172
// a span
7273
// this because undertow will just write down a http 400 raw response over the net channel.
7374
// Here we try to create a span to record this
74-
AgentScope scope = activeScope();
75-
AgentSpan span = null;
75+
AgentSpan span = activeSpan();
76+
AgentScope scope = null;
7677
try {
77-
if (scope != null) {
78-
span = scope.span();
79-
} else {
78+
if (span == null) {
8079
final AgentSpanContext.Extracted extractedContext = DECORATE.extract(exchange);
8180
span = DECORATE.startSpan(exchange, extractedContext).setMeasured(true);
8281
scope = activateSpan(span);
@@ -90,9 +89,11 @@ public static void afterRequestParse(
9089
} finally {
9190
if (span != null) {
9291
span.finish();
93-
}
94-
if (scope != null) {
95-
scope.close();
92+
if (scope != null) {
93+
scope.close();
94+
} else {
95+
closeActive();
96+
}
9697
}
9798
}
9899
}

0 commit comments

Comments
 (0)