Reduce overhead of unsampled requests (#3681)
* Optimize sampled out requests * Comment
This commit is contained in:
parent
07250d3adc
commit
91b302a7d2
|
@ -50,7 +50,9 @@ public final class ServerSpanNaming {
|
||||||
public static void updateServerSpanName(
|
public static void updateServerSpanName(
|
||||||
Context context, Source source, Supplier<String> serverSpanName) {
|
Context context, Source source, Supplier<String> serverSpanName) {
|
||||||
Span serverSpan = ServerSpan.fromContextOrNull(context);
|
Span serverSpan = ServerSpan.fromContextOrNull(context);
|
||||||
if (serverSpan == null) {
|
// checking isRecording() is a helpful optimization for more expensive suppliers
|
||||||
|
// (e.g. Spring MVC instrumentation's HandlerAdapterInstrumentation)
|
||||||
|
if (serverSpan == null || !serverSpan.isRecording()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServerSpanNaming serverSpanNaming = context.get(CONTEXT_KEY);
|
ServerSpanNaming serverSpanNaming = context.get(CONTEXT_KEY);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTROLLER;
|
||||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
|
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
|
||||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
||||||
import static io.opentelemetry.javaagent.instrumentation.springwebmvc.SpringWebMvcSingletons.handlerInstrumenter;
|
import static io.opentelemetry.javaagent.instrumentation.springwebmvc.SpringWebMvcSingletons.handlerInstrumenter;
|
||||||
|
@ -18,6 +19,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
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.Scope;
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
||||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||||
|
@ -69,7 +71,10 @@ public class HandlerAdapterInstrumentation implements TypeInstrumentation {
|
||||||
// TODO (trask) is it important to check serverSpan != null here?
|
// TODO (trask) is it important to check serverSpan != null here?
|
||||||
if (serverSpan != null) {
|
if (serverSpan != null) {
|
||||||
// Name the parent span based on the matching pattern
|
// Name the parent span based on the matching pattern
|
||||||
ServerNameUpdater.updateServerSpanName(parentContext, request);
|
ServerSpanNaming.updateServerSpanName(
|
||||||
|
parentContext,
|
||||||
|
CONTROLLER,
|
||||||
|
SpringWebMvcServerSpanNaming.getServerSpanNameSupplier(parentContext, request));
|
||||||
// Now create a span for handler/controller execution.
|
// Now create a span for handler/controller execution.
|
||||||
context = handlerInstrumenter().start(parentContext, handler);
|
context = handlerInstrumenter().start(parentContext, handler);
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTROLLER;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -38,19 +41,20 @@ public class HandlerMappingResourceNameFilter implements Filter, Ordered {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context context = Context.current();
|
|
||||||
|
|
||||||
if (handlerMappings != null) {
|
if (handlerMappings != null) {
|
||||||
try {
|
Context context = Context.current();
|
||||||
if (findMapping((HttpServletRequest) request)) {
|
ServerSpanNaming.updateServerSpanName(
|
||||||
|
context,
|
||||||
// Name the parent span based on the matching pattern
|
CONTROLLER,
|
||||||
// Let the parent span resource name be set with the attribute set in findMapping.
|
() -> {
|
||||||
ServerNameUpdater.updateServerSpanName(context, (HttpServletRequest) request);
|
if (findMapping((HttpServletRequest) request)) {
|
||||||
}
|
// Name the parent span based on the matching pattern
|
||||||
} catch (Exception ignored) {
|
// Let the parent span resource name be set with the attribute set in findMapping.
|
||||||
// mapping.getHandler() threw exception. Ignore
|
return SpringWebMvcServerSpanNaming.getServerSpanName(
|
||||||
}
|
context, (HttpServletRequest) request);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
@ -64,12 +68,16 @@ public class HandlerMappingResourceNameFilter implements Filter, Ordered {
|
||||||
* as an attribute on the request. This attribute is read by SpringWebMvcDecorator.onRequest and
|
* as an attribute on the request. This attribute is read by SpringWebMvcDecorator.onRequest and
|
||||||
* set as the resource name.
|
* set as the resource name.
|
||||||
*/
|
*/
|
||||||
private boolean findMapping(HttpServletRequest request) throws Exception {
|
private boolean findMapping(HttpServletRequest request) {
|
||||||
for (HandlerMapping mapping : handlerMappings) {
|
try {
|
||||||
HandlerExecutionChain handler = mapping.getHandler(request);
|
for (HandlerMapping mapping : handlerMappings) {
|
||||||
if (handler != null) {
|
HandlerExecutionChain handler = mapping.getHandler(request);
|
||||||
return true;
|
if (handler != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// mapping.getHandler() threw exception. Ignore
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming.Source.CONTROLLER;
|
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServerSpanNaming;
|
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
|
||||||
|
|
||||||
public class ServerNameUpdater {
|
|
||||||
|
|
||||||
public static void updateServerSpanName(Context context, HttpServletRequest request) {
|
|
||||||
if (request != null) {
|
|
||||||
Object bestMatchingPattern =
|
|
||||||
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
|
||||||
if (bestMatchingPattern != null) {
|
|
||||||
ServerSpanNaming.updateServerSpanName(
|
|
||||||
context,
|
|
||||||
CONTROLLER,
|
|
||||||
() -> ServletContextPath.prepend(context, bestMatchingPattern.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.springwebmvc;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
||||||
|
public class SpringWebMvcServerSpanNaming {
|
||||||
|
|
||||||
|
public static Supplier<String> getServerSpanNameSupplier(
|
||||||
|
Context context, HttpServletRequest request) {
|
||||||
|
return () -> getServerSpanName(context, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getServerSpanName(Context context, HttpServletRequest request) {
|
||||||
|
Object bestMatchingPattern =
|
||||||
|
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||||
|
if (bestMatchingPattern != null) {
|
||||||
|
return ServletContextPath.prepend(context, bestMatchingPattern.toString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue