Instrument java.servlet.Filter directly (#1606)
* Instrument filter directly * Remove some additional ignores * Fix OncePerRequestFilter not being instrumented itself
This commit is contained in:
parent
cecdfc2cd0
commit
80b068b459
|
@ -42,7 +42,7 @@ public class Servlet2InstrumentationModule extends InstrumentationModule {
|
|||
@Override
|
||||
public List<TypeInstrumentation> typeInstrumentations() {
|
||||
return Arrays.asList(
|
||||
new HttpServletResponseInstrumentation(), new ServletAndFilterChainInstrumentation());
|
||||
new HttpServletResponseInstrumentation(), new ServletAndFilterInstrumentation());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ import net.bytebuddy.description.method.MethodDescription;
|
|||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
final class ServletAndFilterChainInstrumentation implements TypeInstrumentation {
|
||||
final class ServletAndFilterInstrumentation implements TypeInstrumentation {
|
||||
|
||||
@Override
|
||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||
|
@ -29,8 +29,7 @@ final class ServletAndFilterChainInstrumentation implements TypeInstrumentation
|
|||
|
||||
@Override
|
||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||
return safeHasSuperType(
|
||||
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
||||
return safeHasSuperType(namedOneOf("javax.servlet.Filter", "javax.servlet.http.HttpServlet"));
|
||||
}
|
||||
|
||||
/**
|
|
@ -31,6 +31,6 @@ public class Servlet3InstrumentationModule extends InstrumentationModule {
|
|||
|
||||
@Override
|
||||
public List<TypeInstrumentation> typeInstrumentations() {
|
||||
return asList(new AsyncContextInstrumentation(), new ServletAndFilterChainInstrumentation());
|
||||
return asList(new AsyncContextInstrumentation(), new ServletAndFilterInstrumentation());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import net.bytebuddy.description.method.MethodDescription;
|
|||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
final class ServletAndFilterChainInstrumentation implements TypeInstrumentation {
|
||||
final class ServletAndFilterInstrumentation implements TypeInstrumentation {
|
||||
@Override
|
||||
public ElementMatcher<ClassLoader> classLoaderMatcher() {
|
||||
// Optimization for expensive typeMatcher.
|
||||
|
@ -28,8 +28,7 @@ final class ServletAndFilterChainInstrumentation implements TypeInstrumentation
|
|||
|
||||
@Override
|
||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||
return safeHasSuperType(
|
||||
namedOneOf("javax.servlet.FilterChain", "javax.servlet.http.HttpServlet"));
|
||||
return safeHasSuperType(namedOneOf("javax.servlet.Filter", "javax.servlet.http.HttpServlet"));
|
||||
}
|
||||
|
||||
/**
|
|
@ -12,33 +12,44 @@ import io.opentelemetry.context.Context;
|
|||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
public class HandlerMappingResourceNameFilter extends OncePerRequestFilter implements Ordered {
|
||||
public class HandlerMappingResourceNameFilter implements Filter, Ordered {
|
||||
private volatile List<HandlerMapping> handlerMappings;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(
|
||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
public void init(FilterConfig filterConfig) {}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = Context.current();
|
||||
Span serverSpan = BaseTracer.getCurrentServerSpan(context);
|
||||
|
||||
if (handlerMappings != null && serverSpan != null) {
|
||||
try {
|
||||
if (findMapping(request)) {
|
||||
if (findMapping((HttpServletRequest) request)) {
|
||||
|
||||
// Name the parent span based on the matching pattern
|
||||
// Let the parent span resource name be set with the attribute set in findMapping.
|
||||
tracer().onRequest(context, serverSpan, request);
|
||||
tracer().onRequest(context, serverSpan, (HttpServletRequest) request);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// mapping.getHandler() threw exception. Ignore
|
||||
|
@ -48,6 +59,9 @@ public class HandlerMappingResourceNameFilter extends OncePerRequestFilter imple
|
|||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {}
|
||||
|
||||
/**
|
||||
* When a HandlerMapping matches a request, it sets HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE
|
||||
* as an attribute on the request. This attribute is read by SpringWebMvcDecorator.onRequest and
|
||||
|
|
|
@ -167,6 +167,7 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
|
|||
|
||||
if (name.startsWith("org.springframework.web.")) {
|
||||
if (name.startsWith("org.springframework.web.servlet.")
|
||||
|| name.startsWith("org.springframework.web.filter.")
|
||||
|| name.startsWith("org.springframework.web.reactive.")
|
||||
|| name.startsWith("org.springframework.web.context.request.async.")
|
||||
|| name.equals(
|
||||
|
@ -306,7 +307,7 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
|
|||
return false;
|
||||
}
|
||||
|
||||
private static Set<String> INSTRUMENTED_SPRING_BOOT_CLASSES =
|
||||
private static final Set<String> INSTRUMENTED_SPRING_BOOT_CLASSES =
|
||||
Sets.newHashSet(
|
||||
"org.springframework.boot.autoconfigure.BackgroundPreinitializer$",
|
||||
"org.springframework.boot.autoconfigure.condition.OnClassCondition$",
|
||||
|
@ -319,7 +320,12 @@ public class AdditionalLibraryIgnoresMatcher<T extends TypeDescription>
|
|||
"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext",
|
||||
"org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext",
|
||||
"org.springframework.boot.web.embedded.tomcat.TomcatWebServer$",
|
||||
"org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader");
|
||||
"org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader",
|
||||
"org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean$",
|
||||
"org.springframework.boot.web.filter.OrderedCharacterEncodingFilter",
|
||||
"org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter",
|
||||
"org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter",
|
||||
"org.springframework.boot.web.filter.OrderedRequestContextFilter");
|
||||
|
||||
private static String outerClassName(final String name) {
|
||||
int separator = name.indexOf('$');
|
||||
|
|
Loading…
Reference in New Issue