Skip to content

Commit

Permalink
End span after closing scope (#12952)
Browse files Browse the repository at this point in the history
  • Loading branch information
trask authored Dec 27, 2024
1 parent 1a506cb commit 2ea27b2
Show file tree
Hide file tree
Showing 30 changed files with 138 additions and 152 deletions.
14 changes: 8 additions & 6 deletions docs/contributing/using-instrumenter-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,16 @@ Response decoratedMethod(Request request) {
}

Context context = instrumenter.start(parentContext, request);
Response response;
try (Scope scope = context.makeCurrent()) {
Response response = actualMethod(request);
instrumenter.end(context, request, response, null);
return response;
} catch (Throwable error) {
instrumenter.end(context, request, null, error);
throw error;
response = actualMethod(request);
} catch (Throwable t) {
instrumenter.end(context, request, null, t);
throw t;
}
// calling end after the scope is closed is a best practice
instrumenter.end(context, request, response, null);
return response;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,14 @@ private CloseableHttpResponse execute(
HttpExecutionAware httpExecutionAware,
Context context)
throws IOException, HttpException {
CloseableHttpResponse response = null;
Throwable error = null;
CloseableHttpResponse response;
try (Scope ignored = context.makeCurrent()) {
response = exec.execute(route, request, httpContext, httpExecutionAware);
return response;
} catch (Throwable e) {
error = e;
throw e;
} finally {
instrumenter.end(context, instrumenterRequest, response, error);
} catch (Throwable t) {
instrumenter.end(context, instrumenterRequest, null, t);
throw t;
}
instrumenter.end(context, instrumenterRequest, response, null);
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,18 @@ private static Class<?> createProxyClass() {
return method.invoke(target, args);
}

Response response = null;
Throwable throwable = null;
Context context = instrumenter.start(parentContext, otelRequest);
try (Scope scope = context.makeCurrent()) {

Response response;
try (Scope ignored = context.makeCurrent()) {
response = (Response) method.invoke(target, args);
} catch (Throwable exception) {
throwable = exception;
throw throwable;
} finally {
instrumenter.end(context, otelRequest, response, throwable);
} catch (Throwable t) {
instrumenter.end(context, otelRequest, null, t);
throw t;
}

instrumenter.end(context, otelRequest, response, null);
return response;

} else if ("performRequestAsync".equals(method.getName())
&& args.length == 2
&& args[0] instanceof Request
Expand All @@ -94,22 +93,17 @@ private static Class<?> createProxyClass() {
return method.invoke(target, args);
}

Throwable throwable = null;
Context context = instrumenter.start(parentContext, otelRequest);
args[1] =
new RestResponseListener(
responseListener, parentContext, instrumenter, context, otelRequest);
try (Scope scope = context.makeCurrent()) {
try (Scope ignored = context.makeCurrent()) {
return method.invoke(target, args);
} catch (Throwable exception) {
throwable = exception;
throw throwable;
} finally {
if (throwable != null) {
instrumenter.end(context, otelRequest, null, throwable);
}
// span ended in RestResponseListener
} catch (Throwable t) {
instrumenter.end(context, otelRequest, null, t);
throw t;
}
// span ended in RestResponseListener
}

// delegate to wrapped RestClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,11 @@ public <REQUEST, RESPONSE> ClientCall<REQUEST, RESPONSE> interceptCall(
Context context = instrumenter.start(parentContext, request);
ClientCall<REQUEST, RESPONSE> result;
try (Scope ignored = context.makeCurrent()) {
try {
// call other interceptors
result = next.newCall(method, callOptions);
} catch (Throwable e) {
instrumenter.end(context, request, Status.UNKNOWN, e);
throw e;
}
// call other interceptors
result = next.newCall(method, callOptions);
} catch (Throwable t) {
instrumenter.end(context, request, Status.UNKNOWN, t);
throw t;
}

return new TracingClientCall<>(result, parentContext, context, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.named;

import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.net.http.HttpHeaders;
Expand Down Expand Up @@ -39,7 +40,7 @@ public static class HeadersAdvice {

@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(@Advice.Return(readOnly = false) HttpHeaders headers) {
headers = setter().inject(headers);
headers = setter().inject(headers, Context.current());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ public HttpHeadersSetter(ContextPropagators contextPropagators) {
this.contextPropagators = contextPropagators;
}

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

contextPropagators
.getTextMapPropagator()
.inject(
Context.current(),
context,
headerMap,
(carrier, key, value) -> {
if (carrier != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,17 @@ public <T> HttpResponse<T> send(
return client.send(request, responseBodyHandler);
}

HttpResponse<T> response = null;
Throwable error = null;
Context context = instrumenter.start(parentContext, request);
HttpRequestWrapper requestWrapper =
new HttpRequestWrapper(request, headersSetter.inject(request.headers(), context));
HttpResponse<T> response;
try (Scope ignore = context.makeCurrent()) {
HttpRequestWrapper requestWrapper =
new HttpRequestWrapper(request, headersSetter.inject(request.headers()));

response = client.send(requestWrapper, responseBodyHandler);
} catch (Throwable throwable) {
error = throwable;
throw throwable;
} finally {
instrumenter.end(context, request, response, error);
} catch (Throwable t) {
instrumenter.end(context, request, null, t);
throw t;
}

instrumenter.end(context, request, response, null);
return response;
}

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

Context context = instrumenter.start(parentContext, request);
try (Scope ignore = context.makeCurrent()) {
HttpRequestWrapper requestWrapper =
new HttpRequestWrapper(request, headersSetter.inject(request.headers()));

CompletableFuture<HttpResponse<T>> future = action.apply(requestWrapper);
future = future.whenComplete(new ResponseConsumer(instrumenter, context, request));
future = CompletableFutureWrapper.wrap(future, parentContext);
return future;
} catch (Throwable throwable) {
instrumenter.end(context, request, null, throwable);
throw throwable;
HttpRequestWrapper requestWrapper =
new HttpRequestWrapper(request, headersSetter.inject(request.headers(), context));

CompletableFuture<HttpResponse<T>> future;
try (Scope ignored = context.makeCurrent()) {
future = action.apply(requestWrapper);
} catch (Throwable t) {
instrumenter.end(context, request, null, t);
throw t;
}
future = future.whenComplete(new ResponseConsumer(instrumenter, context, request));
future = CompletableFutureWrapper.wrap(future, parentContext);
return future;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,10 @@ <K, V> Future<RecordMetadata> buildAndInjectSpan(
}

Context context = producerInstrumenter.start(parentContext, request);
propagator().inject(context, record.headers(), SETTER);

try (Scope ignored = context.makeCurrent()) {
propagator().inject(context, record.headers(), SETTER);
callback = new ProducerCallback(callback, parentContext, context, request);
return sendFn.apply(record, callback);
return sendFn.apply(record, new ProducerCallback(callback, parentContext, context, request));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public void writeRequested(ChannelHandlerContext ctx, MessageEvent event) throws

try (Scope ignored = context.makeCurrent()) {
super.writeRequested(ctx, event);
// span is ended normally in HttpClientResponseTracingHandler
} catch (Throwable throwable) {
instrumenter().end(context, request, null, throwable);
throw throwable;
}
// span is ended normally in HttpClientResponseTracingHandler
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throw

try (Scope ignored = context.makeCurrent()) {
super.messageReceived(ctx, event);
// the span is ended normally in HttpServerResponseTracingHandler
} catch (Throwable throwable) {
instrumenter().end(context, request, null, throwable);
throw throwable;
}
// span is ended normally in HttpServerResponseTracingHandler
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,15 @@ public void writeRequested(ChannelHandlerContext ctx, MessageEvent msg) throws E
Context context = requestAndContext.context();
HttpRequestAndChannel request = requestAndContext.request();
HttpResponse response = (HttpResponse) msg.getMessage();
customizeResponse(context, response);

Throwable error = null;
try (Scope ignored = context.makeCurrent()) {
customizeResponse(context, response);
super.writeRequested(ctx, msg);
} catch (Throwable t) {
error = t;
instrumenter().end(context, request, response, NettyErrorHolder.getOrDefault(context, t));
throw t;
} finally {
error = NettyErrorHolder.getOrDefault(context, error);
instrumenter().end(context, request, response, error);
}
instrumenter().end(context, request, response, NettyErrorHolder.getOrDefault(context, null));
}

private static void customizeResponse(Context context, HttpResponse response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) thr

try (Scope ignored = context.makeCurrent()) {
super.write(ctx, msg, prm);
// span is ended normally in HttpClientResponseTracingHandler
} catch (Throwable throwable) {
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
parentContextAttr.remove();
throw throwable;
}
// span is ended normally in HttpClientResponseTracingHandler
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

try (Scope ignored = context.makeCurrent()) {
super.channelRead(ctx, msg);
// the span is ended normally in HttpServerResponseTracingHandler
} catch (Throwable throwable) {
// make sure to remove the server context on end() call
instrumenter().end(contextAttr.getAndRemove(), requestAttr.getAndRemove(), null, throwable);
throw throwable;
}
// the span is ended normally in HttpServerResponseTracingHandler
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
return;
}

customizeResponse(context, (HttpResponse) msg);

try (Scope ignored = context.makeCurrent()) {
customizeResponse(context, (HttpResponse) msg);
ctx.write(msg, prm);
end(ctx.channel(), (HttpResponse) msg, null);
} catch (Throwable throwable) {
end(ctx.channel(), (HttpResponse) msg, throwable);
throw throwable;
} catch (Throwable t) {
end(ctx.channel(), (HttpResponse) msg, t);
throw t;
}
end(ctx.channel(), (HttpResponse) msg, null);
}

// make sure to remove the server context on end() call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) thr

try (Scope ignored = context.makeCurrent()) {
super.write(ctx, msg, prm);
// span is ended normally in HttpClientResponseTracingHandler
} catch (Throwable throwable) {
instrumenter.end(contextAttr.getAndSet(null), requestAttr.getAndSet(null), null, throwable);
parentContextAttr.set(null);
throw throwable;
}
// span is ended normally in HttpClientResponseTracingHandler
}

private static boolean isAwsRequest(HttpRequestAndChannel request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

try (Scope ignored = context.makeCurrent()) {
super.channelRead(ctx, msg);
// the span is ended normally in HttpServerResponseTracingHandler
} catch (Throwable throwable) {
} catch (Throwable t) {
// make sure to remove the server context on end() call
ServerContext serverContext = serverContexts.pollLast();
if (serverContext != null) {
instrumenter.end(serverContext.context(), serverContext.request(), null, throwable);
instrumenter.end(serverContext.context(), serverContext.request(), null, t);
}
throw throwable;
throw t;
}
// span is ended normally in HttpServerResponseTracingHandler
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public Response intercept(Chain chain) throws IOException {
Response response;
try (Scope ignored = context.makeCurrent()) {
response = chain.proceed(request);
} catch (Exception e) {
instrumenter.end(context, request, null, e);
throw e;
} catch (Throwable t) {
instrumenter.end(context, request, null, t);
throw t;
}
instrumenter.end(context, request, response, null);
return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,15 @@ public Response intercept(Chain chain) throws IOException {
Context context = instrumenter.start(parentContext, chain);
request = injectContextToRequest(request, context);

Response response = null;
Throwable error = null;
Response response;
try (Scope ignored = context.makeCurrent()) {
response = chain.proceed(request);
return response;
} catch (Exception e) {
error = e;
throw e;
} finally {
instrumenter.end(context, chain, response, error);
} catch (Throwable t) {
instrumenter.end(context, chain, null, t);
throw t;
}
instrumenter.end(context, chain, response, null);
return response;
}

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

0 comments on commit 2ea27b2

Please sign in to comment.