io.opentelemetry.javaagent.instrumentation.vertx.RoutingContextHandlerWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-javaagent-vertx-web-3.0 Show documentation
Show all versions of opentelemetry-javaagent-vertx-web-3.0 Show documentation
Instrumentation of Java libraries using OpenTelemetry.
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.vertx;
import static io.opentelemetry.context.ContextKey.named;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.LocalRootSpan;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
/** This is used to wrap Vert.x Handlers to provide nice user-friendly SERVER span names */
public final class RoutingContextHandlerWrapper implements Handler {
private static final ContextKey ROUTE_KEY = named("opentelemetry-vertx-route");
private final Handler handler;
public RoutingContextHandlerWrapper(Handler handler) {
this.handler = handler;
}
@Override
public void handle(RoutingContext context) {
Context otelContext = Context.current();
String route = getRoute(otelContext, context);
if (route != null && route.endsWith("/")) {
route = route.substring(0, route.length() - 1);
}
HttpServerRoute.update(otelContext, HttpServerRouteSource.NESTED_CONTROLLER, route);
try (Scope ignore = otelContext.with(ROUTE_KEY, route).makeCurrent()) {
handler.handle(context);
} catch (Throwable throwable) {
Span serverSpan = LocalRootSpan.fromContextOrNull(otelContext);
if (serverSpan != null) {
serverSpan.recordException(unwrapThrowable(throwable));
}
throw throwable;
}
}
private static String getRoute(Context otelContext, RoutingContext routingContext) {
String route = routingContext.currentRoute().getPath();
String existingRoute = otelContext.get(ROUTE_KEY);
return existingRoute != null ? existingRoute + route : route;
}
private static Throwable unwrapThrowable(Throwable throwable) {
if (throwable.getCause() != null
&& (throwable instanceof ExecutionException
|| throwable instanceof CompletionException
|| throwable instanceof InvocationTargetException
|| throwable instanceof UndeclaredThrowableException)) {
return unwrapThrowable(throwable.getCause());
}
return throwable;
}
}