From 7dad3ef9d3a647c46de0b55fff469ee38f5460a8 Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Sun, 12 Jul 2026 21:38:03 +0100 Subject: [PATCH] Codebase consistency: call scope.close() before span.finish() Co-Authored-By: Claude Sonnet 4.6 --- AGENTS.md | 1 + .../AkkaHttpSingleRequestInstrumentation.java | 3 ++- .../akkahttp106/SingleRequestAdvice.java | 3 ++- .../ApacheHttpAsyncClientInstrumentation.java | 6 +++-- .../client/ClientCallImplInstrumentation.java | 18 ++++++++------ .../lambda/LambdaHandlerInstrumentation.java | 14 +++++------ .../cics/ECIInteractionInstrumentation.java | 7 +++--- .../JavaGatewayInterfaceInstrumentation.java | 2 +- .../cucumber/CucumberStepDecorator.java | 2 +- .../ExecutionContextInstrumentation.java | 8 +++---- .../datanucleus/JDOQueryInstrumentation.java | 2 +- .../JDOTransactionInstrumentation.java | 2 +- ...asticsearch5RestClientInstrumentation.java | 4 +++- ...asticsearch6RestClientInstrumentation.java | 4 +++- ...asticsearch7RestClientInstrumentation.java | 4 +++- ...search2TransportClientInstrumentation.java | 4 +++- ...search5TransportClientInstrumentation.java | 4 +++- ...earch53TransportClientInstrumentation.java | 4 +++- ...search6TransportClientInstrumentation.java | 4 +++- ...earch73TransportClientInstrumentation.java | 4 +++- .../finatra/FinatraInstrumentation.java | 2 +- .../instrumentation/finatra/Listener.java | 4 ++-- .../GoogleHttpClientInstrumentation.java | 11 +++++---- .../PublisherInstrumentation.java | 2 +- .../GrizzlyHttpHandlerInstrumentation.java | 4 +++- .../AsyncHttpClientInstrumentation.java | 4 +++- .../MessagesAvailableInstrumentation.java | 2 +- .../DistributedObjectInstrumentation.java | 6 +++-- .../ClientInvocationInstrumentation.java | 6 +++-- .../ClientListenerInstrumentation.java | 6 +---- .../hazelcast4/InvocationAdvice.java | 6 +++-- .../hibernate/SessionMethodUtils.java | 5 ++-- .../IgniteCacheAsyncInstrumentation.java | 24 +++++++++---------- .../httpclient/SendAsyncAdvice.java | 3 ++- .../jetty10/ServerHandleAdvice.java | 4 +++- .../jetty70/ServerHandleInstrumentation.java | 4 +++- .../jetty76/ServerHandleInstrumentation.java | 4 +++- .../jetty9/ServerHandleInstrumentation.java | 4 +++- .../KafkaConsumerInfoInstrumentation.java | 2 +- .../kafka_clients38/RecordsAdvice.java | 2 +- .../lettuce4/InstrumentationPoints.java | 6 ++++- .../OpensearchRestClientInstrumentation.java | 4 +++- ...nsearchTransportClientInstrumentation.java | 4 +++- ...PekkoHttpSingleRequestInstrumentation.java | 3 ++- .../playws1/PlayWSClientInstrumentation.java | 4 +++- .../playws2/PlayWSClientInstrumentation.java | 4 +++- .../playws21/PlayWSClientInstrumentation.java | 4 +++- .../QuartzSchedulingInstrumentation.java | 2 +- .../rabbitmq/amqp/RabbitDecorator.java | 2 +- .../rediscala/RediscalaInstrumentation.java | 3 ++- .../DefaultRequestContextInstrumentation.java | 2 +- .../JakartaRsAnnotationsInstrumentation.java | 6 +++-- .../DefaultRequestContextInstrumentation.java | 2 +- .../JaxRsAnnotationsInstrumentation.java | 6 +++-- .../instrumentation/rxjava3/RxJava3Test.java | 4 ++-- .../servlet3/Servlet3Advice.java | 12 ++++++---- .../SynapseServerWorkerInstrumentation.java | 2 +- .../tibcobw6/BehaviorInstrumentation.java | 10 +++++--- .../twilio/TwilioAsyncInstrumentation.java | 10 ++++---- .../HttpRequestParserInstrumentation.java | 2 +- docs/add_new_instrumentation.md | 4 ++-- docs/how_instrumentations_work.md | 7 ++++-- 62 files changed, 190 insertions(+), 118 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 69e6e48aac3..5b4057389f0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,6 +63,7 @@ docs/ Developer documentation (see below) - **Forked tests**: Use `ForkedTest` suffix when tests need a separate JVM - **Flaky tests**: Annotate with `@Flaky` — they are skipped in CI by default - **Instrumentation one-shot methods**: Never extract the return values of `triggerClasses()`, `contextStore()`, `classLoaderMatcher()`, or `methodAdvice()` into static constants. These are called once by the framework — extracting to a constant adds constant-pool bloat with no benefit. +- **Scope lifecycle order**: Keep the scope open until all work that needs the current active span is done — decorator calls, async callback registration, etc. Required order: decorator calls + callback registration → `scope.close()` → `span.finish()`. ## PR conventions diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java index 5b665068abd..56e14e2c513 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.0/src/main/java/datadog/trace/instrumentation/akkahttp/AkkaHttpSingleRequestInstrumentation.java @@ -98,12 +98,13 @@ public static void methodExit( if (throwable == null) { responseFuture.onComplete(new OnCompleteHandler(span), thiz.system().dispatcher()); + scope.close(); } else { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } - scope.close(); } } diff --git a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java index 4ea48bf5584..de14a16d057 100644 --- a/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java +++ b/dd-java-agent/instrumentation/akka/akka-http/akka-http-10.6/src/main/java11/datadog/trace/instrumentation/akkahttp106/SingleRequestAdvice.java @@ -44,11 +44,12 @@ public static void methodExit( if (throwable == null) { responseFuture.onComplete( new AkkaHttpClientHelpers.OnCompleteHandler(span), thiz.system().dispatcher()); + scope.close(); } else { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } - scope.close(); } } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java index 16aea977e5e..690a4833237 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/ApacheHttpAsyncClientInstrumentation.java @@ -142,15 +142,17 @@ public static void methodExit( if (scope == null) { return; } + final AgentSpan span = scope.span(); try { if (throwable != null) { - final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); } } finally { scope.close(); + if (throwable != null) { + span.finish(); + } } } } diff --git a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java index cde0edeaa10..58c84f37af1 100644 --- a/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java +++ b/dd-java-agent/instrumentation/armeria/armeria-grpc-0.84/src/main/java/datadog/trace/instrumentation/armeria/grpc/client/ClientCallImplInstrumentation.java @@ -122,12 +122,14 @@ public static void after( @Advice.Thrown Throwable error, @Advice.Local("$$ddSpan") AgentSpan span) throws Throwable { + if (null != error && null != span) { + DECORATE.onError(span, error); + DECORATE.beforeFinish(span); + } if (null != scope) { scope.close(); } if (null != error && null != span) { - DECORATE.onError(span, error); - DECORATE.beforeFinish(span); span.finish(); throw error; } @@ -210,8 +212,8 @@ public static void closeObserver( @Advice.Enter AgentScope scope, @Advice.Argument(0) Status status) { if (null != scope) { DECORATE.onClose(scope.span(), status); - scope.span().finish(); scope.close(); + scope.span().finish(); } } } @@ -238,15 +240,17 @@ public static void closeObserver( @Advice.Argument(0) Status status, @Advice.FieldValue("closed") boolean closed) { if (null != scope) { + AgentSpan span = null; if (closed) { - AgentSpan span = - InstrumentationContext.get(ClientCall.class, AgentSpan.class).remove(call); + span = InstrumentationContext.get(ClientCall.class, AgentSpan.class).remove(call); if (span != null) { DECORATE.onClose(span, status); - span.finish(); } } scope.close(); + if (span != null) { + span.finish(); + } } } } @@ -268,8 +272,8 @@ public static AgentScope before() { @Advice.OnMethodExit(onThrowable = Throwable.class) public static void after(@Advice.Enter AgentScope scope) { if (null != scope) { - scope.span().finish(); scope.close(); + scope.span().finish(); } } } diff --git a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java index ecf304f0ebc..cb8d369d51e 100644 --- a/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/src/main/java/datadog/trace/instrumentation/aws/v1/lambda/LambdaHandlerInstrumentation.java @@ -119,15 +119,12 @@ static void exit( CallDepthThreadLocalMap.reset(RequestHandler.class); + final AgentSpan span = scope.span(); try { - final AgentSpan span = scope.span(); - if (throwable != null) { - span.addThrowable(throwable); - } - String lambdaRequestId = awsContext.getAwsRequestId(); - if (throwable == null) { AgentTracer.get().notifyAppSecEnd(span, result); + } else { + span.addThrowable(throwable); } // Force the resource name back to the literal placeholder marker right // before finish so that the Datadog Lambda Extension's filter @@ -144,10 +141,11 @@ static void exit( // and the HTTP/JAX-RS instrumentation will already have written // HTTP_FRAMEWORK_ROUTE (3) by this point. span.setResourceName(INVOCATION_SPAN_NAME, ResourceNamePriorities.TAG_INTERCEPTOR); - span.finish(); - AgentTracer.get().notifyExtensionEnd(span, result, null != throwable, lambdaRequestId); } finally { scope.close(); + span.finish(); + AgentTracer.get() + .notifyExtensionEnd(span, result, null != throwable, awsContext.getAwsRequestId()); } } } diff --git a/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/ECIInteractionInstrumentation.java b/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/ECIInteractionInstrumentation.java index d65ac829fb7..c682bb4466a 100644 --- a/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/ECIInteractionInstrumentation.java +++ b/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/ECIInteractionInstrumentation.java @@ -50,10 +50,11 @@ public static void exit( CallDepthThreadLocalMap.decrementCallDepth(ECIInteraction.class); if (null != scope) { - DECORATE.onError(scope.span(), throwable); - DECORATE.beforeFinish(scope.span()); - scope.span().finish(); + AgentSpan span = scope.span(); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/JavaGatewayInterfaceInstrumentation.java b/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/JavaGatewayInterfaceInstrumentation.java index e7e6aca1129..2745576e4e5 100644 --- a/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/JavaGatewayInterfaceInstrumentation.java +++ b/dd-java-agent/instrumentation/cics-9.1/src/main/java/datadog/trace/instrumentation/cics/JavaGatewayInterfaceInstrumentation.java @@ -71,8 +71,8 @@ public static void exit( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/cucumber-5.4/src/main/java/datadog/trace/instrumentation/cucumber/CucumberStepDecorator.java b/dd-java-agent/instrumentation/cucumber-5.4/src/main/java/datadog/trace/instrumentation/cucumber/CucumberStepDecorator.java index 4e5ac4401af..f0ad990cead 100644 --- a/dd-java-agent/instrumentation/cucumber-5.4/src/main/java/datadog/trace/instrumentation/cucumber/CucumberStepDecorator.java +++ b/dd-java-agent/instrumentation/cucumber-5.4/src/main/java/datadog/trace/instrumentation/cucumber/CucumberStepDecorator.java @@ -44,7 +44,7 @@ public AgentScope onStepStart(StepDefinition step, Object[] arguments) { public void onStepFinish(AgentScope scope) { AgentSpan span = scope.span(); beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } diff --git a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/ExecutionContextInstrumentation.java b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/ExecutionContextInstrumentation.java index 573e51aff53..74518e0cee8 100644 --- a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/ExecutionContextInstrumentation.java +++ b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/ExecutionContextInstrumentation.java @@ -97,8 +97,8 @@ public static void endMethod( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } @@ -133,8 +133,8 @@ public static void endMethod( DECORATE.onOperation(span, entity); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } @@ -164,8 +164,8 @@ public static void endMethod( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } @@ -195,8 +195,8 @@ public static void endMethod( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOQueryInstrumentation.java b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOQueryInstrumentation.java index 1fec8683117..abd3fb76f1c 100644 --- a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOQueryInstrumentation.java +++ b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOQueryInstrumentation.java @@ -89,8 +89,8 @@ public static void endExecute( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOTransactionInstrumentation.java b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOTransactionInstrumentation.java index 196da352374..a3158a7d3c0 100644 --- a/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOTransactionInstrumentation.java +++ b/dd-java-agent/instrumentation/datanucleus-4.0.5/src/main/java/datadog/trace/instrumentation/datanucleus/JDOTransactionInstrumentation.java @@ -51,8 +51,8 @@ public static void end( DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java index 9691b5756f5..8ebc3b9e9e8 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5RestClientInstrumentation.java @@ -76,9 +76,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by RestResponseListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-6.4/src/main/java/datadog/trace/instrumentation/elasticsearch6_4/Elasticsearch6RestClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-6.4/src/main/java/datadog/trace/instrumentation/elasticsearch6_4/Elasticsearch6RestClientInstrumentation.java index c08d3807ef7..93fc4e3948f 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-6.4/src/main/java/datadog/trace/instrumentation/elasticsearch6_4/Elasticsearch6RestClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-6.4/src/main/java/datadog/trace/instrumentation/elasticsearch6_4/Elasticsearch6RestClientInstrumentation.java @@ -79,9 +79,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by RestResponseListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-7.0/src/main/java/datadog/trace/instrumentation/elasticsearch7/Elasticsearch7RestClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-7.0/src/main/java/datadog/trace/instrumentation/elasticsearch7/Elasticsearch7RestClientInstrumentation.java index 4ea559367ef..92430e40ec2 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-7.0/src/main/java/datadog/trace/instrumentation/elasticsearch7/Elasticsearch7RestClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-rest/elasticsearch-rest-7.0/src/main/java/datadog/trace/instrumentation/elasticsearch7/Elasticsearch7RestClientInstrumentation.java @@ -100,6 +100,7 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else if (result instanceof Response) { final AgentSpan span = scope.span(); @@ -107,11 +108,12 @@ public static void stopSpan( DECORATE.onResponse(span, ((Response) result)); } DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else { + scope.close(); // async call, span finished by RestResponseListener } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-2.0/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-2.0/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java index fdad25561bc..642366895fc 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-2.0/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-2.0/src/main/java/datadog/trace/instrumentation/elasticsearch2/Elasticsearch2TransportClientInstrumentation.java @@ -80,9 +80,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java index b2aa96eb1e3..831580a2363 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.0/src/main/java/datadog/trace/instrumentation/elasticsearch5/Elasticsearch5TransportClientInstrumentation.java @@ -80,9 +80,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.3/src/main/java/datadog/trace/instrumentation/elasticsearch5_3/Elasticsearch53TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.3/src/main/java/datadog/trace/instrumentation/elasticsearch5_3/Elasticsearch53TransportClientInstrumentation.java index 17e68319983..4fe2617d330 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.3/src/main/java/datadog/trace/instrumentation/elasticsearch5_3/Elasticsearch53TransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-5.3/src/main/java/datadog/trace/instrumentation/elasticsearch5_3/Elasticsearch53TransportClientInstrumentation.java @@ -81,9 +81,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-6.0/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-6.0/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java index 1ad02b44acd..14c81617e0b 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-6.0/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-6.0/src/main/java/datadog/trace/instrumentation/elasticsearch6/Elasticsearch6TransportClientInstrumentation.java @@ -84,9 +84,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-7.3/src/main/java/datadog/trace/instrumentation/elasticsearch7_3/Elasticsearch73TransportClientInstrumentation.java b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-7.3/src/main/java/datadog/trace/instrumentation/elasticsearch7_3/Elasticsearch73TransportClientInstrumentation.java index 2a07be66fb8..0dcb52a6d98 100644 --- a/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-7.3/src/main/java/datadog/trace/instrumentation/elasticsearch7_3/Elasticsearch73TransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/elasticsearch/elasticsearch-transport/elasticsearch-transport-7.3/src/main/java/datadog/trace/instrumentation/elasticsearch7_3/Elasticsearch73TransportClientInstrumentation.java @@ -91,9 +91,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/FinatraInstrumentation.java b/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/FinatraInstrumentation.java index 7d85528beec..37b198283b3 100644 --- a/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/FinatraInstrumentation.java +++ b/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/FinatraInstrumentation.java @@ -95,8 +95,8 @@ public static void setupCallback( if (throwable != null) { DECORATE.onError(span, throwable); DECORATE.beforeFinish(scope.context()); - span.finish(); scope.close(); + span.finish(); return; } diff --git a/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/Listener.java b/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/Listener.java index a1af31a3ebd..29c3723559d 100644 --- a/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/Listener.java +++ b/dd-java-agent/instrumentation/finatra-2.9/src/main/java/datadog/trace/instrumentation/finatra/Listener.java @@ -24,8 +24,8 @@ public void onSuccess(final Response response) { } DECORATE.beforeFinish(scope.context()); - span.finish(); scope.close(); + span.finish(); } @Override @@ -33,7 +33,7 @@ public void onFailure(final Throwable cause) { final AgentSpan span = AgentSpan.fromContext(scope.context()); DECORATE.onError(span, cause); DECORATE.beforeFinish(scope.context()); - span.finish(); scope.close(); + span.finish(); } } diff --git a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java index cdb871237f6..49aa12e67bc 100644 --- a/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/google-http-client-1.19/src/main/java/datadog/trace/instrumentation/googlehttpclient/GoogleHttpClientInstrumentation.java @@ -90,17 +90,16 @@ public static void methodExit( @Advice.Local("inherited") AgentSpan inheritedSpan, @Advice.Return final HttpResponse response, @Advice.Thrown final Throwable throwable) { + AgentSpan span = scope != null ? scope.span() : inheritedSpan; try { - AgentSpan span = scope != null ? scope.span() : inheritedSpan; DECORATE.onError(span, throwable); DECORATE.onResponse(span, response); - DECORATE.beforeFinish(span); - span.finish(); } finally { if (scope != null) { scope.close(); } + span.finish(); } } } @@ -116,15 +115,17 @@ public static AgentScope methodEnter(@Advice.This HttpRequest request) { @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( @Advice.Enter AgentScope scope, @Advice.Thrown final Throwable throwable) { + final AgentSpan span = scope.span(); try { if (throwable != null) { - AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); } } finally { scope.close(); + if (throwable != null) { + span.finish(); + } } } } diff --git a/dd-java-agent/instrumentation/google-pubsub-1.116/src/main/java/datadog/trace/instrumentation/googlepubsub/PublisherInstrumentation.java b/dd-java-agent/instrumentation/google-pubsub-1.116/src/main/java/datadog/trace/instrumentation/googlepubsub/PublisherInstrumentation.java index a746bcbcfdb..35f44420a64 100644 --- a/dd-java-agent/instrumentation/google-pubsub-1.116/src/main/java/datadog/trace/instrumentation/googlepubsub/PublisherInstrumentation.java +++ b/dd-java-agent/instrumentation/google-pubsub-1.116/src/main/java/datadog/trace/instrumentation/googlepubsub/PublisherInstrumentation.java @@ -57,8 +57,8 @@ public static void stopSpan( @Advice.Enter final AgentScope scope, @Advice.Thrown final Throwable throwable) { PRODUCER_DECORATE.onError(scope, throwable); PRODUCER_DECORATE.beforeFinish(scope); - scope.span().finish(); scope.close(); + scope.span().finish(); } } diff --git a/dd-java-agent/instrumentation/grizzly/grizzly-2.0/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java b/dd-java-agent/instrumentation/grizzly/grizzly-2.0/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java index 195f3ae10fd..447eb01ee98 100644 --- a/dd-java-agent/instrumentation/grizzly/grizzly-2.0/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly/grizzly-2.0/src/main/java/datadog/trace/instrumentation/grizzly/GrizzlyHttpHandlerInstrumentation.java @@ -113,9 +113,11 @@ public static void methodExit( final AgentSpan span = spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by SpanClosingListener if (skippedBody) { diff --git a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java index cc7931efdc9..30b38dbfeb9 100644 --- a/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java +++ b/dd-java-agent/instrumentation/grizzly/grizzly-client-1.9/src/main/java/datadog/trace/instrumentation/grizzly/client/AsyncHttpClientInstrumentation.java @@ -63,9 +63,11 @@ public static void onExit( AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); } } diff --git a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java index a967b00c170..e72ef5d5431 100644 --- a/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java +++ b/dd-java-agent/instrumentation/grpc-1.5/src/main/java/datadog/trace/instrumentation/grpc/client/MessagesAvailableInstrumentation.java @@ -67,8 +67,8 @@ public static AgentScope before() { @Advice.OnMethodExit(onThrowable = Throwable.class) public static void after(@Advice.Enter AgentScope scope) { if (null != scope) { - scope.span().finish(); scope.close(); + scope.span().finish(); } } } diff --git a/dd-java-agent/instrumentation/hazelcast/hazelcast-3.6/src/main/java/datadog/trace/instrumentation/hazelcast36/DistributedObjectInstrumentation.java b/dd-java-agent/instrumentation/hazelcast/hazelcast-3.6/src/main/java/datadog/trace/instrumentation/hazelcast36/DistributedObjectInstrumentation.java index 4f4399b01d8..0e52c21873c 100644 --- a/dd-java-agent/instrumentation/hazelcast/hazelcast-3.6/src/main/java/datadog/trace/instrumentation/hazelcast36/DistributedObjectInstrumentation.java +++ b/dd-java-agent/instrumentation/hazelcast/hazelcast-3.6/src/main/java/datadog/trace/instrumentation/hazelcast36/DistributedObjectInstrumentation.java @@ -278,16 +278,18 @@ public static void methodExit( final AgentSpan span = scope.span(); try { if (throwable != null) { - // There was an synchronous error, + // There was a synchronous error, // which means we shouldn't wait for a callback to close the span. DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); } else { future.andThen(new SpanFinishingExecutionCallback(span)); } } finally { scope.close(); + if (throwable != null) { + span.finish(); + } CallDepthThreadLocalMap.reset(DistributedObject.class); // reset call depth count } } diff --git a/dd-java-agent/instrumentation/hazelcast/hazelcast-3.9/src/main/java/datadog/trace/instrumentation/hazelcast39/ClientInvocationInstrumentation.java b/dd-java-agent/instrumentation/hazelcast/hazelcast-3.9/src/main/java/datadog/trace/instrumentation/hazelcast39/ClientInvocationInstrumentation.java index a3783b1fbb2..09d98e0ba39 100644 --- a/dd-java-agent/instrumentation/hazelcast/hazelcast-3.9/src/main/java/datadog/trace/instrumentation/hazelcast39/ClientInvocationInstrumentation.java +++ b/dd-java-agent/instrumentation/hazelcast/hazelcast-3.9/src/main/java/datadog/trace/instrumentation/hazelcast39/ClientInvocationInstrumentation.java @@ -93,16 +93,18 @@ public static void methodExit( final AgentSpan span = scope.span(); try { if (throwable != null) { - // There was an synchronous error, + // There was a synchronous error, // which means we shouldn't wait for a callback to close the span. DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); } else { future.andThen(new SpanFinishingExecutionCallback(span)); } } finally { scope.close(); + if (throwable != null) { + span.finish(); + } CallDepthThreadLocalMap.reset(ClientInvocation.class); // reset call depth count } } diff --git a/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/ClientListenerInstrumentation.java b/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/ClientListenerInstrumentation.java index d2b9df11b19..902f4e43696 100644 --- a/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/ClientListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/ClientListenerInstrumentation.java @@ -79,13 +79,9 @@ public static void methodExit( final AgentSpan span = scope.span(); try { if (throwable != null) { - // There was an synchronous error, - // which means we shouldn't wait for a callback to close the span. DECORATE.onError(span, throwable); - DECORATE.beforeFinish(span); - } else { - DECORATE.beforeFinish(span); } + DECORATE.beforeFinish(span); } finally { scope.close(); span.finish(); diff --git a/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/InvocationAdvice.java b/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/InvocationAdvice.java index facb9a4e8c4..3d1ae0d5381 100644 --- a/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/InvocationAdvice.java +++ b/dd-java-agent/instrumentation/hazelcast/hazelcast-4.0/src/main/java/datadog/trace/instrumentation/hazelcast4/InvocationAdvice.java @@ -62,16 +62,18 @@ public static void methodExit( final AgentSpan span = scope.span(); try { if (throwable != null) { - // There was an synchronous error, + // There was a synchronous error, // which means we shouldn't wait for a callback to close the span. DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); } else { future.whenComplete(new SpanFinishingExecutionCallback(span)); } } finally { scope.close(); + if (throwable != null) { + span.finish(); + } CallDepthThreadLocalMap.reset(ClientInvocation.class); // reset call depth count } } diff --git a/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/SessionMethodUtils.java b/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/SessionMethodUtils.java index ac81ce40f7b..e2e6751eb14 100644 --- a/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/SessionMethodUtils.java +++ b/dd-java-agent/instrumentation/hibernate/hibernate-common/src/main/java/datadog/trace/instrumentation/hibernate/SessionMethodUtils.java @@ -77,10 +77,11 @@ public static void closeScope( DECORATOR.onOperation(span, entity); } DECORATOR.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - - scope.close(); sessionState.setMethodScope(null); } diff --git a/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheAsyncInstrumentation.java b/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheAsyncInstrumentation.java index 7205216301c..9e61d594ae7 100644 --- a/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheAsyncInstrumentation.java +++ b/dd-java-agent/instrumentation/ignite-2.0/src/main/java/datadog/trace/instrumentation/ignite/v2/cache/IgniteCacheAsyncInstrumentation.java @@ -88,16 +88,14 @@ public static void stopSpan( if (scope == null) { return; } - // If we have a scope (i.e. we were the top-level Twilio SDK invocation), + // If we have a scope (i.e. we were the top-level Ignite SDK invocation), + final AgentSpan span = scope.span(); try { - final AgentSpan span = scope.span(); - if (throwable != null) { - // There was an synchronous error, + // There was a synchronous error, // which means we shouldn't wait for a callback to close the span. IgniteCacheDecorator.DECORATE.onError(span, throwable); IgniteCacheDecorator.DECORATE.beforeFinish(span); - span.finish(); } else { // We're calling an async operation, we still need to finish the span when it's // complete and report the results; set an appropriate callback @@ -105,7 +103,9 @@ public static void stopSpan( } } finally { scope.close(); - // span finished in SpanFinishingCallback + if (throwable != null) { + span.finish(); + } // else span finished in SpanFinishingCallback CallDepthThreadLocalMap.reset(IgniteCache.class); // reset call depth count } } @@ -143,16 +143,14 @@ public static void stopSpan( if (scope == null) { return; } - // If we have a scope (i.e. we were the top-level Twilio SDK invocation), + // If we have a scope (i.e. we were the top-level Ignite SDK invocation), + final AgentSpan span = scope.span(); try { - final AgentSpan span = scope.span(); - if (throwable != null) { - // There was an synchronous error, + // There was a synchronous error, // which means we shouldn't wait for a callback to close the span. IgniteCacheDecorator.DECORATE.onError(span, throwable); IgniteCacheDecorator.DECORATE.beforeFinish(span); - span.finish(); } else { // We're calling an async operation, we still need to finish the span when it's // complete and report the results; set an appropriate callback @@ -160,7 +158,9 @@ public static void stopSpan( } } finally { scope.close(); - // span finished in SpanFinishingCallback + if (throwable != null) { + span.finish(); + } // else span finished in SpanFinishingCallback CallDepthThreadLocalMap.reset(IgniteCache.class); // reset call depth count } } diff --git a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/SendAsyncAdvice.java b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/SendAsyncAdvice.java index 33b2ed9db21..a73c4c15722 100644 --- a/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/SendAsyncAdvice.java +++ b/dd-java-agent/instrumentation/java/java-net/java-net-11.0/src/main/java11/datadog/trace/instrumentation/httpclient/SendAsyncAdvice.java @@ -73,11 +73,12 @@ public static void methodExit( if (throwable != null) { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else { future = future.whenComplete(new ResponseConsumer(span)); + scope.close(); } - scope.close(); } } diff --git a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-10.0/src/main/java11/datadog/trace/instrumentation/jetty10/ServerHandleAdvice.java b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-10.0/src/main/java11/datadog/trace/instrumentation/jetty10/ServerHandleAdvice.java index b121af3f8eb..dab50c3e268 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-10.0/src/main/java11/datadog/trace/instrumentation/jetty10/ServerHandleAdvice.java +++ b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-10.0/src/main/java11/datadog/trace/instrumentation/jetty10/ServerHandleAdvice.java @@ -68,9 +68,11 @@ public static void onExit( // finish will be handled by the async listener // Use the full context from the scope for beforeFinish DECORATE.beforeFinish(scope.context()); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); synchronized (req) { req.removeAttribute(DD_DISPATCH_SPAN_ATTRIBUTE); diff --git a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.0/src/main/java/datadog/trace/instrumentation/jetty70/ServerHandleInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.0/src/main/java/datadog/trace/instrumentation/jetty70/ServerHandleInstrumentation.java index 0acc3649f3f..dd54d2b3677 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.0/src/main/java/datadog/trace/instrumentation/jetty70/ServerHandleInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.0/src/main/java/datadog/trace/instrumentation/jetty70/ServerHandleInstrumentation.java @@ -101,9 +101,11 @@ public static void onExit( // finish will be handled by the async listener // Use the full context from the scope for beforeFinish DECORATE.beforeFinish(scope.context()); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); synchronized (req) { req.removeAttribute(DD_DISPATCH_SPAN_ATTRIBUTE); diff --git a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.6/src/main/java/datadog/trace/instrumentation/jetty76/ServerHandleInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.6/src/main/java/datadog/trace/instrumentation/jetty76/ServerHandleInstrumentation.java index ae8515aec21..258b3f7ca33 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.6/src/main/java/datadog/trace/instrumentation/jetty76/ServerHandleInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-7.6/src/main/java/datadog/trace/instrumentation/jetty76/ServerHandleInstrumentation.java @@ -101,9 +101,11 @@ public static void onExit( // finish will be handled by the async listener // Use the full context from the scope for beforeFinish DECORATE.beforeFinish(scope.context()); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); synchronized (req) { req.removeAttribute(DD_DISPATCH_SPAN_ATTRIBUTE); diff --git a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-9.0/src/main/java/datadog/trace/instrumentation/jetty9/ServerHandleInstrumentation.java b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-9.0/src/main/java/datadog/trace/instrumentation/jetty9/ServerHandleInstrumentation.java index 590390d8404..fb5734fb85f 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-9.0/src/main/java/datadog/trace/instrumentation/jetty9/ServerHandleInstrumentation.java +++ b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-9.0/src/main/java/datadog/trace/instrumentation/jetty9/ServerHandleInstrumentation.java @@ -144,9 +144,11 @@ public static void onExit( // finish will be handled by the async listener // Use the full context from the scope for beforeFinish DECORATE.beforeFinish(scope.context()); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/kafka/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInfoInstrumentation.java b/dd-java-agent/instrumentation/kafka/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInfoInstrumentation.java index 1092d9b2a0c..0c63e413aab 100644 --- a/dd-java-agent/instrumentation/kafka/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInfoInstrumentation.java +++ b/dd-java-agent/instrumentation/kafka/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInfoInstrumentation.java @@ -281,8 +281,8 @@ public static void captureGroup( } AgentSpan span = scope.span(); span.setTag(KAFKA_RECORDS_COUNT, recordsCount); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/kafka/kafka-clients-3.8/src/main/java17/datadog/trace/instrumentation/kafka_clients38/RecordsAdvice.java b/dd-java-agent/instrumentation/kafka/kafka-clients-3.8/src/main/java17/datadog/trace/instrumentation/kafka_clients38/RecordsAdvice.java index 156c6d1f1fa..5254c40a775 100644 --- a/dd-java-agent/instrumentation/kafka/kafka-clients-3.8/src/main/java17/datadog/trace/instrumentation/kafka_clients38/RecordsAdvice.java +++ b/dd-java-agent/instrumentation/kafka/kafka-clients-3.8/src/main/java17/datadog/trace/instrumentation/kafka_clients38/RecordsAdvice.java @@ -70,7 +70,7 @@ public static void captureGroup( } AgentSpan span = scope.span(); span.setTag(KAFKA_RECORDS_COUNT, recordsCount); - span.finish(); scope.close(); + span.finish(); } } diff --git a/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/InstrumentationPoints.java b/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/InstrumentationPoints.java index 921696fb964..338222cfbc0 100644 --- a/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/InstrumentationPoints.java +++ b/dd-java-agent/instrumentation/lettuce/lettuce-4.0/src/main/java/datadog/trace/instrumentation/lettuce4/InstrumentationPoints.java @@ -52,8 +52,11 @@ public static void afterCommand( if (throwable != null) { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else if (expectsResponse(command)) { + // Register the callback before closing the scope so the active span is correct when + // the CompletableFuture instrumentation captures context for the finishing lambda. asyncCommand.handleAsync( (value, ex) -> { if (ex instanceof CancellationException) { @@ -65,12 +68,13 @@ public static void afterCommand( span.finish(); return null; }); + scope.close(); } else { // No response is expected, so we must finish the span now. DECORATE.beforeFinish(span); + scope.close(); span.finish(); } - scope.close(); // span may be finished by handleAsync call above. } diff --git a/dd-java-agent/instrumentation/opensearch/opensearch-rest-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientInstrumentation.java b/dd-java-agent/instrumentation/opensearch/opensearch-rest-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientInstrumentation.java index 5517d8ecc58..e6c900cad53 100644 --- a/dd-java-agent/instrumentation/opensearch/opensearch-rest-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientInstrumentation.java +++ b/dd-java-agent/instrumentation/opensearch/opensearch-rest-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchRestClientInstrumentation.java @@ -92,6 +92,7 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else if (result instanceof Response) { final AgentSpan span = scope.span(); @@ -99,11 +100,12 @@ public static void stopSpan( DECORATE.onResponse(span, ((Response) result)); } DECORATE.beforeFinish(span); + scope.close(); span.finish(); } else { + scope.close(); // async call, span finished by RestResponseListener } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/opensearch/opensearch-transport-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientInstrumentation.java b/dd-java-agent/instrumentation/opensearch/opensearch-transport-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientInstrumentation.java index 46c2a37a095..1ce9c01ba98 100644 --- a/dd-java-agent/instrumentation/opensearch/opensearch-transport-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientInstrumentation.java +++ b/dd-java-agent/instrumentation/opensearch/opensearch-transport-1.0/src/main/java/datadog/trace/instrumentation/opensearch/OpensearchTransportClientInstrumentation.java @@ -87,9 +87,11 @@ public static void stopSpan( final AgentSpan span = scope.span(); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); // span finished by TransportActionListener } } diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java index a8e30ecc03e..4625cdfe955 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java @@ -100,12 +100,13 @@ public static void methodExit( if (throwable == null) { responseFuture.onComplete(new OnCompleteHandler(span), thiz.system().dispatcher()); + scope.close(); } else { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } - scope.close(); } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java index f4ba89e314f..9f53b1fccc1 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-1.0/src/main/java/datadog/trace/instrumentation/playws1/PlayWSClientInstrumentation.java @@ -49,9 +49,11 @@ public static void methodExit( final AgentSpan span = spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java index 5336d5f8d28..1adf651e7e6 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.0/src/main/java/datadog/trace/instrumentation/playws2/PlayWSClientInstrumentation.java @@ -49,9 +49,11 @@ public static void methodExit( final AgentSpan span = spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java index a6dc7ccd11f..810dfdf35e4 100644 --- a/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java +++ b/dd-java-agent/instrumentation/play-ws/play-ws-2.1/src/main/java/datadog/trace/instrumentation/playws21/PlayWSClientInstrumentation.java @@ -49,9 +49,11 @@ public static void methodExit( final AgentSpan span = spanFromContext(scope.context()); DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/quartz-2.0/src/main/java/datadog/trace/instrumentation/quartz/QuartzSchedulingInstrumentation.java b/dd-java-agent/instrumentation/quartz-2.0/src/main/java/datadog/trace/instrumentation/quartz/QuartzSchedulingInstrumentation.java index c1291f15593..aa7993b8639 100644 --- a/dd-java-agent/instrumentation/quartz-2.0/src/main/java/datadog/trace/instrumentation/quartz/QuartzSchedulingInstrumentation.java +++ b/dd-java-agent/instrumentation/quartz-2.0/src/main/java/datadog/trace/instrumentation/quartz/QuartzSchedulingInstrumentation.java @@ -71,8 +71,8 @@ public static void onExit( DECORATE.onError(span, throwable); } DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/rabbitmq-amqp-2.7/src/main/java/datadog/trace/instrumentation/rabbitmq/amqp/RabbitDecorator.java b/dd-java-agent/instrumentation/rabbitmq-amqp-2.7/src/main/java/datadog/trace/instrumentation/rabbitmq/amqp/RabbitDecorator.java index 8f8a734cf13..e73bf99c34a 100644 --- a/dd-java-agent/instrumentation/rabbitmq-amqp-2.7/src/main/java/datadog/trace/instrumentation/rabbitmq/amqp/RabbitDecorator.java +++ b/dd-java-agent/instrumentation/rabbitmq-amqp-2.7/src/main/java/datadog/trace/instrumentation/rabbitmq/amqp/RabbitDecorator.java @@ -268,12 +268,12 @@ public static AgentScope startReceivingSpan( public static void finishReceivingSpan(AgentScope scope) { AgentSpan span = scope.span(); + scope.close(); if (CONSUMER_DECORATE.endToEndDurationsEnabled) { span.finishWithEndToEnd(); } else { span.finish(); } - scope.close(); } public static final String RABBITMQ_PRODUCED_KEY = "x_datadog_rabbitmq_produced"; diff --git a/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaInstrumentation.java b/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaInstrumentation.java index c15bcd370e4..0dd5e434c21 100644 --- a/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaInstrumentation.java +++ b/dd-java-agent/instrumentation/rediscala-1.8/src/main/java/datadog/trace/instrumentation/rediscala/RediscalaInstrumentation.java @@ -107,6 +107,7 @@ public static void stopSpan( } if (throwable == null) { responseFuture.onComplete(new OnCompleteHandler(contextStore, connection), ctx); + scope.close(); } else { if (connection != null) { // try to get the info early @@ -114,9 +115,9 @@ public static void stopSpan( } DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); + scope.close(); span.finish(); } - scope.close(); // span finished in OnCompleteHandler } } diff --git a/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/DefaultRequestContextInstrumentation.java b/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/DefaultRequestContextInstrumentation.java index 5a189597b64..ec65e37549e 100644 --- a/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/DefaultRequestContextInstrumentation.java +++ b/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/DefaultRequestContextInstrumentation.java @@ -73,8 +73,8 @@ public static void stopSpan( } DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/JakartaRsAnnotationsInstrumentation.java b/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/JakartaRsAnnotationsInstrumentation.java index ea72c70ee17..d7fbe26311d 100644 --- a/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/JakartaRsAnnotationsInstrumentation.java +++ b/dd-java-agent/instrumentation/rs/jakarta-rs-annotations-3.0/src/main/java/datadog/trace/instrumentation/jakarta3/JakartaRsAnnotationsInstrumentation.java @@ -144,8 +144,8 @@ public static void stopSpan( if (throwable != null) { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); return; } @@ -155,10 +155,12 @@ public static void stopSpan( } if (asyncResponse == null || !asyncResponse.isSuspended()) { DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } // else span finished by AsyncResponseAdvice - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/DefaultRequestContextInstrumentation.java b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/DefaultRequestContextInstrumentation.java index 4c9b3098967..8dc0da68fbd 100644 --- a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/DefaultRequestContextInstrumentation.java +++ b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/DefaultRequestContextInstrumentation.java @@ -72,8 +72,8 @@ public static void stopSpan( } DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); } } } diff --git a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsInstrumentation.java b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsInstrumentation.java index 5fe95a54c64..963637e91f8 100644 --- a/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsInstrumentation.java +++ b/dd-java-agent/instrumentation/rs/jax-rs/jax-rs-annotations/jax-rs-annotations-2.0/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsInstrumentation.java @@ -151,8 +151,8 @@ public static void stopSpan( if (throwable != null) { DECORATE.onError(span, throwable); DECORATE.beforeFinish(span); - span.finish(); scope.close(); + span.finish(); return; } @@ -162,10 +162,12 @@ public static void stopSpan( } if (asyncResponse == null || !asyncResponse.isSuspended()) { DECORATE.beforeFinish(span); + scope.close(); span.finish(); + } else { + scope.close(); } // else span finished by AsyncResponseAdvice - scope.close(); } } } diff --git a/dd-java-agent/instrumentation/rxjava/rxjava-3.0/src/test/java/testdog/trace/instrumentation/rxjava3/RxJava3Test.java b/dd-java-agent/instrumentation/rxjava/rxjava-3.0/src/test/java/testdog/trace/instrumentation/rxjava3/RxJava3Test.java index e9bef9e2068..698005dca0c 100644 --- a/dd-java-agent/instrumentation/rxjava/rxjava-3.0/src/test/java/testdog/trace/instrumentation/rxjava3/RxJava3Test.java +++ b/dd-java-agent/instrumentation/rxjava/rxjava-3.0/src/test/java/testdog/trace/instrumentation/rxjava3/RxJava3Test.java @@ -95,8 +95,8 @@ static Object assemblePublisherUnderTrace(Supplier publisherSupplier) { } throw new RuntimeException("Unknown publisher: " + publisher); } finally { - span.finish(); scope.close(); + span.finish(); } } @@ -509,8 +509,8 @@ void correctParentsFromSubscriptionTime(String name, int workItems, Supplier