Refactor `ServerSpanNaming` (in preparation for `http.route`) (#4852)
* Refactor ServerSpanNaming (in preparation for http.route) * fix tests * Add ServerSpanNaming to all HTTP server instrumentations * fix tests
This commit is contained in:
parent
331ce287d2
commit
a65e9633ba
|
@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.servlet;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.ContextKey;
|
import io.opentelemetry.context.ContextKey;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -17,14 +18,13 @@ public final class ServerSpanNaming {
|
||||||
private static final ContextKey<ServerSpanNaming> CONTEXT_KEY =
|
private static final ContextKey<ServerSpanNaming> CONTEXT_KEY =
|
||||||
ContextKey.named("opentelemetry-servlet-span-naming-key");
|
ContextKey.named("opentelemetry-servlet-span-naming-key");
|
||||||
|
|
||||||
public static Context init(Context context, Source initialSource) {
|
public static <REQUEST> ContextCustomizer<REQUEST> get() {
|
||||||
ServerSpanNaming serverSpanNaming = context.get(CONTEXT_KEY);
|
return (context, request, startAttributes) -> {
|
||||||
if (serverSpanNaming != null) {
|
if (context.get(CONTEXT_KEY) != null) {
|
||||||
// TODO (trask) does this ever happen?
|
|
||||||
serverSpanNaming.updatedBySource = initialSource;
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
return context.with(CONTEXT_KEY, new ServerSpanNaming(initialSource));
|
return context.with(CONTEXT_KEY, new ServerSpanNaming(Source.CONTAINER));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private volatile Source updatedBySource;
|
private volatile Source updatedBySource;
|
||||||
|
@ -37,16 +37,15 @@ public final class ServerSpanNaming {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If there is a server span in the context, and {@link #init(Context, Source)} has been called to
|
* If there is a server span in the context, and the context has been customized with a {@code
|
||||||
* populate a {@code ServerSpanName} into the context, then this method will update the server
|
* ServerSpanName}, then this method will update the server span name using the provided {@link
|
||||||
* span name using the provided {@link ServerSpanNameSupplier} if and only if the last {@link
|
* ServerSpanNameSupplier} if and only if the last {@link Source} to update the span name using
|
||||||
* Source} to update the span name using this method has strictly lower priority than the provided
|
* this method has strictly lower priority than the provided {@link Source}, and the value
|
||||||
* {@link Source}, and the value returned from the {@link ServerSpanNameSupplier} is non-null.
|
* returned from the {@link ServerSpanNameSupplier} is non-null.
|
||||||
*
|
*
|
||||||
* <p>If there is a server span in the context, and {@link #init(Context, Source)} has NOT been
|
* <p>If there is a server span in the context, and the context has NOT been customized with a
|
||||||
* called to populate a {@code ServerSpanName} into the context, then this method will update the
|
* {@code ServerSpanName}, then this method will update the server span name using the provided
|
||||||
* server span name using the provided {@link ServerSpanNameSupplier} if the value returned from
|
* {@link ServerSpanNameSupplier} if the value returned from it is non-null.
|
||||||
* it is non-null.
|
|
||||||
*/
|
*/
|
||||||
public static <T> void updateServerSpanName(
|
public static <T> void updateServerSpanName(
|
||||||
Context context, Source source, ServerSpanNameSupplier<T> serverSpanName, T arg1) {
|
Context context, Source source, ServerSpanNameSupplier<T> serverSpanName, T arg1) {
|
||||||
|
@ -54,17 +53,15 @@ public final class ServerSpanNaming {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If there is a server span in the context, and {@link #init(Context, Source)} has been called to
|
* If there is a server span in the context, and the context has been customized with a {@code
|
||||||
* populate a {@code ServerSpanName} into the context, then this method will update the server
|
* ServerSpanName}, then this method will update the server span name using the provided {@link
|
||||||
* span name using the provided {@link ServerSpanNameTwoArgSupplier} if and only if the last
|
* ServerSpanNameTwoArgSupplier} if and only if the last {@link Source} to update the span name
|
||||||
* {@link Source} to update the span name using this method has strictly lower priority than the
|
* using this method has strictly lower priority than the provided {@link Source}, and the value
|
||||||
* provided {@link Source}, and the value returned from the {@link ServerSpanNameTwoArgSupplier}
|
* returned from the {@link ServerSpanNameTwoArgSupplier} is non-null.
|
||||||
* is non-null.
|
|
||||||
*
|
*
|
||||||
* <p>If there is a server span in the context, and {@link #init(Context, Source)} has NOT been
|
* <p>If there is a server span in the context, and the context has NOT been customized with a
|
||||||
* called to populate a {@code ServerSpanName} into the context, then this method will update the
|
* {@code ServerSpanName}, then this method will update the server span name using the provided
|
||||||
* server span name using the provided {@link ServerSpanNameTwoArgSupplier} if the value returned
|
* {@link ServerSpanNameTwoArgSupplier} if the value returned from it is non-null.
|
||||||
* from it is non-null.
|
|
||||||
*/
|
*/
|
||||||
public static <T, U> void updateServerSpanName(
|
public static <T, U> void updateServerSpanName(
|
||||||
Context context,
|
Context context,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import io.opentelemetry.javaagent.instrumentation.akkahttp.AkkaHttpUtil;
|
import io.opentelemetry.javaagent.instrumentation.akkahttp.AkkaHttpUtil;
|
||||||
|
|
||||||
public class AkkaHttpServerSingletons {
|
public class AkkaHttpServerSingletons {
|
||||||
|
@ -28,6 +29,7 @@ public class AkkaHttpServerSingletons {
|
||||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesExtractor))
|
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesExtractor))
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
.newServerInstrumenter(AkkaHttpServerHeaders.INSTANCE);
|
.newServerInstrumenter(AkkaHttpServerHeaders.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -135,7 +136,8 @@ public final class ArmeriaTracingBuilder {
|
||||||
HttpSpanStatusExtractor.create(serverAttributesExtractor)))
|
HttpSpanStatusExtractor.create(serverAttributesExtractor)))
|
||||||
.addAttributesExtractor(new ArmeriaNetServerAttributesExtractor())
|
.addAttributesExtractor(new ArmeriaNetServerAttributesExtractor())
|
||||||
.addAttributesExtractor(serverAttributesExtractor)
|
.addAttributesExtractor(serverAttributesExtractor)
|
||||||
.addRequestMetrics(HttpServerMetrics.get());
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get());
|
||||||
|
|
||||||
if (peerService != null) {
|
if (peerService != null) {
|
||||||
clientInstrumenterBuilder.addAttributesExtractor(
|
clientInstrumenterBuilder.addAttributesExtractor(
|
||||||
|
|
|
@ -32,10 +32,8 @@ public final class GrizzlySingletons {
|
||||||
.addAttributesExtractor(netAttributesExtractor)
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, httpRequestPacket, startAttributes) -> {
|
(context, httpRequestPacket, startAttributes) -> GrizzlyErrorHolder.init(context))
|
||||||
context = GrizzlyErrorHolder.init(context);
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
return ServerSpanNaming.init(context, ServerSpanNaming.Source.CONTAINER);
|
|
||||||
})
|
|
||||||
.newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE);
|
.newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jetty.v11_0;
|
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.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
||||||
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
|
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
||||||
|
@ -26,10 +23,7 @@ public final class Jetty11Singletons {
|
||||||
INSTRUMENTER =
|
INSTRUMENTER =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, request, attributes) -> {
|
(context, request, attributes) -> new AppServerBridge.Builder().init(context))
|
||||||
context = ServerSpanNaming.init(context, CONTAINER);
|
|
||||||
return new AppServerBridge.Builder().init(context);
|
|
||||||
})
|
|
||||||
.build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE);
|
.build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE);
|
||||||
|
|
||||||
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
||||||
|
|
|
@ -5,10 +5,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
|
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.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
||||||
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
|
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
||||||
|
@ -26,10 +23,7 @@ public final class Jetty8Singletons {
|
||||||
INSTRUMENTER =
|
INSTRUMENTER =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, request, attributes) -> {
|
(context, request, attributes) -> new AppServerBridge.Builder().init(context))
|
||||||
context = ServerSpanNaming.init(context, CONTAINER);
|
|
||||||
return new AppServerBridge.Builder().init(context);
|
|
||||||
})
|
|
||||||
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
||||||
|
|
||||||
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
private static final JettyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.liberty.dispatcher;
|
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.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||||
|
@ -39,8 +37,7 @@ public final class LibertyDispatcherSingletons {
|
||||||
.setSpanStatusExtractor(spanStatusExtractor)
|
.setSpanStatusExtractor(spanStatusExtractor)
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addAttributesExtractor(netAttributesExtractor)
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
(context, request, attributes) -> ServerSpanNaming.init(context, CONTAINER))
|
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
.newServerInstrumenter(LibertyDispatcherRequestGetter.INSTANCE);
|
.newServerInstrumenter(LibertyDispatcherRequestGetter.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.liberty;
|
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.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
|
||||||
|
@ -25,10 +22,8 @@ public final class LibertySingletons {
|
||||||
INSTRUMENTER =
|
INSTRUMENTER =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, request, attributes) -> {
|
(context, request, attributes) ->
|
||||||
context = ServerSpanNaming.init(context, CONTAINER);
|
new AppServerBridge.Builder().recordException().init(context))
|
||||||
return new AppServerBridge.Builder().recordException().init(context);
|
|
||||||
})
|
|
||||||
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
||||||
|
|
||||||
private static final LibertyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
private static final LibertyHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
||||||
|
|
|
@ -10,6 +10,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
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.common.NettyErrorHolder;
|
||||||
import io.opentelemetry.javaagent.instrumentation.netty.v3_8.HttpRequestAndChannel;
|
import io.opentelemetry.javaagent.instrumentation.netty.v3_8.HttpRequestAndChannel;
|
||||||
import org.jboss.netty.handler.codec.http.HttpResponse;
|
import org.jboss.netty.handler.codec.http.HttpResponse;
|
||||||
|
@ -33,6 +34,7 @@ final class NettyServerSingletons {
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context))
|
(context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context))
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
.newServerInstrumenter(NettyHeadersGetter.INSTANCE);
|
.newServerInstrumenter(NettyHeadersGetter.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,8 @@ public final class NettyServerInstrumenterFactory {
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addAttributesExtractor(new NettyNetServerAttributesExtractor())
|
.addAttributesExtractor(new NettyNetServerAttributesExtractor())
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
.addContextCustomizer(
|
.addContextCustomizer((context, request, attributes) -> NettyErrorHolder.init(context))
|
||||||
(context, request, attributes) -> {
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
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);
|
|
||||||
})
|
|
||||||
.newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE);
|
.newServerInstrumenter(HttpRequestHeadersGetter.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,9 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.servlet.v2_2;
|
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.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
|
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.ServletInstrumenterBuilder;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletResponseContext;
|
||||||
|
@ -33,8 +30,6 @@ public final class Servlet2Singletons {
|
||||||
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
||||||
instrumenter =
|
instrumenter =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.addContextCustomizer(
|
|
||||||
(context, request, attributes) -> ServerSpanNaming.init(context, SERVLET))
|
|
||||||
.build(
|
.build(
|
||||||
INSTRUMENTATION_NAME,
|
INSTRUMENTATION_NAME,
|
||||||
Servlet2Accessor.INSTANCE,
|
Servlet2Accessor.INSTANCE,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import static io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3Si
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.Scope;
|
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.AppServerBridge;
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
|
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
|
||||||
|
@ -39,25 +38,31 @@ public class Servlet3Advice {
|
||||||
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
|
|
||||||
callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey());
|
callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey());
|
||||||
callDepth.getAndIncrement();
|
callDepth.getAndIncrement();
|
||||||
|
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
|
||||||
|
|
||||||
Context currentContext = Java8BytecodeBridge.currentContext();
|
Context currentContext = Java8BytecodeBridge.currentContext();
|
||||||
Context attachedContext = helper().getServerContext(httpServletRequest);
|
Context attachedContext = helper().getServerContext(httpServletRequest);
|
||||||
if (attachedContext != null && helper().needsRescoping(currentContext, attachedContext)) {
|
Context contextToUpdate;
|
||||||
MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter);
|
|
||||||
boolean servlet = servletOrFilter instanceof Servlet;
|
requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter);
|
||||||
attachedContext =
|
if (attachedContext == null && helper().shouldStart(currentContext, requestContext)) {
|
||||||
helper().updateContext(attachedContext, httpServletRequest, mappingResolver, servlet);
|
context = helper().start(currentContext, requestContext);
|
||||||
scope = attachedContext.makeCurrent();
|
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
|
// We are inside nested servlet/filter/app-server span, don't create new span
|
||||||
return;
|
contextToUpdate = currentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachedContext != null || ServerSpan.fromContextOrNull(currentContext) != null) {
|
|
||||||
// Update context with info from current request to ensure that server span gets the best
|
// Update context with info from current request to ensure that server span gets the best
|
||||||
// possible name.
|
// possible name.
|
||||||
// In case server span was created by app server instrumentations calling updateContext
|
// In case server span was created by app server instrumentations calling updateContext
|
||||||
|
@ -65,26 +70,9 @@ public class Servlet3Advice {
|
||||||
// instrumentations for naming server span.
|
// instrumentations for naming server span.
|
||||||
MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter);
|
MappingResolver mappingResolver = Servlet3Singletons.getMappingResolver(servletOrFilter);
|
||||||
boolean servlet = servletOrFilter instanceof Servlet;
|
boolean servlet = servletOrFilter instanceof Servlet;
|
||||||
Context updatedContext =
|
contextToUpdate =
|
||||||
helper().updateContext(currentContext, httpServletRequest, mappingResolver, servlet);
|
helper().updateContext(contextToUpdate, httpServletRequest, mappingResolver, servlet);
|
||||||
if (currentContext != updatedContext) {
|
scope = contextToUpdate.makeCurrent();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter);
|
|
||||||
|
|
||||||
if (!helper().shouldStart(currentContext, requestContext)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context = helper().start(currentContext, requestContext);
|
|
||||||
scope = context.makeCurrent();
|
|
||||||
|
|
||||||
helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
|
|
@ -5,12 +5,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.servlet.v3_0;
|
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.field.VirtualField;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
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.bootstrap.servlet.MappingResolver;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
||||||
|
@ -28,11 +24,6 @@ public final class Servlet3Singletons {
|
||||||
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
||||||
INSTRUMENTER =
|
INSTRUMENTER =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.setMappingResolverFunction(Servlet3Singletons::getMappingResolver)
|
|
||||||
.addContextCustomizer(
|
|
||||||
(context, request, attributes) ->
|
|
||||||
ServerSpanNaming.init(
|
|
||||||
context, request.servletOrFilter() instanceof Servlet ? SERVLET : FILTER))
|
|
||||||
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
.build(INSTRUMENTATION_NAME, Servlet3Accessor.INSTANCE);
|
||||||
|
|
||||||
private static final ServletHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
private static final ServletHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
||||||
|
@ -47,11 +38,6 @@ public final class Servlet3Singletons {
|
||||||
return HELPER;
|
return HELPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MappingResolver getMappingResolver(
|
|
||||||
ServletRequestContext<?> servletRequestContext) {
|
|
||||||
return getMappingResolver(servletRequestContext.servletOrFilter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MappingResolver getMappingResolver(Object servletOrFilter) {
|
public static MappingResolver getMappingResolver(Object servletOrFilter) {
|
||||||
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
|
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
|
|
|
@ -5,12 +5,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.servlet.v5_0;
|
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.field.VirtualField;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
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.bootstrap.servlet.MappingResolver;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletHelper;
|
||||||
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
|
||||||
|
@ -29,11 +25,6 @@ public final class Servlet5Singletons {
|
||||||
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
|
||||||
INSTRUMENTER =
|
INSTRUMENTER =
|
||||||
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
ServletInstrumenterBuilder.<HttpServletRequest, HttpServletResponse>create()
|
||||||
.setMappingResolverFunction(Servlet5Singletons::getMappingResolver)
|
|
||||||
.addContextCustomizer(
|
|
||||||
(context, request, attributes) ->
|
|
||||||
ServerSpanNaming.init(
|
|
||||||
context, request.servletOrFilter() instanceof Servlet ? SERVLET : FILTER))
|
|
||||||
.build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE);
|
.build(INSTRUMENTATION_NAME, Servlet5Accessor.INSTANCE);
|
||||||
|
|
||||||
private static final ServletHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
private static final ServletHelper<HttpServletRequest, HttpServletResponse> HELPER =
|
||||||
|
@ -48,11 +39,6 @@ public final class Servlet5Singletons {
|
||||||
return HELPER;
|
return HELPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MappingResolver getMappingResolver(
|
|
||||||
ServletRequestContext<?> servletRequestContext) {
|
|
||||||
return getMappingResolver(servletRequestContext.servletOrFilter());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MappingResolver getMappingResolver(Object servletOrFilter) {
|
public static MappingResolver getMappingResolver(Object servletOrFilter) {
|
||||||
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
|
MappingResolver.Factory factory = getMappingResolverFactory(servletOrFilter);
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import static io.opentelemetry.javaagent.instrumentation.servlet.v5_0.Servlet5Si
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.Scope;
|
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.AppServerBridge;
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
|
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
|
||||||
|
@ -40,25 +39,31 @@ public class JakartaServletServiceAdvice {
|
||||||
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
|
|
||||||
callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey());
|
callDepth = CallDepth.forClass(AppServerBridge.getCallDepthKey());
|
||||||
callDepth.getAndIncrement();
|
callDepth.getAndIncrement();
|
||||||
|
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
|
||||||
|
|
||||||
Context currentContext = Java8BytecodeBridge.currentContext();
|
Context currentContext = Java8BytecodeBridge.currentContext();
|
||||||
Context attachedContext = helper().getServerContext(httpServletRequest);
|
Context attachedContext = helper().getServerContext(httpServletRequest);
|
||||||
if (attachedContext != null && helper().needsRescoping(currentContext, attachedContext)) {
|
Context contextToUpdate;
|
||||||
MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter);
|
|
||||||
boolean servlet = servletOrFilter instanceof Servlet;
|
requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter);
|
||||||
attachedContext =
|
if (attachedContext == null && helper().shouldStart(currentContext, requestContext)) {
|
||||||
helper().updateContext(attachedContext, httpServletRequest, mappingResolver, servlet);
|
context = helper().start(currentContext, requestContext);
|
||||||
scope = attachedContext.makeCurrent();
|
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
|
// We are inside nested servlet/filter/app-server span, don't create new span
|
||||||
return;
|
contextToUpdate = currentContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachedContext != null || ServerSpan.fromContextOrNull(currentContext) != null) {
|
|
||||||
// Update context with info from current request to ensure that server span gets the best
|
// Update context with info from current request to ensure that server span gets the best
|
||||||
// possible name.
|
// possible name.
|
||||||
// In case server span was created by app server instrumentations calling updateContext
|
// In case server span was created by app server instrumentations calling updateContext
|
||||||
|
@ -66,26 +71,9 @@ public class JakartaServletServiceAdvice {
|
||||||
// instrumentations for naming server span.
|
// instrumentations for naming server span.
|
||||||
MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter);
|
MappingResolver mappingResolver = Servlet5Singletons.getMappingResolver(servletOrFilter);
|
||||||
boolean servlet = servletOrFilter instanceof Servlet;
|
boolean servlet = servletOrFilter instanceof Servlet;
|
||||||
Context updatedContext =
|
contextToUpdate =
|
||||||
helper().updateContext(currentContext, httpServletRequest, mappingResolver, servlet);
|
helper().updateContext(contextToUpdate, httpServletRequest, mappingResolver, servlet);
|
||||||
if (currentContext != updatedContext) {
|
scope = contextToUpdate.makeCurrent();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestContext = new ServletRequestContext<>(httpServletRequest, servletOrFilter);
|
|
||||||
|
|
||||||
if (!helper().shouldStart(currentContext, requestContext)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
context = helper().start(currentContext, requestContext);
|
|
||||||
scope = context.makeCurrent();
|
|
||||||
|
|
||||||
helper().setAsyncListenerResponse(httpServletRequest, (HttpServletResponse) response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
|
|
@ -14,20 +14,16 @@ import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
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.instrumenter.http.HttpSpanStatusExtractor;
|
||||||
import io.opentelemetry.javaagent.bootstrap.servlet.MappingResolver;
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public final class ServletInstrumenterBuilder<REQUEST, RESPONSE> {
|
public final class ServletInstrumenterBuilder<REQUEST, RESPONSE> {
|
||||||
|
|
||||||
private ServletInstrumenterBuilder() {}
|
private ServletInstrumenterBuilder() {}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Function<ServletRequestContext<REQUEST>, MappingResolver> mappingResolverFunction;
|
|
||||||
|
|
||||||
private final List<ContextCustomizer<? super ServletRequestContext<REQUEST>>> contextCustomizers =
|
private final List<ContextCustomizer<? super ServletRequestContext<REQUEST>>> contextCustomizers =
|
||||||
new ArrayList<>();
|
new ArrayList<>();
|
||||||
|
|
||||||
|
@ -35,12 +31,6 @@ public final class ServletInstrumenterBuilder<REQUEST, RESPONSE> {
|
||||||
return new ServletInstrumenterBuilder<>();
|
return new ServletInstrumenterBuilder<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServletInstrumenterBuilder<REQUEST, RESPONSE> setMappingResolverFunction(
|
|
||||||
Function<ServletRequestContext<REQUEST>, MappingResolver> mappingResolverFunction) {
|
|
||||||
this.mappingResolverFunction = mappingResolverFunction;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServletInstrumenterBuilder<REQUEST, RESPONSE> addContextCustomizer(
|
public ServletInstrumenterBuilder<REQUEST, RESPONSE> addContextCustomizer(
|
||||||
ContextCustomizer<? super ServletRequestContext<REQUEST>> contextCustomizer) {
|
ContextCustomizer<? super ServletRequestContext<REQUEST>> contextCustomizer) {
|
||||||
contextCustomizers.add(contextCustomizer);
|
contextCustomizers.add(contextCustomizer);
|
||||||
|
@ -72,7 +62,8 @@ public final class ServletInstrumenterBuilder<REQUEST, RESPONSE> {
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addAttributesExtractor(netAttributesExtractor)
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
.addAttributesExtractor(additionalAttributesExtractor)
|
.addAttributesExtractor(additionalAttributesExtractor)
|
||||||
.addRequestMetrics(HttpServerMetrics.get());
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get());
|
||||||
if (ServletRequestParametersExtractor.enabled()) {
|
if (ServletRequestParametersExtractor.enabled()) {
|
||||||
AttributesExtractor<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>>
|
AttributesExtractor<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>>
|
||||||
requestParametersExtractor = new ServletRequestParametersExtractor<>(accessor);
|
requestParametersExtractor = new ServletRequestParametersExtractor<>(accessor);
|
||||||
|
@ -90,7 +81,7 @@ public final class ServletInstrumenterBuilder<REQUEST, RESPONSE> {
|
||||||
HttpServerAttributesExtractor<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>>
|
HttpServerAttributesExtractor<ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>>
|
||||||
httpAttributesExtractor = new ServletHttpAttributesExtractor<>(accessor);
|
httpAttributesExtractor = new ServletHttpAttributesExtractor<>(accessor);
|
||||||
SpanNameExtractor<ServletRequestContext<REQUEST>> spanNameExtractor =
|
SpanNameExtractor<ServletRequestContext<REQUEST>> spanNameExtractor =
|
||||||
new ServletSpanNameExtractor<>(accessor, mappingResolverFunction);
|
HttpSpanNameExtractor.create(httpAttributesExtractor);
|
||||||
|
|
||||||
return build(instrumentationName, accessor, spanNameExtractor, httpAttributesExtractor);
|
return build(instrumentationName, accessor, spanNameExtractor, httpAttributesExtractor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<REQUEST, RESPONSE>
|
|
||||||
implements SpanNameExtractor<ServletRequestContext<REQUEST>> {
|
|
||||||
private final ServletAccessor<REQUEST, RESPONSE> accessor;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private final Function<ServletRequestContext<REQUEST>, MappingResolver> mappingResolverFunction;
|
|
||||||
|
|
||||||
public ServletSpanNameExtractor(
|
|
||||||
ServletAccessor<REQUEST, RESPONSE> accessor,
|
|
||||||
@Nullable Function<ServletRequestContext<REQUEST>, MappingResolver> mappingResolverFunction) {
|
|
||||||
this.accessor = accessor;
|
|
||||||
this.mappingResolverFunction = mappingResolverFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String route(ServletRequestContext<REQUEST> 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<REQUEST> 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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,6 +13,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeader
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -73,6 +74,7 @@ public final class SpringWebMvcTracingBuilder {
|
||||||
.addAttributesExtractor(new SpringWebMvcNetAttributesExtractor())
|
.addAttributesExtractor(new SpringWebMvcNetAttributesExtractor())
|
||||||
.addAttributesExtractors(additionalExtractors)
|
.addAttributesExtractors(additionalExtractors)
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
.newServerInstrumenter(JavaxHttpServletRequestGetter.INSTANCE);
|
.newServerInstrumenter(JavaxHttpServletRequestGetter.INSTANCE);
|
||||||
|
|
||||||
return new SpringWebMvcTracing(instrumenter);
|
return new SpringWebMvcTracing(instrumenter);
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.tomcat.common;
|
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.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
|
@ -50,15 +48,13 @@ public final class TomcatInstrumenterFactory {
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addAttributesExtractor(netAttributesExtractor)
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
.addAttributesExtractor(additionalAttributeExtractor)
|
.addAttributesExtractor(additionalAttributeExtractor)
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, request, attributes) -> {
|
(context, request, attributes) ->
|
||||||
context = ServerSpanNaming.init(context, CONTAINER);
|
new AppServerBridge.Builder()
|
||||||
|
|
||||||
return new AppServerBridge.Builder()
|
|
||||||
.captureServletAttributes()
|
.captureServletAttributes()
|
||||||
.recordException()
|
.recordException()
|
||||||
.init(context);
|
.init(context))
|
||||||
})
|
|
||||||
.addRequestMetrics(HttpServerMetrics.get())
|
.addRequestMetrics(HttpServerMetrics.get())
|
||||||
.newServerInstrumenter(TomcatRequestGetter.INSTANCE);
|
.newServerInstrumenter(TomcatRequestGetter.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.undertow;
|
package io.opentelemetry.javaagent.instrumentation.undertow;
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTAINER;
|
|
||||||
|
|
||||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||||
|
@ -42,9 +40,9 @@ public final class UndertowSingletons {
|
||||||
.setSpanStatusExtractor(spanStatusExtractor)
|
.setSpanStatusExtractor(spanStatusExtractor)
|
||||||
.addAttributesExtractor(httpAttributesExtractor)
|
.addAttributesExtractor(httpAttributesExtractor)
|
||||||
.addAttributesExtractor(netAttributesExtractor)
|
.addAttributesExtractor(netAttributesExtractor)
|
||||||
|
.addContextCustomizer(ServerSpanNaming.get())
|
||||||
.addContextCustomizer(
|
.addContextCustomizer(
|
||||||
(context, request, attributes) -> {
|
(context, request, attributes) -> {
|
||||||
context = ServerSpanNaming.init(context, CONTAINER);
|
|
||||||
// span is ended when counter reaches 0, we start from 2 which accounts for the
|
// span is ended when counter reaches 0, we start from 2 which accounts for the
|
||||||
// handler that started the span and exchange completion listener
|
// handler that started the span and exchange completion listener
|
||||||
context = UndertowActiveHandlers.init(context, 2);
|
context = UndertowActiveHandlers.init(context, 2);
|
||||||
|
|
Loading…
Reference in New Issue