diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/servlet/ServerSpanNaming.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/servlet/ServerSpanNaming.java index 0c96c8e22f72..08680524ee83 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/servlet/ServerSpanNaming.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/servlet/ServerSpanNaming.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextKey; +import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer; import io.opentelemetry.instrumentation.api.tracer.ServerSpan; import javax.annotation.Nullable; @@ -17,14 +18,13 @@ public final class ServerSpanNaming { private static final ContextKey CONTEXT_KEY = ContextKey.named("opentelemetry-servlet-span-naming-key"); - public static Context init(Context context, Source initialSource) { - ServerSpanNaming serverSpanNaming = context.get(CONTEXT_KEY); - if (serverSpanNaming != null) { - // TODO (trask) does this ever happen? - serverSpanNaming.updatedBySource = initialSource; - return context; - } - return context.with(CONTEXT_KEY, new ServerSpanNaming(initialSource)); + public static ContextCustomizer get() { + return (context, request, startAttributes) -> { + if (context.get(CONTEXT_KEY) != null) { + return context; + } + return context.with(CONTEXT_KEY, new ServerSpanNaming(Source.CONTAINER)); + }; } private volatile Source updatedBySource; @@ -37,16 +37,15 @@ private ServerSpanNaming(Source initialSource) { } /** - * If there is a server span in the context, and {@link #init(Context, Source)} has been called to - * populate a {@code ServerSpanName} into the context, then this method will update the server - * span name using the provided {@link ServerSpanNameSupplier} if and only if the last {@link - * Source} to update the span name using this method has strictly lower priority than the provided - * {@link Source}, and the value returned from the {@link ServerSpanNameSupplier} is non-null. + * If there is a server span in the context, and the context has been customized with a {@code + * ServerSpanName}, then this method will update the server span name using the provided {@link + * ServerSpanNameSupplier} if and only if the last {@link Source} to update the span name using + * this method has strictly lower priority than the provided {@link Source}, and the value + * returned from the {@link ServerSpanNameSupplier} is non-null. * - *

If there is a server span in the context, and {@link #init(Context, Source)} has NOT been - * called to populate a {@code ServerSpanName} into the context, then this method will update the - * server span name using the provided {@link ServerSpanNameSupplier} if the value returned from - * it is non-null. + *

If there is a server span in the context, and the context has NOT been customized with a + * {@code ServerSpanName}, then this method will update the server span name using the provided + * {@link ServerSpanNameSupplier} if the value returned from it is non-null. */ public static void updateServerSpanName( Context context, Source source, ServerSpanNameSupplier serverSpanName, T arg1) { @@ -54,17 +53,15 @@ public static void updateServerSpanName( } /** - * If there is a server span in the context, and {@link #init(Context, Source)} has been called to - * populate a {@code ServerSpanName} into the context, then this method will update the server - * span name using the provided {@link ServerSpanNameTwoArgSupplier} if and only if the last - * {@link Source} to update the span name using this method has strictly lower priority than the - * provided {@link Source}, and the value returned from the {@link ServerSpanNameTwoArgSupplier} - * is non-null. + * If there is a server span in the context, and the context has been customized with a {@code + * ServerSpanName}, then this method will update the server span name using the provided {@link + * ServerSpanNameTwoArgSupplier} if and only if the last {@link Source} to update the span name + * using this method has strictly lower priority than the provided {@link Source}, and the value + * returned from the {@link ServerSpanNameTwoArgSupplier} is non-null. * - *

If there is a server span in the context, and {@link #init(Context, Source)} has NOT been - * called to populate a {@code ServerSpanName} into the context, then this method will update the - * server span name using the provided {@link ServerSpanNameTwoArgSupplier} if the value returned - * from it is non-null. + *

If there is a server span in the context, and the context has NOT been customized with a + * {@code ServerSpanName}, then this method will update the server span name using the provided + * {@link ServerSpanNameTwoArgSupplier} if the value returned from it is non-null. */ public static void updateServerSpanName( Context context, diff --git a/instrumentation/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerSingletons.java b/instrumentation/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerSingletons.java index 04432455e5a1..1f9f97fb7ef7 100644 --- a/instrumentation/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerSingletons.java +++ b/instrumentation/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerSingletons.java @@ -11,6 +11,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; +import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.instrumentation.akkahttp.AkkaHttpUtil; public class AkkaHttpServerSingletons { @@ -28,6 +29,7 @@ public class AkkaHttpServerSingletons { .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesExtractor)) .addAttributesExtractor(httpAttributesExtractor) .addRequestMetrics(HttpServerMetrics.get()) + .addContextCustomizer(ServerSpanNaming.get()) .newServerInstrumenter(AkkaHttpServerHeaders.INSTANCE); } diff --git a/instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaTracingBuilder.java b/instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaTracingBuilder.java index 09e857b60eeb..813d3a066049 100644 --- a/instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaTracingBuilder.java +++ b/instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaTracingBuilder.java @@ -21,6 +21,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; +import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.util.ArrayList; import java.util.List; @@ -135,7 +136,8 @@ public ArmeriaTracing build() { HttpSpanStatusExtractor.create(serverAttributesExtractor))) .addAttributesExtractor(new ArmeriaNetServerAttributesExtractor()) .addAttributesExtractor(serverAttributesExtractor) - .addRequestMetrics(HttpServerMetrics.get()); + .addRequestMetrics(HttpServerMetrics.get()) + .addContextCustomizer(ServerSpanNaming.get()); if (peerService != null) { clientInstrumenterBuilder.addAttributesExtractor( diff --git a/instrumentation/grizzly-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grizzly/GrizzlySingletons.java b/instrumentation/grizzly-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grizzly/GrizzlySingletons.java index 7ec41215d41a..ef6d3009763c 100644 --- a/instrumentation/grizzly-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grizzly/GrizzlySingletons.java +++ b/instrumentation/grizzly-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/grizzly/GrizzlySingletons.java @@ -32,10 +32,8 @@ public final class GrizzlySingletons { .addAttributesExtractor(netAttributesExtractor) .addRequestMetrics(HttpServerMetrics.get()) .addContextCustomizer( - (context, httpRequestPacket, startAttributes) -> { - context = GrizzlyErrorHolder.init(context); - return ServerSpanNaming.init(context, ServerSpanNaming.Source.CONTAINER); - }) + (context, httpRequestPacket, startAttributes) -> GrizzlyErrorHolder.init(context)) + .addContextCustomizer(ServerSpanNaming.get()) .newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE); } diff --git a/instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11Singletons.java b/instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11Singletons.java index 86c9c62ce948..240a96c39aca 100644 --- a/instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11Singletons.java +++ b/instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11Singletons.java @@ -5,10 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.jetty.v11_0; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge; import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; @@ -26,10 +23,7 @@ public final class Jetty11Singletons { INSTRUMENTER = ServletInstrumenterBuilder.create() .addContextCustomizer( - (context, request, attributes) -> { - context = ServerSpanNaming.init(context, CONTAINER); - return new AppServerBridge.Builder().init(context); - }) + (context, request, attributes) -> new AppServerBridge.Builder().init(context)) .build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE); private static final JettyHelper HELPER = diff --git a/instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java b/instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java index d94c196c6def..ed503f12ab4e 100644 --- a/instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java +++ b/instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java @@ -5,10 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.jetty.v8_0; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge; import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; @@ -26,10 +23,7 @@ public final class Jetty8Singletons { INSTRUMENTER = ServletInstrumenterBuilder.create() .addContextCustomizer( - (context, request, attributes) -> { - context = ServerSpanNaming.init(context, CONTAINER); - return new AppServerBridge.Builder().init(context); - }) + (context, request, attributes) -> new AppServerBridge.Builder().init(context)) .build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE); private static final JettyHelper HELPER = diff --git a/instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherSingletons.java b/instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherSingletons.java index 7474dc7e520f..d98152605f92 100644 --- a/instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherSingletons.java +++ b/instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherSingletons.java @@ -5,8 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.liberty.dispatcher; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; @@ -39,8 +37,7 @@ public final class LibertyDispatcherSingletons { .setSpanStatusExtractor(spanStatusExtractor) .addAttributesExtractor(httpAttributesExtractor) .addAttributesExtractor(netAttributesExtractor) - .addContextCustomizer( - (context, request, attributes) -> ServerSpanNaming.init(context, CONTAINER)) + .addContextCustomizer(ServerSpanNaming.get()) .addRequestMetrics(HttpServerMetrics.get()) .newServerInstrumenter(LibertyDispatcherRequestGetter.INSTANCE); } diff --git a/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertySingletons.java b/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertySingletons.java index cb30188b9061..9d4e4aba4a7a 100644 --- a/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertySingletons.java +++ b/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertySingletons.java @@ -5,10 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.liberty; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext; @@ -25,10 +22,8 @@ public final class LibertySingletons { INSTRUMENTER = ServletInstrumenterBuilder.create() .addContextCustomizer( - (context, request, attributes) -> { - context = ServerSpanNaming.init(context, CONTAINER); - return new AppServerBridge.Builder().recordException().init(context); - }) + (context, request, attributes) -> + new AppServerBridge.Builder().recordException().init(context)) .build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE); private static final LibertyHelper HELPER = diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/NettyServerSingletons.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/NettyServerSingletons.java index 6757cc2814ea..ffb65759b813 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/NettyServerSingletons.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/server/NettyServerSingletons.java @@ -10,6 +10,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; +import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.instrumentation.netty.common.NettyErrorHolder; import io.opentelemetry.javaagent.instrumentation.netty.v3_8.HttpRequestAndChannel; import org.jboss.netty.handler.codec.http.HttpResponse; @@ -33,6 +34,7 @@ final class NettyServerSingletons { .addRequestMetrics(HttpServerMetrics.get()) .addContextCustomizer( (context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context)) + .addContextCustomizer(ServerSpanNaming.get()) .newServerInstrumenter(NettyHeadersGetter.INSTANCE); } diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/server/NettyServerInstrumenterFactory.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/server/NettyServerInstrumenterFactory.java index 892ed0766ab8..b46d1990cb27 100644 --- a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/server/NettyServerInstrumenterFactory.java +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/server/NettyServerInstrumenterFactory.java @@ -31,12 +31,8 @@ public static Instrumenter create( .addAttributesExtractor(httpAttributesExtractor) .addAttributesExtractor(new NettyNetServerAttributesExtractor()) .addRequestMetrics(HttpServerMetrics.get()) - .addContextCustomizer( - (context, request, attributes) -> { - context = NettyErrorHolder.init(context); - // netty is not exactly a "container", but it's the best match out of these - return ServerSpanNaming.init(context, ServerSpanNaming.Source.CONTAINER); - }) + .addContextCustomizer((context, request, attributes) -> NettyErrorHolder.init(context)) + .addContextCustomizer(ServerSpanNaming.get()) .newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE); } diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Singletons.java b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Singletons.java index 9e6e9c8e7ffd..cb3796d2c6bc 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Singletons.java +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Singletons.java @@ -5,12 +5,9 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.SERVLET; - import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext; import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext; @@ -33,8 +30,6 @@ public final class Servlet2Singletons { ServletRequestContext, ServletResponseContext> instrumenter = ServletInstrumenterBuilder.create() - .addContextCustomizer( - (context, request, attributes) -> ServerSpanNaming.init(context, SERVLET)) .build( INSTRUMENTATION_NAME, Servlet2Accessor.INSTANCE, diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Advice.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Advice.java index c03fc445b191..8ab3c2c7a611 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Advice.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Advice.java @@ -9,7 +9,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.tracer.ServerSpan; import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge; import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; import io.opentelemetry.javaagent.instrumentation.api.CallDepth; @@ -39,52 +38,41 @@ public static void onEnter( if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { return; } + HttpServletRequest httpServletRequest = (HttpServletRequest) request; callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey()); callDepth.getAndIncrement(); - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - Context currentContext = Java8BytecodeBridge.currentContext(); Context attachedContext = helper().getServerContext(httpServletRequest); - if (attachedContext != null && helper().needsRescoping(currentContext, attachedContext)) { - MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter); - boolean servlet = servletOrFilter instanceof Servlet; - attachedContext = - helper().updateContext(attachedContext, httpServletRequest, mappingResolver, servlet); - scope = attachedContext.makeCurrent(); - // We are inside nested servlet/filter/app-server span, don't create new span - return; - } - - if (attachedContext != null || ServerSpan.fromContextOrNull(currentContext) != null) { - // Update context with info from current request to ensure that server span gets the best - // possible name. - // In case server span was created by app server instrumentations calling updateContext - // returns a new context that contains servlet context path that is used in other - // instrumentations for naming server span. - MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter); - boolean servlet = servletOrFilter instanceof Servlet; - Context updatedContext = - helper().updateContext(currentContext, httpServletRequest, mappingResolver, servlet); - if (currentContext != updatedContext) { - // updateContext updated context, need to re-scope - scope = updatedContext.makeCurrent(); - } - // We are inside nested servlet/filter/app-server span, don't create new span - return; - } + Context contextToUpdate; requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter); - - if (!helper().shouldStart(currentContext, requestContext)) { - return; + if (attachedContext == null && helper().shouldStart(currentContext, requestContext)) { + context = helper().start(currentContext, requestContext); + helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response); + + contextToUpdate = context; + } else if (attachedContext != null + && helper().needsRescoping(currentContext, attachedContext)) { + // Given request already has a context associated with it. + // see the needsRescoping() javadoc for more explanation + contextToUpdate = attachedContext; + } else { + // We are inside nested servlet/filter/app-server span, don't create new span + contextToUpdate = currentContext; } - context = helper().start(currentContext, requestContext); - scope = context.makeCurrent(); - - helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response); + // Update context with info from current request to ensure that server span gets the best + // possible name. + // In case server span was created by app server instrumentations calling updateContext + // returns a new context that contains servlet context path that is used in other + // instrumentations for naming server span. + MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter); + boolean servlet = servletOrFilter instanceof Servlet; + contextToUpdate = + helper().updateContext(contextToUpdate, httpServletRequest, mappingResolver, servlet); + scope = contextToUpdate.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Singletons.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Singletons.java index cb8efedb2814..939c04605d8c 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Singletons.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3Singletons.java @@ -5,12 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.FILTER; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.SERVLET; - import io.opentelemetry.instrumentation.api.field.VirtualField; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; @@ -28,11 +24,6 @@ public final class Servlet3Singletons { ServletRequestContext, ServletResponseContext> INSTRUMENTER = ServletInstrumenterBuilder.create() - .setMappingResolverFunction(Servlet3Singletons::getMappingResolver) - .addContextCustomizer( - (context, request, attributes) -> - ServerSpanNaming.init( - context, request.servletOrFilter() instanceof Servlet ? SERVLET : FILTER)) .build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE); private static final ServletHelper HELPER = @@ -47,11 +38,6 @@ public static ServletHelper helper() { return HELPER; } - private static MappingResolver getMappingResolver( - ServletRequestContext servletRequestContext) { - return getMappingResolver(servletRequestContext.servletOrFilter()); - } - public static MappingResolver getMappingResolver(Object servletOrFilter) { MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter); if (factory != null) { diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/Servlet5Singletons.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/Servlet5Singletons.java index 9df1b01a98d9..d046f342a780 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/Servlet5Singletons.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/Servlet5Singletons.java @@ -5,12 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v5_0; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.FILTER; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.SERVLET; - import io.opentelemetry.instrumentation.api.field.VirtualField; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper; import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder; @@ -29,11 +25,6 @@ public final class Servlet5Singletons { ServletRequestContext, ServletResponseContext> INSTRUMENTER = ServletInstrumenterBuilder.create() - .setMappingResolverFunction(Servlet5Singletons::getMappingResolver) - .addContextCustomizer( - (context, request, attributes) -> - ServerSpanNaming.init( - context, request.servletOrFilter() instanceof Servlet ? SERVLET : FILTER)) .build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE); private static final ServletHelper HELPER = @@ -48,11 +39,6 @@ public static ServletHelper helper() { return HELPER; } - private static MappingResolver getMappingResolver( - ServletRequestContext servletRequestContext) { - return getMappingResolver(servletRequestContext.servletOrFilter()); - } - public static MappingResolver getMappingResolver(Object servletOrFilter) { MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter); if (factory != null) { diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java index f063ba03ead6..988fd0c50b07 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java @@ -9,7 +9,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.tracer.ServerSpan; import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge; import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; import io.opentelemetry.javaagent.instrumentation.api.CallDepth; @@ -40,52 +39,41 @@ public static void onEnter( if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { return; } + HttpServletRequest httpServletRequest = (HttpServletRequest) request; callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey()); callDepth.getAndIncrement(); - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - Context currentContext = Java8BytecodeBridge.currentContext(); Context attachedContext = helper().getServerContext(httpServletRequest); - if (attachedContext != null && helper().needsRescoping(currentContext, attachedContext)) { - MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter); - boolean servlet = servletOrFilter instanceof Servlet; - attachedContext = - helper().updateContext(attachedContext, httpServletRequest, mappingResolver, servlet); - scope = attachedContext.makeCurrent(); - // We are inside nested servlet/filter/app-server span, don't create new span - return; - } - - if (attachedContext != null || ServerSpan.fromContextOrNull(currentContext) != null) { - // Update context with info from current request to ensure that server span gets the best - // possible name. - // In case server span was created by app server instrumentations calling updateContext - // returns a new context that contains servlet context path that is used in other - // instrumentations for naming server span. - MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter); - boolean servlet = servletOrFilter instanceof Servlet; - Context updatedContext = - helper().updateContext(currentContext, httpServletRequest, mappingResolver, servlet); - if (currentContext != updatedContext) { - // updateContext updated context, need to re-scope - scope = updatedContext.makeCurrent(); - } - // We are inside nested servlet/filter/app-server span, don't create new span - return; - } + Context contextToUpdate; requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter); - - if (!helper().shouldStart(currentContext, requestContext)) { - return; + if (attachedContext == null && helper().shouldStart(currentContext, requestContext)) { + context = helper().start(currentContext, requestContext); + helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response); + + contextToUpdate = context; + } else if (attachedContext != null + && helper().needsRescoping(currentContext, attachedContext)) { + // Given request already has a context associated with it. + // see the needsRescoping() javadoc for more explanation + contextToUpdate = attachedContext; + } else { + // We are inside nested servlet/filter/app-server span, don't create new span + contextToUpdate = currentContext; } - context = helper().start(currentContext, requestContext); - scope = context.makeCurrent(); - - helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response); + // Update context with info from current request to ensure that server span gets the best + // possible name. + // In case server span was created by app server instrumentations calling updateContext + // returns a new context that contains servlet context path that is used in other + // instrumentations for naming server span. + MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter); + boolean servlet = servletOrFilter instanceof Servlet; + contextToUpdate = + helper().updateContext(contextToUpdate, httpServletRequest, mappingResolver, servlet); + scope = contextToUpdate.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletInstrumenterBuilder.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletInstrumenterBuilder.java index 2c7b9a9805d7..deaf72c6428a 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletInstrumenterBuilder.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletInstrumenterBuilder.java @@ -14,20 +14,16 @@ import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; +import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; -import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; +import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; -import javax.annotation.Nullable; public final class ServletInstrumenterBuilder { private ServletInstrumenterBuilder() {} - @Nullable - private Function, MappingResolver> mappingResolverFunction; - private final List>> contextCustomizers = new ArrayList<>(); @@ -35,12 +31,6 @@ public static ServletInstrumenterBuilder return new ServletInstrumenterBuilder<>(); } - public ServletInstrumenterBuilder setMappingResolverFunction( - Function, MappingResolver> mappingResolverFunction) { - this.mappingResolverFunction = mappingResolverFunction; - return this; - } - public ServletInstrumenterBuilder addContextCustomizer( ContextCustomizer> contextCustomizer) { contextCustomizers.add(contextCustomizer); @@ -72,7 +62,8 @@ public Instrumenter, ServletResponseContext, ServletResponseContext> requestParametersExtractor = new ServletRequestParametersExtractor<>(accessor); @@ -90,7 +81,7 @@ public Instrumenter, ServletResponseContext, ServletResponseContext> httpAttributesExtractor = new ServletHttpAttributesExtractor<>(accessor); SpanNameExtractor> spanNameExtractor = - new ServletSpanNameExtractor<>(accessor, mappingResolverFunction); + HttpSpanNameExtractor.create(httpAttributesExtractor); return build(instrumentationName, accessor, spanNameExtractor, httpAttributesExtractor); } diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletSpanNameExtractor.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletSpanNameExtractor.java deleted file mode 100644 index db074fb42909..000000000000 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletSpanNameExtractor.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.servlet; - -import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; -import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver; -import java.util.function.Function; -import javax.annotation.Nullable; - -public class ServletSpanNameExtractor - implements SpanNameExtractor> { - private final ServletAccessor accessor; - - @Nullable - private final Function, MappingResolver> mappingResolverFunction; - - public ServletSpanNameExtractor( - ServletAccessor accessor, - @Nullable Function, MappingResolver> mappingResolverFunction) { - this.accessor = accessor; - this.mappingResolverFunction = mappingResolverFunction; - } - - @Nullable - private String route(ServletRequestContext requestContext) { - if (mappingResolverFunction == null) { - return null; - } - MappingResolver mappingResolver = mappingResolverFunction.apply(requestContext); - if (mappingResolver == null) { - return null; - } - - REQUEST request = requestContext.request(); - String servletPath = accessor.getRequestServletPath(request); - String pathInfo = accessor.getRequestPathInfo(request); - String contextPath = accessor.getRequestContextPath(request); - boolean hasContextPath = - contextPath != null && !contextPath.isEmpty() && !contextPath.equals("/"); - - String route = mappingResolver.resolve(servletPath, pathInfo); - if (route == null) { - if (hasContextPath) { - return contextPath + "/*"; - } - return null; - } - // prepend context path - return contextPath + route; - } - - @Override - public String extract(ServletRequestContext requestContext) { - String route = route(requestContext); - if (route != null) { - return route; - } - REQUEST request = requestContext.request(); - String method = accessor.getRequestMethod(request); - if (method != null) { - return "HTTP " + method; - } - return "HTTP request"; - } -} diff --git a/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcTracingBuilder.java b/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcTracingBuilder.java index c8ad42f2cd59..a30be8e74059 100644 --- a/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcTracingBuilder.java +++ b/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcTracingBuilder.java @@ -13,6 +13,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; +import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -73,6 +74,7 @@ public SpringWebMvcTracing build() { .addAttributesExtractor(new SpringWebMvcNetAttributesExtractor()) .addAttributesExtractors(additionalExtractors) .addRequestMetrics(HttpServerMetrics.get()) + .addContextCustomizer(ServerSpanNaming.get()) .newServerInstrumenter(JavaxHttpServletRequestGetter.INSTANCE); return new SpringWebMvcTracing(instrumenter); diff --git a/instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatInstrumenterFactory.java b/instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatInstrumenterFactory.java index 1708fd0b6afd..51eb22cffe3f 100644 --- a/instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatInstrumenterFactory.java +++ b/instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatInstrumenterFactory.java @@ -5,8 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.tomcat.common; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; @@ -50,15 +48,13 @@ public static Instrumenter create( .addAttributesExtractor(httpAttributesExtractor) .addAttributesExtractor(netAttributesExtractor) .addAttributesExtractor(additionalAttributeExtractor) + .addContextCustomizer(ServerSpanNaming.get()) .addContextCustomizer( - (context, request, attributes) -> { - context = ServerSpanNaming.init(context, CONTAINER); - - return new AppServerBridge.Builder() - .captureServletAttributes() - .recordException() - .init(context); - }) + (context, request, attributes) -> + new AppServerBridge.Builder() + .captureServletAttributes() + .recordException() + .init(context)) .addRequestMetrics(HttpServerMetrics.get()) .newServerInstrumenter(TomcatRequestGetter.INSTANCE); } diff --git a/instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowSingletons.java b/instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowSingletons.java index 36744cb9334c..6be82e3d6b7b 100644 --- a/instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowSingletons.java +++ b/instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowSingletons.java @@ -5,8 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.undertow; -import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER; - import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; @@ -42,9 +40,9 @@ public final class UndertowSingletons { .setSpanStatusExtractor(spanStatusExtractor) .addAttributesExtractor(httpAttributesExtractor) .addAttributesExtractor(netAttributesExtractor) + .addContextCustomizer(ServerSpanNaming.get()) .addContextCustomizer( (context, request, attributes) -> { - context = ServerSpanNaming.init(context, CONTAINER); // span is ended when counter reaches 0, we start from 2 which accounts for the // handler that started the span and exchange completion listener context = UndertowActiveHandlers.init(context, 2);