Skip to content

Commit 2ea27b2

Browse files
authored
End span after closing scope (#12952)
1 parent 1a506cb commit 2ea27b2

File tree

30 files changed

+138
-152
lines changed

30 files changed

+138
-152
lines changed

docs/contributing/using-instrumenter-api.md

+8-6
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@ Response decoratedMethod(Request request) {
8484
}
8585

8686
Context context = instrumenter.start(parentContext, request);
87+
Response response;
8788
try (Scope scope = context.makeCurrent()) {
88-
Response response = actualMethod(request);
89-
instrumenter.end(context, request, response, null);
90-
return response;
91-
} catch (Throwable error) {
92-
instrumenter.end(context, request, null, error);
93-
throw error;
89+
response = actualMethod(request);
90+
} catch (Throwable t) {
91+
instrumenter.end(context, request, null, t);
92+
throw t;
9493
}
94+
// calling end after the scope is closed is a best practice
95+
instrumenter.end(context, request, response, null);
96+
return response;
9597
}
9698
```
9799

instrumentation/apache-httpclient/apache-httpclient-4.3/library/src/main/java/io/opentelemetry/instrumentation/apachehttpclient/v4_3/TracingProtocolExec.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,14 @@ private CloseableHttpResponse execute(
8989
HttpExecutionAware httpExecutionAware,
9090
Context context)
9191
throws IOException, HttpException {
92-
CloseableHttpResponse response = null;
93-
Throwable error = null;
92+
CloseableHttpResponse response;
9493
try (Scope ignored = context.makeCurrent()) {
9594
response = exec.execute(route, request, httpContext, httpExecutionAware);
96-
return response;
97-
} catch (Throwable e) {
98-
error = e;
99-
throw e;
100-
} finally {
101-
instrumenter.end(context, instrumenterRequest, response, error);
95+
} catch (Throwable t) {
96+
instrumenter.end(context, instrumenterRequest, null, t);
97+
throw t;
10298
}
99+
instrumenter.end(context, instrumenterRequest, response, null);
100+
return response;
103101
}
104102
}

instrumentation/elasticsearch/elasticsearch-rest-7.0/library/src/main/java/io/opentelemetry/instrumentation/elasticsearch/rest/v7_0/RestClientWrapper.java

+13-19
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,18 @@ private static Class<?> createProxyClass() {
6767
return method.invoke(target, args);
6868
}
6969

70-
Response response = null;
71-
Throwable throwable = null;
7270
Context context = instrumenter.start(parentContext, otelRequest);
73-
try (Scope scope = context.makeCurrent()) {
71+
72+
Response response;
73+
try (Scope ignored = context.makeCurrent()) {
7474
response = (Response) method.invoke(target, args);
75-
} catch (Throwable exception) {
76-
throwable = exception;
77-
throw throwable;
78-
} finally {
79-
instrumenter.end(context, otelRequest, response, throwable);
75+
} catch (Throwable t) {
76+
instrumenter.end(context, otelRequest, null, t);
77+
throw t;
8078
}
81-
79+
instrumenter.end(context, otelRequest, response, null);
8280
return response;
81+
8382
} else if ("performRequestAsync".equals(method.getName())
8483
&& args.length == 2
8584
&& args[0] instanceof Request
@@ -94,22 +93,17 @@ private static Class<?> createProxyClass() {
9493
return method.invoke(target, args);
9594
}
9695

97-
Throwable throwable = null;
9896
Context context = instrumenter.start(parentContext, otelRequest);
9997
args[1] =
10098
new RestResponseListener(
10199
responseListener, parentContext, instrumenter, context, otelRequest);
102-
try (Scope scope = context.makeCurrent()) {
100+
try (Scope ignored = context.makeCurrent()) {
103101
return method.invoke(target, args);
104-
} catch (Throwable exception) {
105-
throwable = exception;
106-
throw throwable;
107-
} finally {
108-
if (throwable != null) {
109-
instrumenter.end(context, otelRequest, null, throwable);
110-
}
111-
// span ended in RestResponseListener
102+
} catch (Throwable t) {
103+
instrumenter.end(context, otelRequest, null, t);
104+
throw t;
112105
}
106+
// span ended in RestResponseListener
113107
}
114108

115109
// delegate to wrapped RestClient

instrumentation/grpc-1.6/library/src/main/java/io/opentelemetry/instrumentation/grpc/v1_6/TracingClientInterceptor.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,11 @@ public <REQUEST, RESPONSE> ClientCall<REQUEST, RESPONSE> interceptCall(
5858
Context context = instrumenter.start(parentContext, request);
5959
ClientCall<REQUEST, RESPONSE> result;
6060
try (Scope ignored = context.makeCurrent()) {
61-
try {
62-
// call other interceptors
63-
result = next.newCall(method, callOptions);
64-
} catch (Throwable e) {
65-
instrumenter.end(context, request, Status.UNKNOWN, e);
66-
throw e;
67-
}
61+
// call other interceptors
62+
result = next.newCall(method, callOptions);
63+
} catch (Throwable t) {
64+
instrumenter.end(context, request, Status.UNKNOWN, t);
65+
throw t;
6866
}
6967

7068
return new TracingClientCall<>(result, parentContext, context, request);

instrumentation/java-http-client/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/httpclient/HttpHeadersInstrumentation.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
1212
import static net.bytebuddy.matcher.ElementMatchers.named;
1313

14+
import io.opentelemetry.context.Context;
1415
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1516
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1617
import java.net.http.HttpHeaders;
@@ -39,7 +40,7 @@ public static class HeadersAdvice {
3940

4041
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
4142
public static void methodExit(@Advice.Return(readOnly = false) HttpHeaders headers) {
42-
headers = setter().inject(headers);
43+
headers = setter().inject(headers, Context.current());
4344
}
4445
}
4546
}

instrumentation/java-http-client/library/src/main/java/io/opentelemetry/instrumentation/httpclient/internal/HttpHeadersSetter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public HttpHeadersSetter(ContextPropagators contextPropagators) {
2525
this.contextPropagators = contextPropagators;
2626
}
2727

28-
public HttpHeaders inject(HttpHeaders original) {
28+
public HttpHeaders inject(HttpHeaders original, Context context) {
2929
Map<String, List<String>> headerMap = new HashMap<>(original.map());
3030

3131
contextPropagators
3232
.getTextMapPropagator()
3333
.inject(
34-
Context.current(),
34+
context,
3535
headerMap,
3636
(carrier, key, value) -> {
3737
if (carrier != null) {

instrumentation/java-http-client/library/src/main/java/io/opentelemetry/instrumentation/httpclient/internal/OpenTelemetryHttpClient.java

+19-22
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,17 @@ public <T> HttpResponse<T> send(
9595
return client.send(request, responseBodyHandler);
9696
}
9797

98-
HttpResponse<T> response = null;
99-
Throwable error = null;
10098
Context context = instrumenter.start(parentContext, request);
99+
HttpRequestWrapper requestWrapper =
100+
new HttpRequestWrapper(request, headersSetter.inject(request.headers(), context));
101+
HttpResponse<T> response;
101102
try (Scope ignore = context.makeCurrent()) {
102-
HttpRequestWrapper requestWrapper =
103-
new HttpRequestWrapper(request, headersSetter.inject(request.headers()));
104-
105103
response = client.send(requestWrapper, responseBodyHandler);
106-
} catch (Throwable throwable) {
107-
error = throwable;
108-
throw throwable;
109-
} finally {
110-
instrumenter.end(context, request, response, error);
104+
} catch (Throwable t) {
105+
instrumenter.end(context, request, null, t);
106+
throw t;
111107
}
112-
108+
instrumenter.end(context, request, response, null);
113109
return response;
114110
}
115111

@@ -136,17 +132,18 @@ private <T> CompletableFuture<HttpResponse<T>> traceAsync(
136132
}
137133

138134
Context context = instrumenter.start(parentContext, request);
139-
try (Scope ignore = context.makeCurrent()) {
140-
HttpRequestWrapper requestWrapper =
141-
new HttpRequestWrapper(request, headersSetter.inject(request.headers()));
142-
143-
CompletableFuture<HttpResponse<T>> future = action.apply(requestWrapper);
144-
future = future.whenComplete(new ResponseConsumer(instrumenter, context, request));
145-
future = CompletableFutureWrapper.wrap(future, parentContext);
146-
return future;
147-
} catch (Throwable throwable) {
148-
instrumenter.end(context, request, null, throwable);
149-
throw throwable;
135+
HttpRequestWrapper requestWrapper =
136+
new HttpRequestWrapper(request, headersSetter.inject(request.headers(), context));
137+
138+
CompletableFuture<HttpResponse<T>> future;
139+
try (Scope ignored = context.makeCurrent()) {
140+
future = action.apply(requestWrapper);
141+
} catch (Throwable t) {
142+
instrumenter.end(context, request, null, t);
143+
throw t;
150144
}
145+
future = future.whenComplete(new ResponseConsumer(instrumenter, context, request));
146+
future = CompletableFutureWrapper.wrap(future, parentContext);
147+
return future;
151148
}
152149
}

instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/KafkaTelemetry.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,10 @@ <K, V> Future<RecordMetadata> buildAndInjectSpan(
252252
}
253253

254254
Context context = producerInstrumenter.start(parentContext, request);
255+
propagator().inject(context, record.headers(), SETTER);
256+
255257
try (Scope ignored = context.makeCurrent()) {
256-
propagator().inject(context, record.headers(), SETTER);
257-
callback = new ProducerCallback(callback, parentContext, context, request);
258-
return sendFn.apply(record, callback);
258+
return sendFn.apply(record, new ProducerCallback(callback, parentContext, context, request));
259259
}
260260
}
261261

instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/client/HttpClientRequestTracingHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ public void writeRequested(ChannelHandlerContext ctx, MessageEvent event) throws
5555

5656
try (Scope ignored = context.makeCurrent()) {
5757
super.writeRequested(ctx, event);
58-
// span is ended normally in HttpClientResponseTracingHandler
5958
} catch (Throwable throwable) {
6059
instrumenter().end(context, request, null, throwable);
6160
throw throwable;
6261
}
62+
// span is ended normally in HttpClientResponseTracingHandler
6363
}
6464
}

instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/HttpServerRequestTracingHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throw
5151

5252
try (Scope ignored = context.makeCurrent()) {
5353
super.messageReceived(ctx, event);
54-
// the span is ended normally in HttpServerResponseTracingHandler
5554
} catch (Throwable throwable) {
5655
instrumenter().end(context, request, null, throwable);
5756
throw throwable;
5857
}
58+
// span is ended normally in HttpServerResponseTracingHandler
5959
}
6060
}

instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/HttpServerResponseTracingHandler.java

+3-6
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,15 @@ public void writeRequested(ChannelHandlerContext ctx, MessageEvent msg) throws E
3636
Context context = requestAndContext.context();
3737
HttpRequestAndChannel request = requestAndContext.request();
3838
HttpResponse response = (HttpResponse) msg.getMessage();
39+
customizeResponse(context, response);
3940

40-
Throwable error = null;
4141
try (Scope ignored = context.makeCurrent()) {
42-
customizeResponse(context, response);
4342
super.writeRequested(ctx, msg);
4443
} catch (Throwable t) {
45-
error = t;
44+
instrumenter().end(context, request, response, NettyErrorHolder.getOrDefault(context, t));
4645
throw t;
47-
} finally {
48-
error = NettyErrorHolder.getOrDefault(context, error);
49-
instrumenter().end(context, request, response, error);
5046
}
47+
instrumenter().end(context, request, response, NettyErrorHolder.getOrDefault(context, null));
5148
}
5249

5350
private static void customizeResponse(Context context, HttpResponse response) {

instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/client/HttpClientRequestTracingHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) thr
4949

5050
try (Scope ignored = context.makeCurrent()) {
5151
super.write(ctx, msg, prm);
52-
// span is ended normally in HttpClientResponseTracingHandler
5352
} catch (Throwable throwable) {
5453
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
5554
parentContextAttr.remove();
5655
throw throwable;
5756
}
57+
// span is ended normally in HttpClientResponseTracingHandler
5858
}
5959
}

instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/server/HttpServerRequestTracingHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
5858

5959
try (Scope ignored = context.makeCurrent()) {
6060
super.channelRead(ctx, msg);
61-
// the span is ended normally in HttpServerResponseTracingHandler
6261
} catch (Throwable throwable) {
6362
// make sure to remove the server context on end() call
6463
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
6564
throw throwable;
6665
}
66+
// the span is ended normally in HttpServerResponseTracingHandler
6767
}
6868
}

instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/server/HttpServerResponseTracingHandler.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
3131
return;
3232
}
3333

34+
customizeResponse(context, (HttpResponse) msg);
35+
3436
try (Scope ignored = context.makeCurrent()) {
35-
customizeResponse(context, (HttpResponse) msg);
3637
ctx.write(msg, prm);
37-
end(ctx.channel(), (HttpResponse) msg, null);
38-
} catch (Throwable throwable) {
39-
end(ctx.channel(), (HttpResponse) msg, throwable);
40-
throw throwable;
38+
} catch (Throwable t) {
39+
end(ctx.channel(), (HttpResponse) msg, t);
40+
throw t;
4141
}
42+
end(ctx.channel(), (HttpResponse) msg, null);
4243
}
4344

4445
// make sure to remove the server context on end() call

instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/client/HttpClientRequestTracingHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) thr
6363

6464
try (Scope ignored = context.makeCurrent()) {
6565
super.write(ctx, msg, prm);
66-
// span is ended normally in HttpClientResponseTracingHandler
6766
} catch (Throwable throwable) {
6867
instrumenter.end(contextAttr.getAndSet(null), requestAttr.getAndSet(null), null, throwable);
6968
parentContextAttr.set(null);
7069
throw throwable;
7170
}
71+
// span is ended normally in HttpClientResponseTracingHandler
7272
}
7373

7474
private static boolean isAwsRequest(HttpRequestAndChannel request) {

instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/server/HttpServerRequestTracingHandler.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
5959

6060
try (Scope ignored = context.makeCurrent()) {
6161
super.channelRead(ctx, msg);
62-
// the span is ended normally in HttpServerResponseTracingHandler
63-
} catch (Throwable throwable) {
62+
} catch (Throwable t) {
6463
// make sure to remove the server context on end() call
6564
ServerContext serverContext = serverContexts.pollLast();
6665
if (serverContext != null) {
67-
instrumenter.end(serverContext.context(), serverContext.request(), null, throwable);
66+
instrumenter.end(serverContext.context(), serverContext.request(), null, t);
6867
}
69-
throw throwable;
68+
throw t;
7069
}
70+
// span is ended normally in HttpServerResponseTracingHandler
7171
}
7272

7373
@Override

instrumentation/okhttp/okhttp-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/okhttp/v2_2/TracingInterceptor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ public Response intercept(Chain chain) throws IOException {
3939
Response response;
4040
try (Scope ignored = context.makeCurrent()) {
4141
response = chain.proceed(request);
42-
} catch (Exception e) {
43-
instrumenter.end(context, request, null, e);
44-
throw e;
42+
} catch (Throwable t) {
43+
instrumenter.end(context, request, null, t);
44+
throw t;
4545
}
4646
instrumenter.end(context, request, response, null);
4747
return response;

instrumentation/okhttp/okhttp-3.0/library/src/main/java/io/opentelemetry/instrumentation/okhttp/v3_0/internal/TracingInterceptor.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,15 @@ public Response intercept(Chain chain) throws IOException {
4141
Context context = instrumenter.start(parentContext, chain);
4242
request = injectContextToRequest(request, context);
4343

44-
Response response = null;
45-
Throwable error = null;
44+
Response response;
4645
try (Scope ignored = context.makeCurrent()) {
4746
response = chain.proceed(request);
48-
return response;
49-
} catch (Exception e) {
50-
error = e;
51-
throw e;
52-
} finally {
53-
instrumenter.end(context, chain, response, error);
47+
} catch (Throwable t) {
48+
instrumenter.end(context, chain, null, t);
49+
throw t;
5450
}
51+
instrumenter.end(context, chain, response, null);
52+
return response;
5553
}
5654

5755
// Context injection is being handled manually for a reason: we want to use the OkHttp Request

0 commit comments

Comments
 (0)