From 68a765c323f0a6ec0e48113126ba2c9e37248ce1 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Sat, 20 Mar 2021 06:24:24 +0200 Subject: [PATCH 01/11] Servlet 5.0 API support, refactored other servlet modules --- instrumentation-core/README.md | 17 -- .../servlet/ServletHttpServerTracer.java | 180 -------------- .../jaxrs-2.0-jersey-2.0-javaagent.gradle | 2 +- .../jaxrs-2.0-resteasy-3.0-javaagent.gradle | 2 +- .../jaxrs-2.0-resteasy-3.1-javaagent.gradle | 2 +- .../javaagent/jetty-8.0-javaagent.gradle | 2 +- .../jetty/JettyHttpServerTracer.java | 2 +- .../instrumentation/jetty/package-info.java | 2 +- .../javaagent/mojarra-1.2-javaagent.gradle | 2 +- .../javaagent/myfaces-1.2-javaagent.gradle | 2 +- .../javaagent/jsp-2.3-javaagent.gradle | 2 +- .../liberty/LibertyHttpServerTracer.java | 2 +- instrumentation/servlet/README.md | 25 +- .../glassfish-testing.gradle | 2 +- .../javaagent/servlet-2.2-javaagent.gradle | 5 +- .../servlet/v2_2/Servlet2Advice.java | 3 +- .../v2_2/Servlet2InstrumentationModule.java | 6 +- .../library/servlet-2.2-library.gradle | 12 + .../servlet/v2_2/ResponseWithStatus.java | 6 +- .../servlet/v2_2/Servlet2Accessor.java | 30 +++ .../v2_2/Servlet2HttpServerTracer.java | 24 +- .../javaagent/servlet-3.0-javaagent.gradle | 5 +- .../v3_0/AsyncContextInstrumentation.java | 87 ------- .../servlet/v3_0/AsyncDispatchAdvice.java | 51 ++++ .../servlet/v3_0/Servlet3Advice.java | 6 +- .../v3_0/Servlet3InstrumentationModule.java | 12 +- .../servlet/v3_0/TagSettingAsyncListener.java | 1 + .../library/servlet-3.0-library.gradle | 10 + .../servlet/v3_0/Servlet3Accessor.java | 31 +++ .../v3_0/Servlet3HttpServerTracer.java | 62 +---- .../javaagent/servlet-common-javaagent.gradle | 25 +- .../async/AsyncContextInstrumentation.java | 44 ++++ .../RequestDispatcherAdviceHelper.java | 74 ++++++ .../RequestDispatcherInstrumentation.java | 52 ++++ ...equestDispatcherInstrumentationModule.java | 159 ------------ ...pServletResponseInstrumentationModule.java | 97 -------- .../HttpServletResponseAdviceHelper.java | 34 +++ .../HttpServletResponseInstrumentation.java} | 27 ++- .../ServletAndFilterInstrumentation.java | 19 +- .../library/servlet-common-library.gradle | 8 + .../servlet}/MappingResolver.java | 2 +- .../servlet/ServletAccessor.java | 46 ++++ .../servlet/ServletHttpServerTracer.java | 227 ++++++++++++++++++ .../servlet-jakarta-javaagent.gradle | 15 ++ .../JakartaServletInstrumentationModule.java | 50 ++++ .../servlet/async/AsyncDispatchAdvice.java | 51 ++++ .../dispatcher/RequestDispatcherAdvice.java | 69 ++++++ .../dispatcher/RequestDispatcherTracer.java | 2 +- .../servlet/response/ResponseSendAdvice.java | 45 ++++ .../servlet/response/ResponseTracer.java} | 10 +- .../service/JakartaServletServiceAdvice.java | 132 ++++++++++ .../service/TagSettingAsyncListener.java | 54 +++++ .../library/servlet-jakarta-library.gradle | 14 ++ .../JakartaHttpServletRequestGetter.java | 26 ++ .../jakarta/JakartaServletAccessor.java | 109 +++++++++ .../JakartaServletHttpServerTracer.java | 143 +++++++++++ .../JakartaServletHttpServerTracerTest.java | 69 ++++++ .../servlet-javax-common-javaagent.gradle | 30 +++ .../javax/JavaxCommonServletAccessor.java | 30 +++ .../JavaxServletInstrumentationModule.java | 44 ++++ .../dispatcher/RequestDispatcherAdvice.java | 71 ++++++ .../dispatcher/RequestDispatcherTracer.java | 27 +++ .../javax/response/ResponseSendAdvice.java | 46 ++++ .../javax/response/ResponseTracer.java | 27 +++ .../groovy/HttpServletResponseTest.groovy | 0 .../test/groovy/RequestDispatcherTest.groovy | 0 .../src/test/java/RequestDispatcherUtils.java | 0 .../servlet-javax-common-library.gradle | 4 +- .../javax/JavaxHttpServletRequestGetter.java | 6 +- .../servlet/javax/JavaxServletAccessor.java | 89 +++++++ .../javax/JavaxServletHttpServerTracer.java | 22 ++ .../src/test/java/RequestOnlyTracer.java | 35 +++ .../java}/ServletHttpServerTracerTest.java | 16 +- .../spring-webmvc-3.1-javaagent.gradle | 2 +- .../library/spring-webmvc-3.1-library.gradle | 3 +- .../webmvc/SpringWebMvcServerTracer.java | 4 +- .../javaagent/struts-2.3-javaagent.gradle | 2 +- .../javaagent/tomcat-7.0-javaagent.gradle | 2 +- .../javaagent/wicket-8.0-javaagent.gradle | 2 +- settings.gradle | 9 +- smoke-tests/matrix/build.gradle | 11 +- .../matrix/servlet-jakarta/build.gradle | 15 ++ .../matrix/AsyncGreetingServlet.java | 54 +++++ .../matrix/ExceptionRequestListener.java | 21 ++ .../smoketest/matrix/ExceptionServlet.java | 19 ++ .../smoketest/matrix/ForwardServlet.java | 21 ++ .../smoketest/matrix/GreetingServlet.java | 50 ++++ .../matrix/HeaderDumpingServlet.java | 42 ++++ .../smoketest/matrix/IncludeServlet.java | 21 ++ .../smoketest/matrix/JspServlet.java | 23 ++ .../src/main/webapp/WEB-INF/web.xml | 66 +++++ .../servlet-jakarta/src/main/webapp/hello.txt | 1 + .../servlet-jakarta/src/main/webapp/test.jsp | 10 + smoke-tests/matrix/settings.gradle | 2 + 94 files changed, 2311 insertions(+), 714 deletions(-) delete mode 100644 instrumentation-core/README.md delete mode 100644 instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java create mode 100644 instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle rename instrumentation/servlet/servlet-2.2/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/servlet/v2_2/ResponseWithStatus.java (77%) create mode 100644 instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2Accessor.java rename instrumentation/servlet/servlet-2.2/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java (67%) delete mode 100644 instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncContextInstrumentation.java create mode 100644 instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncDispatchAdvice.java create mode 100644 instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle create mode 100644 instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3Accessor.java rename instrumentation/servlet/servlet-3.0/{javaagent/src/main/java/io/opentelemetry/javaagent => library/src/main/java/io/opentelemetry}/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java (66%) create mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java create mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java create mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java delete mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentationModule.java delete mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseInstrumentationModule.java create mode 100644 instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java rename instrumentation/servlet/{servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/ServletAndFilterInstrumentation.java => servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java} (56%) rename instrumentation/servlet/{servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2 => servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service}/ServletAndFilterInstrumentation.java (66%) create mode 100644 instrumentation/servlet/servlet-common/library/servlet-common-library.gradle rename instrumentation/servlet/{servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0 => servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet}/MappingResolver.java (98%) create mode 100644 instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java create mode 100644 instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java rename instrumentation/servlet/{servlet-common => servlet-jakarta}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java (92%) create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java rename instrumentation/servlet/{servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseTracer.java => servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java} (55%) create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java create mode 100644 instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java create mode 100644 instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle create mode 100644 instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java create mode 100644 instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java create mode 100644 instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java create mode 100644 instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/servlet-javax-common-javaagent.gradle create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java create mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseTracer.java rename instrumentation/servlet/{servlet-common => servlet-javax-common}/javaagent/src/test/groovy/HttpServletResponseTest.groovy (100%) rename instrumentation/servlet/{servlet-common => servlet-javax-common}/javaagent/src/test/groovy/RequestDispatcherTest.groovy (100%) rename instrumentation/servlet/{servlet-common => servlet-javax-common}/javaagent/src/test/java/RequestDispatcherUtils.java (100%) rename instrumentation-core/servlet-2.2/servlet-2.2.gradle => instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle (78%) rename instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/HttpServletRequestGetter.java => instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxHttpServletRequestGetter.java (65%) create mode 100644 instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java create mode 100644 instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletHttpServerTracer.java create mode 100644 instrumentation/servlet/servlet-javax-common/library/src/test/java/RequestOnlyTracer.java rename {instrumentation-core/servlet-2.2/src/test/java/io/opentelemetry/instrumentation/servlet => instrumentation/servlet/servlet-javax-common/library/src/test/java}/ServletHttpServerTracerTest.java (79%) create mode 100644 smoke-tests/matrix/servlet-jakarta/build.gradle create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt create mode 100644 smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp diff --git a/instrumentation-core/README.md b/instrumentation-core/README.md deleted file mode 100644 index 067aaef2435a..000000000000 --- a/instrumentation-core/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Instrumentation Core - -These modules for the core logic for library instrumentation. [instrumentation](../instrumentation) -should add core logic here which can be set up manually by a user, and agent-specific code -for automatically setting up the instrumentation in that folder. - -Note, we are currently working on separating instrumentation projects so that their core parts can -be accessed by users not using the agent. Due to the current Gradle setup, we have these two top-level -folders, instrumentation and instrumentation-core, but eventually we want to move to flattening them -into something like - -``` -instrumentation/ - aws-sdk/ - aws-sdk-2.2/ - auto/ -``` diff --git a/instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java b/instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java deleted file mode 100644 index 227f3ab0e852..000000000000 --- a/instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.servlet; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.propagation.TextMapGetter; -import io.opentelemetry.instrumentation.api.servlet.AppServerBridge; -import io.opentelemetry.instrumentation.api.servlet.ServletContextPath; -import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; -import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.Principal; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class ServletHttpServerTracer - extends HttpServerTracer { - - private static final Logger log = LoggerFactory.getLogger(ServletHttpServerTracer.class); - - public Context startSpan(HttpServletRequest request, String spanName) { - Context context = startSpan(request, request, request, spanName); - - SpanContext spanContext = Span.fromContext(context).getSpanContext(); - // we do this e.g. so that servlet containers can use these values in their access logs - request.setAttribute("trace_id", spanContext.getTraceId()); - request.setAttribute("span_id", spanContext.getSpanId()); - - return context; - } - - @Override - protected Context customizeContext(Context context, HttpServletRequest request) { - // add context for tracking whether servlet instrumentation has updated - // server span - context = ServletSpanNaming.init(context); - // add context for current request's context path - return addServletContextPath(context, request); - } - - private static Context addServletContextPath(Context context, HttpServletRequest request) { - String contextPath = request.getContextPath(); - if (contextPath != null && !contextPath.isEmpty() && !contextPath.equals("/")) { - return context.with(ServletContextPath.CONTEXT_KEY, contextPath); - } - return context; - } - - @Override - public void endExceptionally( - Context context, Throwable throwable, RESPONSE response, long timestamp) { - if (isResponseCommitted(response)) { - super.endExceptionally(context, throwable, response, timestamp); - } else { - // passing null response to super, in order to capture as 500 / INTERNAL, due to servlet spec - // https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf: - // "If a servlet generates an error that is not handled by the error page mechanism as - // described above, the container must ensure to send a response with status 500." - super.endExceptionally(context, throwable, null, timestamp); - } - } - - protected abstract boolean isResponseCommitted(RESPONSE response); - - @Override - protected String url(HttpServletRequest httpServletRequest) { - try { - return new URI( - httpServletRequest.getScheme(), - null, - httpServletRequest.getServerName(), - httpServletRequest.getServerPort(), - httpServletRequest.getRequestURI(), - httpServletRequest.getQueryString(), - null) - .toString(); - } catch (URISyntaxException e) { - log.debug("Failed to construct request URI", e); - return null; - } - } - - @Override - public Context getServerContext(HttpServletRequest request) { - Object context = request.getAttribute(CONTEXT_ATTRIBUTE); - return context instanceof Context ? (Context) context : null; - } - - @Override - protected void attachServerContext(Context context, HttpServletRequest request) { - request.setAttribute(CONTEXT_ATTRIBUTE, context); - } - - @Override - protected Integer peerPort(HttpServletRequest connection) { - // HttpServletResponse doesn't have accessor for remote port prior to Servlet spec 3.0 - return null; - } - - @Override - protected String peerHostIP(HttpServletRequest connection) { - return connection.getRemoteAddr(); - } - - @Override - protected String method(HttpServletRequest request) { - return request.getMethod(); - } - - @Override - protected TextMapGetter getGetter() { - return HttpServletRequestGetter.GETTER; - } - - public void addUnwrappedThrowable(Context context, Throwable throwable) { - if (AppServerBridge.shouldRecordException(context)) { - onException(context, throwable); - } - } - - @Override - protected Throwable unwrapThrowable(Throwable throwable) { - if (throwable.getCause() != null && throwable instanceof ServletException) { - throwable = throwable.getCause(); - } - return super.unwrapThrowable(throwable); - } - - public void setPrincipal(Context context, HttpServletRequest request) { - Principal principal = request.getUserPrincipal(); - if (principal != null) { - Span.fromContext(context).setAttribute(SemanticAttributes.ENDUSER_ID, principal.getName()); - } - } - - @Override - protected String flavor(HttpServletRequest connection, HttpServletRequest request) { - return connection.getProtocol(); - } - - @Override - protected String requestHeader(HttpServletRequest httpServletRequest, String name) { - return httpServletRequest.getHeader(name); - } - - public static String getSpanName(HttpServletRequest request) { - String servletPath = request.getServletPath(); - if (servletPath.isEmpty()) { - return "HTTP " + request.getMethod(); - } - String contextPath = request.getContextPath(); - if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { - return servletPath; - } - return contextPath + servletPath; - } - - /** - * When server spans are managed by app server instrumentation we need to add context path of - * current request to context if it isn't already added. Servlet instrumentation adds it when it - * starts server span. - */ - public Context updateContext(Context context, HttpServletRequest request) { - String contextPath = context.get(ServletContextPath.CONTEXT_KEY); - if (contextPath == null) { - context = addServletContextPath(context, request); - } - - return context; - } -} diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-jersey-2.0/javaagent/jaxrs-2.0-jersey-2.0-javaagent.gradle b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-jersey-2.0/javaagent/jaxrs-2.0-jersey-2.0-javaagent.gradle index ff4cb569cb85..d129e09016fa 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-jersey-2.0/javaagent/jaxrs-2.0-jersey-2.0-javaagent.gradle +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-jersey-2.0/javaagent/jaxrs-2.0-jersey-2.0-javaagent.gradle @@ -17,7 +17,7 @@ dependencies { implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent') testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing') diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.0/javaagent/jaxrs-2.0-resteasy-3.0-javaagent.gradle b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.0/javaagent/jaxrs-2.0-resteasy-3.0-javaagent.gradle index 3752d193d57f..0a6cd996beba 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.0/javaagent/jaxrs-2.0-resteasy-3.0-javaagent.gradle +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.0/javaagent/jaxrs-2.0-resteasy-3.0-javaagent.gradle @@ -27,7 +27,7 @@ dependencies { implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent') testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing') diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.1/javaagent/jaxrs-2.0-resteasy-3.1-javaagent.gradle b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.1/javaagent/jaxrs-2.0-resteasy-3.1-javaagent.gradle index 81c67bd2c5f5..d70ca52f1383 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.1/javaagent/jaxrs-2.0-resteasy-3.1-javaagent.gradle +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-resteasy-3.1/javaagent/jaxrs-2.0-resteasy-3.1-javaagent.gradle @@ -27,7 +27,7 @@ dependencies { implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent') testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing') diff --git a/instrumentation/jetty-8.0/javaagent/jetty-8.0-javaagent.gradle b/instrumentation/jetty-8.0/javaagent/jetty-8.0-javaagent.gradle index a0a3ad130678..e7dc46d45847 100644 --- a/instrumentation/jetty-8.0/javaagent/jetty-8.0-javaagent.gradle +++ b/instrumentation/jetty-8.0/javaagent/jetty-8.0-javaagent.gradle @@ -13,7 +13,7 @@ muzzle { dependencies { library group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901' implementation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') // Don't want to conflict with jetty from the test server. testImplementation(project(':testing-common')) { diff --git a/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/JettyHttpServerTracer.java b/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/JettyHttpServerTracer.java index b3fb65ecf984..aedfa4b70861 100644 --- a/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/JettyHttpServerTracer.java +++ b/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/JettyHttpServerTracer.java @@ -7,7 +7,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.servlet.AppServerBridge; -import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer; +import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer; import javax.servlet.http.HttpServletRequest; public class JettyHttpServerTracer extends Servlet3HttpServerTracer { diff --git a/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/package-info.java b/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/package-info.java index 748bfce2eacc..22315b936201 100644 --- a/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/package-info.java +++ b/instrumentation/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/package-info.java @@ -11,6 +11,6 @@ * has its own {@code JettyHandlerInstrumentation} and {@code JettyHandlerAdvice}. But this is the * only difference between two instrumentations, thus {@link * io.opentelemetry.javaagent.instrumentation.jetty.JettyHttpServerTracer} is a very thin subclass - * of {@link io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer}. + * of {@link io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer}. */ package io.opentelemetry.javaagent.instrumentation.jetty; diff --git a/instrumentation/jsf/mojarra-1.2/javaagent/mojarra-1.2-javaagent.gradle b/instrumentation/jsf/mojarra-1.2/javaagent/mojarra-1.2-javaagent.gradle index 59b427227976..1cd383eb74d2 100644 --- a/instrumentation/jsf/mojarra-1.2/javaagent/mojarra-1.2-javaagent.gradle +++ b/instrumentation/jsf/mojarra-1.2/javaagent/mojarra-1.2-javaagent.gradle @@ -61,7 +61,7 @@ dependencies { testImplementation project(':instrumentation:jsf:jsf-testing-common') testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') mojarra12TestImplementation group: 'javax.faces', name: 'jsf-impl', version: '1.2-20' mojarra12TestImplementation group: 'javax.faces', name: 'jsf-api', version: '1.2' diff --git a/instrumentation/jsf/myfaces-1.2/javaagent/myfaces-1.2-javaagent.gradle b/instrumentation/jsf/myfaces-1.2/javaagent/myfaces-1.2-javaagent.gradle index 7b34878bbe22..a05c9397281c 100644 --- a/instrumentation/jsf/myfaces-1.2/javaagent/myfaces-1.2-javaagent.gradle +++ b/instrumentation/jsf/myfaces-1.2/javaagent/myfaces-1.2-javaagent.gradle @@ -30,7 +30,7 @@ dependencies { testImplementation project(':instrumentation:jsf:jsf-testing-common') testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') myfaces12TestImplementation group: 'org.apache.myfaces.core', name: 'myfaces-impl', version: '1.2.12' myfaces12TestImplementation group: 'com.sun.facelets', name: 'jsf-facelets', version: '1.1.14' diff --git a/instrumentation/jsp-2.3/javaagent/jsp-2.3-javaagent.gradle b/instrumentation/jsp-2.3/javaagent/jsp-2.3-javaagent.gradle index d7d39bf0900e..2edef49e83c0 100644 --- a/instrumentation/jsp-2.3/javaagent/jsp-2.3-javaagent.gradle +++ b/instrumentation/jsp-2.3/javaagent/jsp-2.3-javaagent.gradle @@ -18,7 +18,7 @@ dependencies { compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0' testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') // using tomcat 7.0.37 because there seems to be some issues with Tomcat's jar scanning in versions < 7.0.37 // https://stackoverflow.com/questions/23484098/org-apache-tomcat-util-bcel-classfile-classformatexception-invalid-byte-tag-in diff --git a/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyHttpServerTracer.java b/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyHttpServerTracer.java index 81607e36abf6..be8f4cffbccd 100644 --- a/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyHttpServerTracer.java +++ b/instrumentation/liberty/liberty/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/LibertyHttpServerTracer.java @@ -6,7 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.liberty; import io.opentelemetry.context.Context; -import io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer; +import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer; import javax.servlet.http.HttpServletRequest; public class LibertyHttpServerTracer extends Servlet3HttpServerTracer { diff --git a/instrumentation/servlet/README.md b/instrumentation/servlet/README.md index 6c69f479c19d..f56601113a64 100644 --- a/instrumentation/servlet/README.md +++ b/instrumentation/servlet/README.md @@ -2,15 +2,24 @@ ## A word about version -We support Servlet API starting from version 2.2. +We support Servlet API starting from version 2.2. But various instrumentations apply to different versions of the API. -They are divided into 3 sub-modules: -`servlet-common` contains instrumentations applicable to all API versions that we support. - -`servlet-2.2` contains instrumentations applicable to Servlet API 2.2, but not to 3+. - -`servlet-3.0` contains instrumentations that require Servlet API 3.0 or newer. +They are divided into the following sub-modules: +- `servlet-common` contains shared code for both `javax.servlet` and `jakarta.servlet` packages + - `library` contains the abstract tracer applicable to all servlet versions given an + implementation of `ServletAccessor` to access request and response objects of the specific + version + - `javaagent` contains shared type instrumentations which can be used by version specific modules + by specifying the base package and advice class to use with them. Contains some helper classes + used by advices to reduce code duplication. It does not define any instrumentation modules and + is used only as a dependency for other `javaagent` modules. +- Version-specific modules where `library` contains the version-specific tracer and request/response + accessor, and `javaagent` contains the instrumentation modules and advices. + - `servlet-javax-common` contains instrumentations/abstract tracer common for Servlet API versions `[2.2, 5)` + - `servlet-2.2` contains instrumentations/tracer for Servlet API versions `[2.2, 3)` + - `servlet-3.0` contains instrumentations/tracer for Servlet API versions `[3.0, 5)` + - `servlet-jakarta` contains instrumentations/tracer for Servlet API versions `[5,)` ## Implementation details @@ -49,7 +58,7 @@ This is the main target for `Servlet3Instrumentation` and `Servlet2Instrumentati `public void javax.servlet.http.HttpServlet#service(ServletRequest, ServletResponse)`. -These instrumentations are located in two separate submodules `servlet-3.0` and `servlet-2.2`, +These instrumentations are located in separate submodules `servlet-3.0`, `servlet-2.2` and `servlet-jakarta`, because they and corresponding tests depend on different versions of the servlet specification. At last, request processing may reach the specific framework that your application uses. diff --git a/instrumentation/servlet/glassfish-testing/glassfish-testing.gradle b/instrumentation/servlet/glassfish-testing/glassfish-testing.gradle index 65bed64a6c8c..e5c7bfcaff14 100644 --- a/instrumentation/servlet/glassfish-testing/glassfish-testing.gradle +++ b/instrumentation/servlet/glassfish-testing/glassfish-testing.gradle @@ -7,7 +7,7 @@ apply from: "$rootDir/gradle/instrumentation.gradle" dependencies { testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testInstrumentation project(':instrumentation:grizzly-2.0:javaagent') testLibrary group: 'org.glassfish.main.extras', name: 'glassfish-embedded-all', version: '4.0' diff --git a/instrumentation/servlet/servlet-2.2/javaagent/servlet-2.2-javaagent.gradle b/instrumentation/servlet/servlet-2.2/javaagent/servlet-2.2-javaagent.gradle index 2184c396cb81..6a29abebbd45 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/servlet-2.2-javaagent.gradle +++ b/instrumentation/servlet/servlet-2.2/javaagent/servlet-2.2-javaagent.gradle @@ -17,9 +17,10 @@ muzzle { dependencies { compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.2' - api(project(':instrumentation-core:servlet-2.2')) + api(project(':instrumentation:servlet:servlet-2.2:library')) + implementation(project(':instrumentation:servlet:servlet-common:javaagent')) - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testImplementation(project(':testing-common')) { exclude group: 'org.eclipse.jetty', module: 'jetty-server' diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Advice.java b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Advice.java index cec55b4bb9d2..35f45a7fd99a 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Advice.java +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2Advice.java @@ -5,11 +5,12 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; -import static io.opentelemetry.javaagent.instrumentation.servlet.v2_2.Servlet2HttpServerTracer.tracer; +import static io.opentelemetry.instrumentation.servlet.v2_2.Servlet2HttpServerTracer.tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.servlet.AppServerBridge; +import io.opentelemetry.instrumentation.servlet.v2_2.ResponseWithStatus; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java index 86d728547a66..77bf0831b2f7 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java @@ -10,6 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not; import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; @@ -32,7 +33,10 @@ public ElementMatcher.Junction classLoaderMatcher() { @Override public List typeInstrumentations() { return Arrays.asList( - new HttpServletResponseInstrumentation(), new ServletAndFilterInstrumentation()); + new HttpServletResponseInstrumentation(), + new ServletAndFilterInstrumentation( + "javax.servlet", + Servlet2InstrumentationModule.class.getPackage().getName() + ".Servlet2Advice")); } @Override diff --git a/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle b/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle new file mode 100644 index 000000000000..e10c3dbc8c80 --- /dev/null +++ b/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle @@ -0,0 +1,12 @@ +apply from: "$rootDir/gradle/instrumentation-library.gradle" + +// need to override archivesBaseName set in instrumentation-library.gradle +archivesBaseName = "servlet-2.2" + +dependencies { + implementation deps.slf4j + + api(project(':instrumentation:servlet:servlet-javax-common:library')) + + compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.2' +} diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ResponseWithStatus.java b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/ResponseWithStatus.java similarity index 77% rename from instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ResponseWithStatus.java rename to instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/ResponseWithStatus.java index ebd48e43a11e..64bb260b668d 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ResponseWithStatus.java +++ b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/ResponseWithStatus.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; +package io.opentelemetry.instrumentation.servlet.v2_2; import javax.servlet.http.HttpServletResponse; @@ -17,11 +17,11 @@ public ResponseWithStatus(HttpServletResponse response, int status) { this.status = status; } - HttpServletResponse getResponse() { + public HttpServletResponse getResponse() { return response; } - int getStatus() { + public int getStatus() { return status; } } diff --git a/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2Accessor.java b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2Accessor.java new file mode 100644 index 000000000000..c208a73fc8ee --- /dev/null +++ b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2Accessor.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.v2_2; + +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; +import javax.servlet.http.HttpServletRequest; + +public class Servlet2Accessor extends JavaxServletAccessor { + public static final Servlet2Accessor INSTANCE = new Servlet2Accessor(); + + private Servlet2Accessor() {} + + @Override + public Integer getRequestRemotePort(HttpServletRequest httpServletRequest) { + return null; + } + + @Override + public int getResponseStatus(ResponseWithStatus responseWithStatus) { + return responseWithStatus.getStatus(); + } + + @Override + public boolean isResponseCommitted(ResponseWithStatus responseWithStatus) { + return responseWithStatus.getResponse().isCommitted(); + } +} diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java similarity index 67% rename from instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java rename to instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java index 9d0653c81a33..600e2bd92581 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java +++ b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java @@ -3,17 +3,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; +package io.opentelemetry.instrumentation.servlet.v2_2; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; import io.opentelemetry.instrumentation.api.tracer.ServerSpan; -import io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer; +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletHttpServerTracer; import javax.servlet.http.HttpServletRequest; -public class Servlet2HttpServerTracer extends ServletHttpServerTracer { - private static final Servlet2HttpServerTracer TRACER = new Servlet2HttpServerTracer(); +public class Servlet2HttpServerTracer extends JavaxServletHttpServerTracer { + private static final Servlet2HttpServerTracer TRACER = + new Servlet2HttpServerTracer(Servlet2Accessor.INSTANCE); + + public Servlet2HttpServerTracer(JavaxServletAccessor accessor) { + super(accessor); + } public static Servlet2HttpServerTracer tracer() { return TRACER; @@ -41,14 +47,4 @@ public Context updateContext(Context context, HttpServletRequest request) { protected String getInstrumentationName() { return "io.opentelemetry.javaagent.servlet-2.2"; } - - @Override - protected int responseStatus(ResponseWithStatus responseWithStatus) { - return responseWithStatus.getStatus(); - } - - @Override - protected boolean isResponseCommitted(ResponseWithStatus responseWithStatus) { - return responseWithStatus.getResponse().isCommitted(); - } } diff --git a/instrumentation/servlet/servlet-3.0/javaagent/servlet-3.0-javaagent.gradle b/instrumentation/servlet/servlet-3.0/javaagent/servlet-3.0-javaagent.gradle index fbb6e8ef50ea..e2014854d87b 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/servlet-3.0-javaagent.gradle +++ b/instrumentation/servlet/servlet-3.0/javaagent/servlet-3.0-javaagent.gradle @@ -16,10 +16,11 @@ muzzle { dependencies { compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1' - api(project(':instrumentation-core:servlet-2.2')) + api(project(':instrumentation:servlet:servlet-3.0:library')) + implementation(project(':instrumentation:servlet:servlet-common:javaagent')) testInstrumentation project(':instrumentation:jetty-8.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testImplementation(project(':testing-common')) { exclude group: 'org.eclipse.jetty', module: 'jetty-server' diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncContextInstrumentation.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncContextInstrumentation.java deleted file mode 100644 index 8472e18bdcae..000000000000 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncContextInstrumentation.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; - -import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; -import static java.util.Collections.singletonMap; -import static net.bytebuddy.matcher.ElementMatchers.isMethod; -import static net.bytebuddy.matcher.ElementMatchers.isPublic; -import static net.bytebuddy.matcher.ElementMatchers.named; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Context; -import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; -import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.tooling.TypeInstrumentation; -import java.util.Map; -import javax.servlet.AsyncContext; -import javax.servlet.ServletRequest; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.matcher.ElementMatcher; - -public class AsyncContextInstrumentation implements TypeInstrumentation { - - @Override - public ElementMatcher classLoaderOptimization() { - return hasClassesNamed("javax.servlet.AsyncContext"); - } - - @Override - public ElementMatcher typeMatcher() { - return implementsInterface(named("javax.servlet.AsyncContext")); - } - - @Override - public Map, String> transformers() { - return singletonMap( - isMethod().and(isPublic()).and(named("dispatch")), - AsyncContextInstrumentation.class.getName() + "$DispatchAdvice"); - } - - /** - * When a request is dispatched, we want new request to have propagation headers from its parent - * request. The parent request's span is later closed by {@code - * TagSettingAsyncListener#onStartAsync} - */ - public static class DispatchAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static boolean enter( - @Advice.This AsyncContext context, @Advice.AllArguments Object[] args) { - int depth = CallDepthThreadLocalMap.incrementCallDepth(AsyncContext.class); - if (depth > 0) { - return false; - } - - ServletRequest request = context.getRequest(); - - Context currentContext = Java8BytecodeBridge.currentContext(); - Span currentSpan = Java8BytecodeBridge.spanFromContext(currentContext); - if (currentSpan.getSpanContext().isValid()) { - // this tells the dispatched servlet to use the current span as the parent for its work - // (if the currentSpan is not valid for some reason, the original servlet span should still - // be present in the same request attribute, and so that will be used) - // - // the original servlet span stored in the same request attribute does not need to be saved - // and restored on method exit, because dispatch() hands off control of the request - // processing, and nothing can be done with the request anymore after this - request.setAttribute(CONTEXT_ATTRIBUTE, currentContext); - } - - return true; - } - - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void exit(@Advice.Enter boolean topLevel) { - if (topLevel) { - CallDepthThreadLocalMap.reset(AsyncContext.class); - } - } - } -} diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncDispatchAdvice.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncDispatchAdvice.java new file mode 100644 index 000000000000..bda3cfbbbb6d --- /dev/null +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/AsyncDispatchAdvice.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; + +import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import javax.servlet.AsyncContext; +import javax.servlet.ServletRequest; +import net.bytebuddy.asm.Advice; + +public class AsyncDispatchAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static boolean enter( + @Advice.This AsyncContext context, @Advice.AllArguments Object[] args) { + int depth = CallDepthThreadLocalMap.incrementCallDepth(AsyncContext.class); + if (depth > 0) { + return false; + } + + ServletRequest request = context.getRequest(); + + Context currentContext = Java8BytecodeBridge.currentContext(); + Span currentSpan = Java8BytecodeBridge.spanFromContext(currentContext); + if (currentSpan.getSpanContext().isValid()) { + // this tells the dispatched servlet to use the current span as the parent for its work + // (if the currentSpan is not valid for some reason, the original servlet span should still + // be present in the same request attribute, and so that will be used) + // + // the original servlet span stored in the same request attribute does not need to be saved + // and restored on method exit, because dispatch() hands off control of the request + // processing, and nothing can be done with the request anymore after this + request.setAttribute(CONTEXT_ATTRIBUTE, currentContext); + } + + return true; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void exit(@Advice.Enter boolean topLevel) { + if (topLevel) { + CallDepthThreadLocalMap.reset(AsyncContext.class); + } + } +} 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 c7c7160bdb4f..0260d4bcd2da 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 @@ -5,7 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; -import static io.opentelemetry.javaagent.instrumentation.servlet.v3_0.Servlet3HttpServerTracer.tracer; +import static io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer.tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; @@ -39,7 +39,7 @@ public static void onEnter( Context attachedContext = tracer().getServerContext(httpServletRequest); if (attachedContext != null) { // We are inside nested servlet/filter/app-server span, don't create new span - if (Servlet3HttpServerTracer.needsRescoping(attachedContext)) { + if (tracer().needsRescoping(attachedContext)) { attachedContext = tracer().updateContext(attachedContext, servletOrFilter, httpServletRequest); scope = attachedContext.makeCurrent(); @@ -129,4 +129,4 @@ public static void stopSpan( tracer().end(context, (HttpServletResponse) response); } } -} +} \ No newline at end of file diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java index 4cb5923af41f..082d2e63c517 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java @@ -8,18 +8,28 @@ import static java.util.Arrays.asList; import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.instrumentation.servlet.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.List; @AutoService(InstrumentationModule.class) public class Servlet3InstrumentationModule extends InstrumentationModule { + private static final String BASE_PACKAGE = "javax.servlet"; + public Servlet3InstrumentationModule() { super("servlet", "servlet-3.0"); } @Override public List typeInstrumentations() { - return asList(new AsyncContextInstrumentation(), new ServletAndFilterInstrumentation()); + return asList( + new AsyncContextInstrumentation(BASE_PACKAGE, adviceClassName(".AsyncDispatchAdvice")), + new ServletAndFilterInstrumentation(BASE_PACKAGE, adviceClassName(".Servlet3Advice"))); + } + + private static String adviceClassName(String suffix) { + return Servlet3InstrumentationModule.class.getPackage().getName() + suffix; } } diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java index bf47b1edb3e4..181dbd8ec947 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.servlet.v3_0.Servlet3HttpServerTracer; import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; diff --git a/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle b/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle new file mode 100644 index 000000000000..0b60f6200974 --- /dev/null +++ b/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle @@ -0,0 +1,10 @@ +apply from: "$rootDir/gradle/instrumentation-library.gradle" + +// need to override archivesBaseName set in instrumentation-library.gradle +archivesBaseName = "servlet-3.0" + +dependencies { + api(project(':instrumentation:servlet:servlet-javax-common:library')) + + compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1' +} diff --git a/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3Accessor.java b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3Accessor.java new file mode 100644 index 000000000000..3c9a63680b22 --- /dev/null +++ b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3Accessor.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.v3_0; + +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class Servlet3Accessor extends JavaxServletAccessor { + public static final Servlet3Accessor INSTANCE = new Servlet3Accessor(); + + private Servlet3Accessor() {} + + @Override + public Integer getRequestRemotePort(HttpServletRequest request) { + return request.getRemotePort(); + } + + @Override + public int getResponseStatus(HttpServletResponse response) { + return response.getStatus(); + } + + @Override + public boolean isResponseCommitted(HttpServletResponse response) { + return response.isCommitted(); + } +} diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java similarity index 66% rename from instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java rename to instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java index 94f015805a6f..74b50b93ba14 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java +++ b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java @@ -3,15 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; +package io.opentelemetry.instrumentation.servlet.v3_0; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.config.Config; import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; import io.opentelemetry.instrumentation.api.tracer.ServerSpan; -import io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer; +import io.opentelemetry.instrumentation.servlet.MappingResolver; +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletHttpServerTracer; import java.util.Collection; import javax.servlet.Servlet; import javax.servlet.ServletConfig; @@ -20,14 +19,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -public class Servlet3HttpServerTracer extends ServletHttpServerTracer { - - private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES = - Config.get() - .getBooleanProperty("otel.instrumentation.servlet.experimental-span-attributes", false); - +public class Servlet3HttpServerTracer extends JavaxServletHttpServerTracer { private static final Servlet3HttpServerTracer TRACER = new Servlet3HttpServerTracer(); + public Servlet3HttpServerTracer() { + super(Servlet3Accessor.INSTANCE); + } + public static Servlet3HttpServerTracer tracer() { return TRACER; } @@ -135,48 +133,4 @@ public Context updateContext( protected String getInstrumentationName() { return "io.opentelemetry.javaagent.servlet-3.0"; } - - @Override - protected Integer peerPort(HttpServletRequest connection) { - return connection.getRemotePort(); - } - - @Override - protected int responseStatus(HttpServletResponse httpServletResponse) { - return httpServletResponse.getStatus(); - } - - @Override - protected boolean isResponseCommitted(HttpServletResponse response) { - return response.isCommitted(); - } - - public void onTimeout(Context context, long timeout) { - Span span = Span.fromContext(context); - span.setStatus(StatusCode.ERROR); - if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) { - span.setAttribute("servlet.timeout", timeout); - } - span.end(); - } - - /* - Given request already has a context associated with it. - As there should not be nested spans of kind SERVER, we should NOT create a new span here. - - But it may happen that there is no span in current Context or it is from a different trace. - E.g. in case of async servlet request processing we create span for incoming request in one thread, - but actual request continues processing happens in another thread. - Depending on servlet container implementation, this processing may again arrive into this method. - E.g. Jetty handles async requests in a way that calls HttpServlet.service method twice. - - In this case we have to put the span from the request into current context before continuing. - */ - public static boolean needsRescoping(Context attachedContext) { - return !sameTrace(Span.fromContext(Context.current()), Span.fromContext(attachedContext)); - } - - private static boolean sameTrace(Span oneSpan, Span otherSpan) { - return oneSpan.getSpanContext().getTraceId().equals(otherSpan.getSpanContext().getTraceId()); - } } diff --git a/instrumentation/servlet/servlet-common/javaagent/servlet-common-javaagent.gradle b/instrumentation/servlet/servlet-common/javaagent/servlet-common-javaagent.gradle index ed6d181150f4..8889b2b38cfd 100644 --- a/instrumentation/servlet/servlet-common/javaagent/servlet-common-javaagent.gradle +++ b/instrumentation/servlet/servlet-common/javaagent/servlet-common-javaagent.gradle @@ -1,27 +1,8 @@ apply from: "$rootDir/gradle/instrumentation.gradle" -muzzle { - pass { - group = "javax.servlet" - module = "servlet-api" - versions = "(0,)" - } - pass { - group = "javax.servlet" - module = 'javax.servlet-api' - versions = "[3.0,)" - assertInverse = true - } -} +// This module is only used as a dependency for other javaagent modules and does not contain any +// non-abstract implementations of InstrumentationModule dependencies { - compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.3' - - testImplementation(project(':testing-common')) { - exclude group: 'org.eclipse.jetty', module: 'jetty-server' - } - - // We don't check testLatestDeps for this module since we have coverage in others like servlet-3.0 - testImplementation group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005' - testImplementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.0.v20091005' + api(project(':instrumentation:servlet:servlet-common:library')) } diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java new file mode 100644 index 000000000000..2b3d6f445a31 --- /dev/null +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.async; + +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Map; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class AsyncContextInstrumentation implements TypeInstrumentation { + private final String basePackageName; + private final String adviceClassName; + + public AsyncContextInstrumentation(String basePackageName, String adviceClassName) { + this.basePackageName = basePackageName; + this.adviceClassName = adviceClassName; + } + + @Override + public ElementMatcher classLoaderOptimization() { + return hasClassesNamed(basePackageName + ".AsyncContext"); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named(basePackageName + ".AsyncContext")); + } + + @Override + public Map, String> transformers() { + return singletonMap(isMethod().and(isPublic()).and(named("dispatch")), adviceClassName); + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java new file mode 100644 index 000000000000..2efc48a333df --- /dev/null +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java @@ -0,0 +1,74 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; + +import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.tracer.BaseTracer; +import io.opentelemetry.instrumentation.servlet.ServletAccessor; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; + +public class RequestDispatcherAdviceHelper { + public static Context getStartParentContext( + ServletAccessor accessor, REQUEST request) { + Context parentContext = Java8BytecodeBridge.currentContext(); + + Object servletContextObject = accessor.getRequestAttribute(request, CONTEXT_ATTRIBUTE); + Context servletContext = + servletContextObject instanceof Context ? (Context) servletContextObject : null; + + Span parentSpan = Java8BytecodeBridge.spanFromContext(parentContext); + SpanContext parentSpanContext = parentSpan.getSpanContext(); + if (!parentSpanContext.isValid() && servletContext == null) { + // Don't want to generate a new top-level span + return null; + } + + Span servletSpan = + servletContext != null ? Java8BytecodeBridge.spanFromContext(servletContext) : null; + Context parent; + if (servletContext == null + || (parentSpanContext.isValid() + && servletSpan.getSpanContext().getTraceId().equals(parentSpanContext.getTraceId()))) { + // Use the parentSpan if the servletSpan is null or part of the same trace. + parent = parentContext; + } else { + // parentSpan is part of a different trace, so lets ignore it. + // This can happen with the way Tomcat does error handling. + parent = servletContext; + } + + return parent; + } + + public static void stop( + BaseTracer tracer, + ServletAccessor accessor, + Object originalContext, + REQUEST request, + Context context, + Scope scope, + Throwable throwable) { + scope.close(); + + // restore the original servlet span + // since spanWithScope is non-null here, originalContext must have been set with the + // prior + // servlet span (as opposed to remaining unset) + // TODO review this logic. Seems like manual context management + accessor.setRequestAttribute(request, CONTEXT_ATTRIBUTE, originalContext); + + if (throwable != null) { + tracer.endExceptionally(context, throwable); + } else { + tracer.end(context); + } + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java new file mode 100644 index 000000000000..73afefbdb1b7 --- /dev/null +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java @@ -0,0 +1,52 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; + +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Map; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class RequestDispatcherInstrumentation implements TypeInstrumentation { + private final String basePackageName; + private final String adviceClassName; + + public RequestDispatcherInstrumentation(String basePackageName, String adviceClassName) { + this.basePackageName = basePackageName; + this.adviceClassName = adviceClassName; + } + + @Override + public ElementMatcher classLoaderOptimization() { + return hasClassesNamed(basePackageName + ".RequestDispatcher"); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named(basePackageName + ".RequestDispatcher")); + } + + @Override + public Map, String> transformers() { + return singletonMap( + namedOneOf("forward", "include") + .and(takesArguments(2)) + .and(takesArgument(0, named(basePackageName + ".ServletRequest"))) + .and(takesArgument(1, named(basePackageName + ".ServletResponse"))) + .and(isPublic()), + adviceClassName); + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentationModule.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentationModule.java deleted file mode 100644 index 752405ad1792..000000000000 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentationModule.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; - -import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; -import static io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherTracer.tracer; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static net.bytebuddy.matcher.ElementMatchers.isPublic; -import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArgument; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; - -import com.google.auto.service.AutoService; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.tooling.InstrumentationModule; -import io.opentelemetry.javaagent.tooling.TypeInstrumentation; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.matcher.ElementMatcher; - -@AutoService(InstrumentationModule.class) -public class RequestDispatcherInstrumentationModule extends InstrumentationModule { - public RequestDispatcherInstrumentationModule() { - super("servlet", "servlet-dispatcher"); - } - - @Override - public List typeInstrumentations() { - return singletonList(new RequestDispatcherInstrumentation()); - } - - @Override - public Map contextStore() { - return singletonMap("javax.servlet.RequestDispatcher", String.class.getName()); - } - - public static class RequestDispatcherInstrumentation implements TypeInstrumentation { - @Override - public ElementMatcher classLoaderOptimization() { - return hasClassesNamed("javax.servlet.RequestDispatcher"); - } - - @Override - public ElementMatcher typeMatcher() { - return implementsInterface(named("javax.servlet.RequestDispatcher")); - } - - @Override - public Map, String> transformers() { - return singletonMap( - namedOneOf("forward", "include") - .and(takesArguments(2)) - .and(takesArgument(0, named("javax.servlet.ServletRequest"))) - .and(takesArgument(1, named("javax.servlet.ServletResponse"))) - .and(isPublic()), - RequestDispatcherInstrumentationModule.class.getName() + "$RequestDispatcherAdvice"); - } - } - - public static class RequestDispatcherAdvice { - - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void start( - @Advice.Origin Method method, - @Advice.This RequestDispatcher dispatcher, - @Advice.Local("_originalContext") Object originalContext, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Argument(0) ServletRequest request) { - - Context parentContext = Java8BytecodeBridge.currentContext(); - - Object servletContextObject = request.getAttribute(CONTEXT_ATTRIBUTE); - Context servletContext = - servletContextObject instanceof Context ? (Context) servletContextObject : null; - - Span parentSpan = Java8BytecodeBridge.spanFromContext(parentContext); - SpanContext parentSpanContext = parentSpan.getSpanContext(); - if (!parentSpanContext.isValid() && servletContext == null) { - // Don't want to generate a new top-level span - return; - } - - Span servletSpan = - servletContext != null ? Java8BytecodeBridge.spanFromContext(servletContext) : null; - Context parent; - if (servletContext == null - || (parentSpanContext.isValid() - && servletSpan - .getSpanContext() - .getTraceId() - .equals(parentSpanContext.getTraceId()))) { - // Use the parentSpan if the servletSpan is null or part of the same trace. - parent = parentContext; - } else { - // parentSpan is part of a different trace, so lets ignore it. - // This can happen with the way Tomcat does error handling. - parent = servletContext; - } - - try (Scope ignored = parent.makeCurrent()) { - context = tracer().startSpan(method); - - // save the original servlet span before overwriting the request attribute, so that it can - // be - // restored on method exit - originalContext = request.getAttribute(CONTEXT_ATTRIBUTE); - - // this tells the dispatched servlet to use the current span as the parent for its work - request.setAttribute(CONTEXT_ATTRIBUTE, context); - } - scope = context.makeCurrent(); - } - - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stop( - @Advice.Local("_originalContext") Object originalContext, - @Advice.Argument(0) ServletRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Thrown Throwable throwable) { - if (scope == null) { - return; - } - - scope.close(); - - // restore the original servlet span - // since spanWithScope is non-null here, originalContext must have been set with the - // prior - // servlet span (as opposed to remaining unset) - // TODO review this logic. Seems like manual context management - request.setAttribute(CONTEXT_ATTRIBUTE, originalContext); - - if (throwable != null) { - tracer().endExceptionally(context, throwable); - } else { - tracer().end(context); - } - } - } -} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseInstrumentationModule.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseInstrumentationModule.java deleted file mode 100644 index 3df1833c09fb..000000000000 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseInstrumentationModule.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.servlet.http; - -import static io.opentelemetry.javaagent.instrumentation.servlet.http.HttpServletResponseTracer.tracer; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static net.bytebuddy.matcher.ElementMatchers.named; - -import com.google.auto.service.AutoService; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.instrumentation.api.CallDepth; -import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; -import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.tooling.InstrumentationModule; -import io.opentelemetry.javaagent.tooling.TypeInstrumentation; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletResponse; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.matcher.ElementMatcher; - -@AutoService(InstrumentationModule.class) -public class HttpServletResponseInstrumentationModule extends InstrumentationModule { - public HttpServletResponseInstrumentationModule() { - super("servlet", "servlet-response"); - } - - @Override - public List typeInstrumentations() { - return singletonList(new HttpServletResponseInstrumentation()); - } - - public static class HttpServletResponseInstrumentation implements TypeInstrumentation { - @Override - public ElementMatcher classLoaderOptimization() { - return hasClassesNamed("javax.servlet.http.HttpServletResponse"); - } - - @Override - public ElementMatcher typeMatcher() { - return implementsInterface(named("javax.servlet.http.HttpServletResponse")); - } - - @Override - public Map, String> transformers() { - return singletonMap(namedOneOf("sendError", "sendRedirect"), SendAdvice.class.getName()); - } - } - - public static class SendAdvice { - - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void start( - @Advice.Origin Method method, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Local("otelCallDepth") CallDepth callDepth) { - callDepth = CallDepthThreadLocalMap.getCallDepth(HttpServletResponse.class); - // Don't want to generate a new top-level span - if (callDepth.getAndIncrement() == 0 - && Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) { - context = tracer().startSpan(method); - scope = context.makeCurrent(); - } - } - - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stopSpan( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Local("otelCallDepth") CallDepth callDepth) { - if (callDepth.decrementAndGet() == 0 && context != null) { - CallDepthThreadLocalMap.reset(HttpServletResponse.class); - - scope.close(); - - if (throwable != null) { - tracer().endExceptionally(context, throwable); - } else { - tracer().end(context); - } - } - } - } -} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java new file mode 100644 index 000000000000..a1e073e9ad42 --- /dev/null +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.response; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.tracer.BaseTracer; +import io.opentelemetry.javaagent.instrumentation.api.CallDepth; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; + +public class HttpServletResponseAdviceHelper { + public static void stopSpan( + BaseTracer tracer, + Class responseClass, + Throwable throwable, + Context context, + Scope scope, + CallDepth callDepth) { + if (callDepth.decrementAndGet() == 0 && context != null) { + CallDepthThreadLocalMap.reset(responseClass); + + scope.close(); + + if (throwable != null) { + tracer.endExceptionally(context, throwable); + } else { + tracer.end(context); + } + } + } +} diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/ServletAndFilterInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java similarity index 56% rename from instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/ServletAndFilterInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java index b47edcd98919..ed644f612fa7 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/ServletAndFilterInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java @@ -3,15 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; +package io.opentelemetry.javaagent.instrumentation.servlet.response; -import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; import static java.util.Collections.singletonMap; -import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -19,24 +17,27 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; -public class ServletAndFilterInstrumentation implements TypeInstrumentation { +public class HttpServletResponseInstrumentation implements TypeInstrumentation { + private final String basePackageName; + private final String adviceClassName; + + public HttpServletResponseInstrumentation(String basePackageName, String adviceClassName) { + this.basePackageName = basePackageName; + this.adviceClassName = adviceClassName; + } + @Override public ElementMatcher classLoaderOptimization() { - return hasClassesNamed("javax.servlet.Filter"); + return hasClassesNamed(basePackageName + ".http.HttpServletResponse"); } @Override public ElementMatcher typeMatcher() { - return safeHasSuperType(namedOneOf("javax.servlet.Filter", "javax.servlet.Servlet")); + return implementsInterface(named(basePackageName + ".http.HttpServletResponse")); } @Override public Map, String> transformers() { - return singletonMap( - namedOneOf("doFilter", "service") - .and(takesArgument(0, named("javax.servlet.ServletRequest"))) - .and(takesArgument(1, named("javax.servlet.ServletResponse"))) - .and(isPublic()), - Servlet3Advice.class.getName()); + return singletonMap(namedOneOf("sendError", "sendRedirect"), adviceClassName); } } diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ServletAndFilterInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java similarity index 66% rename from instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ServletAndFilterInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java index 4beae3dcef00..7aaf6f9a58b9 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/ServletAndFilterInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v2_2; +package io.opentelemetry.javaagent.instrumentation.servlet.service; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; @@ -20,24 +20,31 @@ import net.bytebuddy.matcher.ElementMatcher; public class ServletAndFilterInstrumentation implements TypeInstrumentation { + private final String basePackageName; + private final String adviceClassName; + + public ServletAndFilterInstrumentation(String basePackageName, String adviceClassName) { + this.basePackageName = basePackageName; + this.adviceClassName = adviceClassName; + } @Override public ElementMatcher classLoaderOptimization() { - return hasClassesNamed("javax.servlet.Servlet"); + return hasClassesNamed(basePackageName + ".Servlet"); } @Override public ElementMatcher typeMatcher() { - return safeHasSuperType(namedOneOf("javax.servlet.Filter", "javax.servlet.Servlet")); + return safeHasSuperType(namedOneOf(basePackageName + ".Filter", basePackageName + ".Servlet")); } @Override public Map, String> transformers() { return singletonMap( namedOneOf("doFilter", "service") - .and(takesArgument(0, named("javax.servlet.ServletRequest"))) - .and(takesArgument(1, named("javax.servlet.ServletResponse"))) + .and(takesArgument(0, named(basePackageName + ".ServletRequest"))) + .and(takesArgument(1, named(basePackageName + ".ServletResponse"))) .and(isPublic()), - Servlet2Advice.class.getName()); + adviceClassName); } } diff --git a/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle b/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle new file mode 100644 index 000000000000..dbdb5ba32d16 --- /dev/null +++ b/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle @@ -0,0 +1,8 @@ +apply from: "$rootDir/gradle/instrumentation-library.gradle" + +// need to override archivesBaseName set in instrumentation-library.gradle +archivesBaseName = "servlet-common" + +dependencies { + implementation deps.slf4j +} diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/MappingResolver.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/MappingResolver.java similarity index 98% rename from instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/MappingResolver.java rename to instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/MappingResolver.java index 840939abd9d9..1ddc071feaad 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/MappingResolver.java +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/MappingResolver.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v3_0; +package io.opentelemetry.instrumentation.servlet; import java.util.ArrayList; import java.util.Collection; diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java new file mode 100644 index 000000000000..b413f9b8f6ce --- /dev/null +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet; + +import java.security.Principal; + +public interface ServletAccessor { + String getRequestContextPath(REQUEST request); + + String getRequestScheme(REQUEST request); + + String getRequestServerName(REQUEST request); + + int getRequestServerPort(REQUEST request); + + String getRequestURI(REQUEST request); + + String getRequestQueryString(REQUEST request); + + Object getRequestAttribute(REQUEST request, String name); + + void setRequestAttribute(REQUEST request, String name, Object value); + + String getRequestProtocol(REQUEST request); + + String getRequestMethod(REQUEST request); + + String getRequestRemoteAddr(REQUEST request); + + String getRequestHeader(REQUEST request, String name); + + String getRequestServletPath(REQUEST request); + + Principal getRequestUserPrincipal(REQUEST request); + + Integer getRequestRemotePort(REQUEST request); + + int getResponseStatus(RESPONSE response); + + boolean isResponseCommitted(RESPONSE response); + + boolean isServletException(Throwable throwable); +} diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java new file mode 100644 index 000000000000..8754dfd73fc7 --- /dev/null +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java @@ -0,0 +1,227 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.instrumentation.api.config.Config; +import io.opentelemetry.instrumentation.api.servlet.AppServerBridge; +import io.opentelemetry.instrumentation.api.servlet.ServletContextPath; +import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; +import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.Principal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class ServletHttpServerTracer + extends HttpServerTracer { + + private static final Logger log = LoggerFactory.getLogger(ServletHttpServerTracer.class); + + private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES = + Config.get() + .getBooleanProperty("otel.instrumentation.grpc.experimental-span-attributes", false); + + private final ServletAccessor accessor; + + public ServletHttpServerTracer(ServletAccessor accessor) { + this.accessor = accessor; + } + + public Context startSpan(REQUEST request, String spanName) { + Context context = startSpan(request, request, request, spanName); + + SpanContext spanContext = Span.fromContext(context).getSpanContext(); + // we do this e.g. so that servlet containers can use these values in their access logs + accessor.setRequestAttribute(request, "trace_id", spanContext.getTraceId()); + accessor.setRequestAttribute(request, "span_id", spanContext.getSpanId()); + + return addServletContextPath(context, request); + } + + @Override + protected Context customizeContext(Context context, REQUEST request) { + // add context for tracking whether servlet instrumentation has updated + // server span + context = ServletSpanNaming.init(context); + // add context for current request's context path + return addServletContextPath(context, request); + } + + private Context addServletContextPath(Context context, REQUEST request) { + String contextPath = accessor.getRequestContextPath(request); + if (contextPath != null && !contextPath.isEmpty() && !contextPath.equals("/")) { + return context.with(ServletContextPath.CONTEXT_KEY, contextPath); + } + return context; + } + + @Override + public void endExceptionally( + Context context, Throwable throwable, RESPONSE response, long timestamp) { + if (accessor.isResponseCommitted(response)) { + super.endExceptionally(context, throwable, response, timestamp); + } else { + // passing null response to super, in order to capture as 500 / INTERNAL, due to servlet spec + // https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf: + // "If a servlet generates an error that is not handled by the error page mechanism as + // described above, the container must ensure to send a response with status 500." + super.endExceptionally(context, throwable, null, timestamp); + } + } + + @Override + protected String url(REQUEST httpServletRequest) { + try { + return new URI( + accessor.getRequestScheme(httpServletRequest), + null, + accessor.getRequestServerName(httpServletRequest), + accessor.getRequestServerPort(httpServletRequest), + accessor.getRequestURI(httpServletRequest), + accessor.getRequestQueryString(httpServletRequest), + null) + .toString(); + } catch (URISyntaxException e) { + log.debug("Failed to construct request URI", e); + return null; + } + } + + @Override + public Context getServerContext(REQUEST request) { + Object context = accessor.getRequestAttribute(request, CONTEXT_ATTRIBUTE); + return context instanceof Context ? (Context) context : null; + } + + @Override + protected void attachServerContext(Context context, REQUEST request) { + accessor.setRequestAttribute(request, CONTEXT_ATTRIBUTE, context); + } + + @Override + protected Integer peerPort(REQUEST connection) { + return accessor.getRequestRemotePort(connection); + } + + @Override + protected String peerHostIP(REQUEST connection) { + return accessor.getRequestRemoteAddr(connection); + } + + @Override + protected String method(REQUEST request) { + return accessor.getRequestMethod(request); + } + + @Override + protected int responseStatus(RESPONSE response) { + return accessor.getResponseStatus(response); + } + + @Override + protected abstract TextMapGetter getGetter(); + + public void addUnwrappedThrowable(Context context, Throwable throwable) { + if (AppServerBridge.shouldRecordException(context)) { + onException(context, throwable); + } + } + + @Override + protected Throwable unwrapThrowable(Throwable throwable) { + if (accessor.isServletException(throwable) && throwable.getCause() != null) { + throwable = throwable.getCause(); + } + return super.unwrapThrowable(throwable); + } + + public void setPrincipal(Context context, REQUEST request) { + Principal principal = accessor.getRequestUserPrincipal(request); + if (principal != null) { + Span.fromContext(context).setAttribute(SemanticAttributes.ENDUSER_ID, principal.getName()); + } + } + + @Override + protected String flavor(REQUEST connection, REQUEST request) { + return accessor.getRequestProtocol(connection); + } + + @Override + protected String requestHeader(REQUEST httpServletRequest, String name) { + return accessor.getRequestHeader(httpServletRequest, name); + } + + public String getSpanName(REQUEST request) { + String servletPath = accessor.getRequestServletPath(request); + if (servletPath.isEmpty()) { + return "HTTP " + accessor.getRequestMethod(request); + } + String contextPath = accessor.getRequestContextPath(request); + if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { + return servletPath; + } + return contextPath + servletPath; + } + + /** + * When server spans are managed by app server instrumentation we need to add context path of + * current request to context if it isn't already added. Servlet instrumentation adds it when it + * starts server span. + */ + public Context updateContext(Context context, REQUEST request) { + String contextPath = context.get(ServletContextPath.CONTEXT_KEY); + if (contextPath == null) { + context = addServletContextPath(context, request); + } + + return context; + } + + public void updateSpanName(REQUEST request) { + updateSpanName(getServerSpan(request), request); + } + + private void updateSpanName(Span span, REQUEST request) { + span.updateName(getSpanName(request)); + } + + public void onTimeout(Context context, long timeout) { + Span span = Span.fromContext(context); + span.setStatus(StatusCode.ERROR); + if (CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES) { + span.setAttribute("servlet.timeout", timeout); + } + span.end(); + } + + /* + Given request already has a context associated with it. + As there should not be nested spans of kind SERVER, we should NOT create a new span here. + + But it may happen that there is no span in current Context or it is from a different trace. + E.g. in case of async servlet request processing we create span for incoming request in one thread, + but actual request continues processing happens in another thread. + Depending on servlet container implementation, this processing may again arrive into this method. + E.g. Jetty handles async requests in a way that calls HttpServlet.service method twice. + + In this case we have to put the span from the request into current context before continuing. + */ + public boolean needsRescoping(Context attachedContext) { + return !sameTrace(Span.fromContext(Context.current()), Span.fromContext(attachedContext)); + } + + private static boolean sameTrace(Span oneSpan, Span otherSpan) { + return oneSpan.getSpanContext().getTraceId().equals(otherSpan.getSpanContext().getTraceId()); + } +} diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle b/instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle new file mode 100644 index 000000000000..d757ca616a26 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle @@ -0,0 +1,15 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "jakarta.servlet" + module = 'jakarta.servlet-api' + versions = "[5.0.0,)" + } +} + +dependencies { + api(project(':instrumentation:servlet:servlet-jakarta:library')) + implementation(project(':instrumentation:servlet:servlet-common:javaagent')) + compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' +} diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java new file mode 100644 index 000000000000..0002a08cbe9b --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet; + +import static java.util.Collections.singletonMap; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.instrumentation.servlet.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.tooling.InstrumentationModule; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@AutoService(InstrumentationModule.class) +public class JakartaServletInstrumentationModule extends InstrumentationModule { + private static final String BASE_PACKAGE = "jakarta.servlet"; + + public JakartaServletInstrumentationModule() { + super("servlet", "servlet-jakarta"); + } + + @Override + public List typeInstrumentations() { + return Arrays.asList( + new AsyncContextInstrumentation( + BASE_PACKAGE, adviceClassName(".async.AsyncDispatchAdvice")), + new ServletAndFilterInstrumentation( + BASE_PACKAGE, adviceClassName(".service.JakartaServletServiceAdvice")), + new HttpServletResponseInstrumentation( + BASE_PACKAGE, adviceClassName(".response.ResponseSendAdvice")), + new RequestDispatcherInstrumentation( + BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice"))); + } + + @Override + public Map contextStore() { + return singletonMap(BASE_PACKAGE + ".RequestDispatcher", String.class.getName()); + } + + private static String adviceClassName(String suffix) { + return JakartaServletInstrumentationModule.class.getPackage().getName() + suffix; + } +} diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java new file mode 100644 index 000000000000..1aee4607e9cd --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.async; + +import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ServletRequest; +import net.bytebuddy.asm.Advice; + +public class AsyncDispatchAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static boolean enter( + @Advice.This AsyncContext context, @Advice.AllArguments Object[] args) { + int depth = CallDepthThreadLocalMap.incrementCallDepth(AsyncContext.class); + if (depth > 0) { + return false; + } + + ServletRequest request = context.getRequest(); + + Context currentContext = Java8BytecodeBridge.currentContext(); + Span currentSpan = Java8BytecodeBridge.spanFromContext(currentContext); + if (currentSpan.getSpanContext().isValid()) { + // this tells the dispatched servlet to use the current span as the parent for its work + // (if the currentSpan is not valid for some reason, the original servlet span should still + // be present in the same request attribute, and so that will be used) + // + // the original servlet span stored in the same request attribute does not need to be saved + // and restored on method exit, because dispatch() hands off control of the request + // processing, and nothing can be done with the request anymore after this + request.setAttribute(CONTEXT_ATTRIBUTE, currentContext); + } + + return true; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void exit(@Advice.Enter boolean topLevel) { + if (topLevel) { + CallDepthThreadLocalMap.reset(AsyncContext.class); + } + } +} diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java new file mode 100644 index 000000000000..0527e8161a71 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java @@ -0,0 +1,69 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; + +import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletAccessor; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; + +public class RequestDispatcherAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void start( + @Advice.Origin Method method, + @Advice.This RequestDispatcher dispatcher, + @Advice.Local("_originalContext") Object originalContext, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Argument(0) ServletRequest request) { + + Context parent = + RequestDispatcherAdviceHelper.getStartParentContext( + JakartaServletAccessor.INSTANCE, (HttpServletRequest) request); + + if (parent == null) { + return; + } + + try (Scope ignored = parent.makeCurrent()) { + context = RequestDispatcherTracer.tracer().startSpan(method); + + // save the original servlet span before overwriting the request attribute, so that it can + // be + // restored on method exit + originalContext = request.getAttribute(CONTEXT_ATTRIBUTE); + + // this tells the dispatched servlet to use the current span as the parent for its work + request.setAttribute(CONTEXT_ATTRIBUTE, context); + } + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stop( + @Advice.Local("_originalContext") Object originalContext, + @Advice.Argument(0) ServletRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Thrown Throwable throwable) { + + RequestDispatcherAdviceHelper.stop( + RequestDispatcherTracer.tracer(), + JakartaServletAccessor.INSTANCE, + originalContext, + (HttpServletRequest) request, + context, + scope, + throwable); + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java similarity index 92% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java rename to instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java index f562a364b317..4b0c0687e761 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-common"; + return "io.opentelemetry.javaagent.servlet-jakarta"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java new file mode 100644 index 000000000000..641a3d9a0612 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.response; + +import static io.opentelemetry.javaagent.instrumentation.servlet.response.ResponseTracer.tracer; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepth; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import jakarta.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; + +public class ResponseSendAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void start( + @Advice.Origin Method method, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Local("otelCallDepth") CallDepth callDepth) { + callDepth = CallDepthThreadLocalMap.getCallDepth(HttpServletResponse.class); + // Don't want to generate a new top-level span + if (callDepth.getAndIncrement() == 0 + && Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) { + context = tracer().startSpan(method); + scope = context.makeCurrent(); + } + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Local("otelCallDepth") CallDepth callDepth) { + HttpServletResponseAdviceHelper.stopSpan( + tracer(), HttpServletResponse.class, throwable, context, scope, callDepth); + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseTracer.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java similarity index 55% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseTracer.java rename to instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java index 83cc74fffbcf..e44a8fe94fc6 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/http/HttpServletResponseTracer.java +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java @@ -3,22 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.http; +package io.opentelemetry.javaagent.instrumentation.servlet.response; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; import java.lang.reflect.Method; -public class HttpServletResponseTracer extends BaseTracer { - private static final HttpServletResponseTracer TRACER = new HttpServletResponseTracer(); +public class ResponseTracer extends BaseTracer { + private static final ResponseTracer TRACER = new ResponseTracer(); - public static HttpServletResponseTracer tracer() { + public static ResponseTracer tracer() { return TRACER; } @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-common"; + return "io.opentelemetry.javaagent.servlet-jakarta"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java new file mode 100644 index 000000000000..3bd99d272e5a --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java @@ -0,0 +1,132 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.service; + +import static io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer.tracer; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.servlet.AppServerBridge; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.concurrent.atomic.AtomicBoolean; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.implementation.bytecode.assign.Assigner; + +public class JakartaServletServiceAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.This(typing = Assigner.Typing.DYNAMIC) Object servletOrFilter, + @Advice.Argument(value = 0, readOnly = false) ServletRequest request, + @Advice.Argument(value = 1, readOnly = false) ServletResponse response, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + CallDepthThreadLocalMap.incrementCallDepth(AppServerBridge.getCallDepthKey()); + if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { + return; + } + + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + + Context attachedContext = tracer().getServerContext(httpServletRequest); + if (attachedContext != null) { + // We are inside nested servlet/filter/app-server span, don't create new span + if (tracer().needsRescoping(attachedContext)) { + attachedContext = + tracer().updateContext(attachedContext, servletOrFilter, httpServletRequest); + scope = attachedContext.makeCurrent(); + return; + } + + // We already have attached context to request but this could have been done by app server + // instrumentation, if needed update span with info from current request. + Context currentContext = Java8BytecodeBridge.currentContext(); + Context updatedContext = + tracer().updateContext(currentContext, servletOrFilter, httpServletRequest); + if (updatedContext != currentContext) { + // runOnceUnderAppServer updated context, need to re-scope + scope = updatedContext.makeCurrent(); + } + return; + } + + Context currentContext = Java8BytecodeBridge.currentContext(); + if (currentContext != null + && Java8BytecodeBridge.spanFromContext(currentContext).isRecording()) { + // We already have a span but it was not created by servlet instrumentation. + // In case it was created by app server integration we need to update it with info from + // current request. + Context updatedContext = + tracer().updateContext(currentContext, servletOrFilter, httpServletRequest); + if (currentContext != updatedContext) { + // updateContext updated context, need to re-scope + scope = updatedContext.makeCurrent(); + } + return; + } + + context = tracer().startSpan(servletOrFilter, httpServletRequest); + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Argument(0) ServletRequest request, + @Advice.Argument(1) ServletResponse response, + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + int callDepth = CallDepthThreadLocalMap.decrementCallDepth(AppServerBridge.getCallDepthKey()); + + if (scope != null) { + scope.close(); + } + + if (context == null && callDepth == 0) { + Context currentContext = Java8BytecodeBridge.currentContext(); + // Something else is managing the context, we're in the outermost level of Servlet + // instrumentation and we have an uncaught throwable. Let's add it to the current span. + if (throwable != null) { + tracer().addUnwrappedThrowable(currentContext, throwable); + } + tracer().setPrincipal(currentContext, (HttpServletRequest) request); + } + + if (scope == null || context == null) { + return; + } + + tracer().setPrincipal(context, (HttpServletRequest) request); + if (throwable != null) { + tracer().endExceptionally(context, throwable, (HttpServletResponse) response); + return; + } + + AtomicBoolean responseHandled = new AtomicBoolean(false); + + // In case of async servlets wait for the actual response to be ready + if (request.isAsyncStarted()) { + try { + request + .getAsyncContext() + .addListener(new TagSettingAsyncListener(responseHandled, context)); + } catch (IllegalStateException e) { + // org.eclipse.jetty.server.Request may throw an exception here if request became + // finished after check above. We just ignore that exception and move on. + } + } + + // Check again in case the request finished before adding the listener. + if (!request.isAsyncStarted() && responseHandled.compareAndSet(false, true)) { + tracer().end(context, (HttpServletResponse) response); + } + } +} diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java new file mode 100644 index 000000000000..a67f27fd0be4 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.service; + +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer; +import jakarta.servlet.AsyncEvent; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.http.HttpServletResponse; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TagSettingAsyncListener implements AsyncListener { + private static final JakartaServletHttpServerTracer tracer = + JakartaServletHttpServerTracer.tracer(); + + private final AtomicBoolean responseHandled; + private final Context context; + + public TagSettingAsyncListener(AtomicBoolean responseHandled, Context context) { + this.responseHandled = responseHandled; + this.context = context; + } + + @Override + public void onComplete(AsyncEvent event) { + if (responseHandled.compareAndSet(false, true)) { + tracer.end(context, (HttpServletResponse) event.getSuppliedResponse()); + } + } + + @Override + public void onTimeout(AsyncEvent event) { + if (responseHandled.compareAndSet(false, true)) { + tracer.onTimeout(context, event.getAsyncContext().getTimeout()); + } + } + + @Override + public void onError(AsyncEvent event) { + if (responseHandled.compareAndSet(false, true)) { + tracer.endExceptionally( + context, event.getThrowable(), (HttpServletResponse) event.getSuppliedResponse()); + } + } + + /** Transfer the listener over to the new context. */ + @Override + public void onStartAsync(AsyncEvent event) { + event.getAsyncContext().addListener(this); + } +} diff --git a/instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle b/instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle new file mode 100644 index 000000000000..3da00fc071d0 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle @@ -0,0 +1,14 @@ +apply from: "$rootDir/gradle/instrumentation-library.gradle" + +// need to override archivesBaseName set in instrumentation-library.gradle +archivesBaseName = "servlet-jakarta" + +dependencies { + api(project(':instrumentation:servlet:servlet-common:library')) + + compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' + + testImplementation group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' + testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.6.0' + testImplementation deps.assertj +} diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java new file mode 100644 index 000000000000..b49588b23d4f --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.jakarta; + +import io.opentelemetry.context.propagation.TextMapGetter; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Collections; + +public class JakartaHttpServletRequestGetter implements TextMapGetter { + + public static final JakartaHttpServletRequestGetter GETTER = + new JakartaHttpServletRequestGetter(); + + @Override + public Iterable keys(HttpServletRequest carrier) { + return Collections.list(carrier.getHeaderNames()); + } + + @Override + public String get(HttpServletRequest carrier, String key) { + return carrier.getHeader(key); + } +} diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java new file mode 100644 index 000000000000..83561ef2aec4 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java @@ -0,0 +1,109 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.jakarta; + +import io.opentelemetry.instrumentation.servlet.ServletAccessor; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.security.Principal; + +public class JakartaServletAccessor + implements ServletAccessor { + public static final JakartaServletAccessor INSTANCE = new JakartaServletAccessor(); + + private JakartaServletAccessor() {} + + @Override + public String getRequestContextPath(HttpServletRequest request) { + return request.getContextPath(); + } + + @Override + public String getRequestScheme(HttpServletRequest request) { + return request.getScheme(); + } + + @Override + public String getRequestServerName(HttpServletRequest request) { + return request.getServerName(); + } + + @Override + public int getRequestServerPort(HttpServletRequest request) { + return request.getServerPort(); + } + + @Override + public String getRequestURI(HttpServletRequest request) { + return request.getRequestURI(); + } + + @Override + public String getRequestQueryString(HttpServletRequest request) { + return request.getQueryString(); + } + + @Override + public Object getRequestAttribute(HttpServletRequest request, String name) { + return request.getAttribute(name); + } + + @Override + public void setRequestAttribute(HttpServletRequest request, String name, Object value) { + request.setAttribute(name, value); + } + + @Override + public String getRequestProtocol(HttpServletRequest request) { + return request.getProtocol(); + } + + @Override + public String getRequestMethod(HttpServletRequest request) { + return request.getMethod(); + } + + @Override + public String getRequestRemoteAddr(HttpServletRequest request) { + return request.getRemoteAddr(); + } + + @Override + public String getRequestHeader(HttpServletRequest request, String name) { + return request.getHeader(name); + } + + @Override + public String getRequestServletPath(HttpServletRequest request) { + return request.getServletPath(); + } + + @Override + public Principal getRequestUserPrincipal(HttpServletRequest request) { + return request.getUserPrincipal(); + } + + @Override + public Integer getRequestRemotePort(HttpServletRequest request) { + return request.getRemotePort(); + } + + @Override + public int getResponseStatus(HttpServletResponse response) { + return response.getStatus(); + } + + @Override + public boolean isResponseCommitted(HttpServletResponse response) { + return response.isCommitted(); + } + + @Override + public boolean isServletException(Throwable throwable) { + return throwable instanceof ServletException; + } +} diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java new file mode 100644 index 000000000000..d5dfe93983a4 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java @@ -0,0 +1,143 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.jakarta; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; +import io.opentelemetry.instrumentation.api.tracer.ServerSpan; +import io.opentelemetry.instrumentation.servlet.MappingResolver; +import io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.Collection; + +public class JakartaServletHttpServerTracer + extends ServletHttpServerTracer { + private static final JakartaServletHttpServerTracer TRACER = new JakartaServletHttpServerTracer(); + + public JakartaServletHttpServerTracer() { + super(JakartaServletAccessor.INSTANCE); + } + + public static JakartaServletHttpServerTracer tracer() { + return TRACER; + } + + public Context startSpan(Object servletOrFilter, HttpServletRequest request) { + Context context = startSpan(request, getSpanName(servletOrFilter, request, false)); + // server span name shouldn't be update when server span was created from a call to Servlet + // if server span was created from a call to Filter then name may be updated from updateContext. + if (servletOrFilter instanceof Servlet) { + ServletSpanNaming.setServletUpdatedServerSpanName(context); + } + return context; + } + + private String getSpanName( + Object servletOrFilter, HttpServletRequest request, boolean allowNull) { + String spanName = getSpanName(servletOrFilter, request); + if (spanName == null && !allowNull) { + String contextPath = request.getContextPath(); + if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { + return "HTTP " + request.getMethod(); + } + return contextPath; + } + return spanName; + } + + private static String getSpanName(Object servletOrFilter, HttpServletRequest request) { + // we are only interested in Servlets + if (!(servletOrFilter instanceof Servlet)) { + return null; + } + Servlet servlet = (Servlet) servletOrFilter; + + String mapping = getMapping(servlet, request.getServletPath(), request.getPathInfo()); + // mapping was not found + if (mapping == null) { + return null; + } + + // prepend context path + String contextPath = request.getContextPath(); + if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { + return mapping; + } + return contextPath + mapping; + } + + private static String getMapping(Servlet servlet, String servletPath, String pathInfo) { + ServletConfig servletConfig = servlet.getServletConfig(); + if (servletConfig == null) { + return null; + } + String servletName = servletConfig.getServletName(); + ServletContext servletContext = servletConfig.getServletContext(); + MappingResolver mappingResolver = getMappingResolver(servletContext, servletName); + if (mappingResolver == null) { + return null; + } + + return mappingResolver.resolve(servletPath, pathInfo); + } + + private static MappingResolver getMappingResolver( + ServletContext servletContext, String servletName) { + if (servletContext == null || servletName == null) { + return null; + } + String key = MappingResolver.class.getName() + "." + servletName; + MappingResolver mappingResolver = (MappingResolver) servletContext.getAttribute(key); + if (mappingResolver != null) { + return mappingResolver; + } + + ServletRegistration servletRegistration = servletContext.getServletRegistration(servletName); + if (servletRegistration == null) { + return null; + } + Collection mappings = servletRegistration.getMappings(); + if (mappings == null) { + return null; + } + + mappingResolver = MappingResolver.build(mappings); + servletContext.setAttribute(key, mappingResolver); + + return mappingResolver; + } + + public Context updateContext( + Context context, Object servletOrFilter, HttpServletRequest request) { + Span span = ServerSpan.fromContextOrNull(context); + if (span != null && ServletSpanNaming.shouldUpdateServerSpanName(context)) { + String spanName = getSpanName(servletOrFilter, request, true); + if (spanName != null) { + span.updateName(spanName); + ServletSpanNaming.setServletUpdatedServerSpanName(context); + } + } + + return updateContext(context, request); + } + + @Override + protected String getInstrumentationName() { + return "io.opentelemetry.javaagent.servlet-jakarta"; + } + + @Override + protected TextMapGetter getGetter() { + return JakartaHttpServletRequestGetter.GETTER; + } +} diff --git a/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java b/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java new file mode 100644 index 000000000000..729775ed4131 --- /dev/null +++ b/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java @@ -0,0 +1,69 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer; +import jakarta.servlet.http.HttpServletRequest; +import org.junit.jupiter.api.Test; + +public class JakartaServletHttpServerTracerTest { + private static final JakartaServletHttpServerTracer tracer = JakartaServletHttpServerTracer.tracer(); + + @Test + void testGetSpanName_emptySpanName() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn(""); + when(request.getMethod()).thenReturn("PUT"); + String spanName = tracer.getSpanName(request); + assertThat(spanName).isEqualTo("HTTP PUT"); + } + + @Test + void testGetSpanName_nullSpanName() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn(null); + assertThatThrownBy(() -> tracer.getSpanName(request)).isInstanceOf(NullPointerException.class); + } + + @Test + void testGetSpanName_nullContextPath() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn("/swizzler"); + when(request.getContextPath()).thenReturn(null); + String spanName = tracer.getSpanName(request); + assertThat(spanName).isEqualTo("/swizzler"); + } + + @Test + void testGetSpanName_emptyContextPath() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn("/swizzler"); + when(request.getContextPath()).thenReturn(""); + String spanName = tracer.getSpanName(request); + assertThat(spanName).isEqualTo("/swizzler"); + } + + @Test + void testGetSpanName_slashContextPath() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn("/swizzler"); + when(request.getContextPath()).thenReturn("/"); + String spanName = tracer.getSpanName(request); + assertThat(spanName).isEqualTo("/swizzler"); + } + + @Test + void testGetSpanName_appendsSpanNameToContext() { + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getServletPath()).thenReturn("/swizzler"); + when(request.getContextPath()).thenReturn("/path/to"); + String spanName = tracer.getSpanName(request); + assertThat(spanName).isEqualTo("/path/to/swizzler"); + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/servlet-javax-common-javaagent.gradle b/instrumentation/servlet/servlet-javax-common/javaagent/servlet-javax-common-javaagent.gradle new file mode 100644 index 000000000000..4963bf675228 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/servlet-javax-common-javaagent.gradle @@ -0,0 +1,30 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "javax.servlet" + module = "servlet-api" + versions = "(0,)" + } + pass { + group = "javax.servlet" + module = 'javax.servlet-api' + versions = "[3.0,)" + assertInverse = true + } +} + +dependencies { + api(project(':instrumentation:servlet:servlet-javax-common:library')) + implementation(project(':instrumentation:servlet:servlet-common:javaagent')) + + compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.3' + + testImplementation(project(':testing-common')) { + exclude group: 'org.eclipse.jetty', module: 'jetty-server' + } + + // We don't check testLatestDeps for this module since we have coverage in others like servlet-3.0 + testImplementation group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005' + testImplementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.0.v20091005' +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java new file mode 100644 index 000000000000..04b74dfa129e --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax; + +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; +import javax.servlet.http.HttpServletRequest; + +public class JavaxCommonServletAccessor extends JavaxServletAccessor { + public static final JavaxCommonServletAccessor INSTANCE = new JavaxCommonServletAccessor(); + + private JavaxCommonServletAccessor() {} + + @Override + public Integer getRequestRemotePort(HttpServletRequest httpServletRequest) { + return null; + } + + @Override + public int getResponseStatus(Void unused) { + return 0; + } + + @Override + public boolean isResponseCommitted(Void unused) { + return false; + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java new file mode 100644 index 000000000000..75813d45eec5 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax; + +import static java.util.Collections.singletonMap; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.tooling.InstrumentationModule; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@AutoService(InstrumentationModule.class) +public class JavaxServletInstrumentationModule extends InstrumentationModule { + private static final String BASE_PACKAGE = "javax.servlet"; + + public JavaxServletInstrumentationModule() { + super("servlet", "servlet-javax-common"); + } + + @Override + public List typeInstrumentations() { + return Arrays.asList( + new HttpServletResponseInstrumentation( + BASE_PACKAGE, adviceClassName(".response.ResponseSendAdvice")), + new RequestDispatcherInstrumentation( + BASE_PACKAGE, adviceClassName(".dispatcher.RequestDispatcherAdvice"))); + } + + @Override + protected Map contextStore() { + return singletonMap(BASE_PACKAGE + ".RequestDispatcher", String.class.getName()); + } + + private static String adviceClassName(String suffix) { + return JavaxServletInstrumentationModule.class.getPackage().getName() + suffix; + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java new file mode 100644 index 000000000000..519fb10a34ee --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java @@ -0,0 +1,71 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax.dispatcher; + +import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; +import static io.opentelemetry.javaagent.instrumentation.servlet.javax.dispatcher.RequestDispatcherTracer.tracer; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherAdviceHelper; +import io.opentelemetry.javaagent.instrumentation.servlet.javax.JavaxCommonServletAccessor; +import java.lang.reflect.Method; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import net.bytebuddy.asm.Advice; + +public class RequestDispatcherAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void start( + @Advice.Origin Method method, + @Advice.This RequestDispatcher dispatcher, + @Advice.Local("_originalContext") Object originalContext, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Argument(0) ServletRequest request) { + + Context parent = + RequestDispatcherAdviceHelper.getStartParentContext( + JavaxCommonServletAccessor.INSTANCE, (HttpServletRequest) request); + + if (parent == null) { + return; + } + + try (Scope ignored = parent.makeCurrent()) { + context = tracer().startSpan(method); + + // save the original servlet span before overwriting the request attribute, so that it can + // be + // restored on method exit + originalContext = request.getAttribute(CONTEXT_ATTRIBUTE); + + // this tells the dispatched servlet to use the current span as the parent for its work + request.setAttribute(CONTEXT_ATTRIBUTE, context); + } + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stop( + @Advice.Local("_originalContext") Object originalContext, + @Advice.Argument(0) ServletRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Thrown Throwable throwable) { + + RequestDispatcherAdviceHelper.stop( + tracer(), + JavaxCommonServletAccessor.INSTANCE, + originalContext, + (HttpServletRequest) request, + context, + scope, + throwable); + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java new file mode 100644 index 000000000000..eb72f3859d97 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax.dispatcher; + +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.tracer.BaseTracer; +import java.lang.reflect.Method; + +public class RequestDispatcherTracer extends BaseTracer { + private static final RequestDispatcherTracer TRACER = new RequestDispatcherTracer(); + + public static RequestDispatcherTracer tracer() { + return TRACER; + } + + @Override + protected String getInstrumentationName() { + return "io.opentelemetry.javaagent.servlet-jakarta"; + } + + public Context startSpan(Method method) { + return startSpan(spanNameForMethod(method)); + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java new file mode 100644 index 000000000000..b17886abbc9b --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax.response; + +import static io.opentelemetry.javaagent.instrumentation.servlet.javax.response.ResponseTracer.tracer; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepth; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseAdviceHelper; +import java.lang.reflect.Method; +import javax.servlet.http.HttpServletResponse; +import net.bytebuddy.asm.Advice; + +public class ResponseSendAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void start( + @Advice.Origin Method method, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Local("otelCallDepth") CallDepth callDepth) { + callDepth = CallDepthThreadLocalMap.getCallDepth(HttpServletResponse.class); + // Don't want to generate a new top-level span + if (callDepth.getAndIncrement() == 0 + && Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) { + context = tracer().startSpan(method); + scope = context.makeCurrent(); + } + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope, + @Advice.Local("otelCallDepth") CallDepth callDepth) { + HttpServletResponseAdviceHelper.stopSpan( + tracer(), HttpServletResponse.class, throwable, context, scope, callDepth); + } +} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseTracer.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseTracer.java new file mode 100644 index 000000000000..4be66f2338f1 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseTracer.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.servlet.javax.response; + +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.tracer.BaseTracer; +import java.lang.reflect.Method; + +public class ResponseTracer extends BaseTracer { + private static final ResponseTracer TRACER = new ResponseTracer(); + + public static ResponseTracer tracer() { + return TRACER; + } + + @Override + protected String getInstrumentationName() { + return "io.opentelemetry.javaagent.servlet-javax-common"; + } + + public Context startSpan(Method method) { + return startSpan(spanNameForMethod(method)); + } +} diff --git a/instrumentation/servlet/servlet-common/javaagent/src/test/groovy/HttpServletResponseTest.groovy b/instrumentation/servlet/servlet-javax-common/javaagent/src/test/groovy/HttpServletResponseTest.groovy similarity index 100% rename from instrumentation/servlet/servlet-common/javaagent/src/test/groovy/HttpServletResponseTest.groovy rename to instrumentation/servlet/servlet-javax-common/javaagent/src/test/groovy/HttpServletResponseTest.groovy diff --git a/instrumentation/servlet/servlet-common/javaagent/src/test/groovy/RequestDispatcherTest.groovy b/instrumentation/servlet/servlet-javax-common/javaagent/src/test/groovy/RequestDispatcherTest.groovy similarity index 100% rename from instrumentation/servlet/servlet-common/javaagent/src/test/groovy/RequestDispatcherTest.groovy rename to instrumentation/servlet/servlet-javax-common/javaagent/src/test/groovy/RequestDispatcherTest.groovy diff --git a/instrumentation/servlet/servlet-common/javaagent/src/test/java/RequestDispatcherUtils.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/test/java/RequestDispatcherUtils.java similarity index 100% rename from instrumentation/servlet/servlet-common/javaagent/src/test/java/RequestDispatcherUtils.java rename to instrumentation/servlet/servlet-javax-common/javaagent/src/test/java/RequestDispatcherUtils.java diff --git a/instrumentation-core/servlet-2.2/servlet-2.2.gradle b/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle similarity index 78% rename from instrumentation-core/servlet-2.2/servlet-2.2.gradle rename to instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle index 0e2fe0036237..2231bece13c1 100644 --- a/instrumentation-core/servlet-2.2/servlet-2.2.gradle +++ b/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle @@ -1,11 +1,13 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" // need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-2.2" +archivesBaseName = "servlet-javax-common" dependencies { implementation deps.slf4j + api(project(':instrumentation:servlet:servlet-common:library')) + compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.2' testImplementation group: 'javax.servlet', name: 'servlet-api', version: '2.2' diff --git a/instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/HttpServletRequestGetter.java b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxHttpServletRequestGetter.java similarity index 65% rename from instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/HttpServletRequestGetter.java rename to instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxHttpServletRequestGetter.java index 18096c3497ee..3618bc62fb4c 100644 --- a/instrumentation-core/servlet-2.2/src/main/java/io/opentelemetry/instrumentation/servlet/HttpServletRequestGetter.java +++ b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxHttpServletRequestGetter.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.servlet; +package io.opentelemetry.instrumentation.servlet.javax; import io.opentelemetry.context.propagation.TextMapGetter; import java.util.Collections; import javax.servlet.http.HttpServletRequest; -public class HttpServletRequestGetter implements TextMapGetter { +public class JavaxHttpServletRequestGetter implements TextMapGetter { - public static final HttpServletRequestGetter GETTER = new HttpServletRequestGetter(); + public static final JavaxHttpServletRequestGetter GETTER = new JavaxHttpServletRequestGetter(); @Override public Iterable keys(HttpServletRequest carrier) { diff --git a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java new file mode 100644 index 000000000000..15b4bd16d515 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java @@ -0,0 +1,89 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.javax; + +import io.opentelemetry.instrumentation.servlet.ServletAccessor; +import java.security.Principal; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +public abstract class JavaxServletAccessor + implements ServletAccessor { + @Override + public String getRequestContextPath(HttpServletRequest request) { + return request.getContextPath(); + } + + @Override + public String getRequestScheme(HttpServletRequest request) { + return request.getScheme(); + } + + @Override + public String getRequestServerName(HttpServletRequest request) { + return request.getServerName(); + } + + @Override + public int getRequestServerPort(HttpServletRequest request) { + return request.getServerPort(); + } + + @Override + public String getRequestURI(HttpServletRequest request) { + return request.getRequestURI(); + } + + @Override + public String getRequestQueryString(HttpServletRequest request) { + return request.getQueryString(); + } + + @Override + public Object getRequestAttribute(HttpServletRequest request, String name) { + return request.getAttribute(name); + } + + @Override + public void setRequestAttribute(HttpServletRequest request, String name, Object value) { + request.setAttribute(name, value); + } + + @Override + public String getRequestProtocol(HttpServletRequest request) { + return request.getProtocol(); + } + + @Override + public String getRequestMethod(HttpServletRequest request) { + return request.getMethod(); + } + + @Override + public String getRequestRemoteAddr(HttpServletRequest request) { + return request.getRemoteAddr(); + } + + @Override + public String getRequestHeader(HttpServletRequest request, String name) { + return request.getHeader(name); + } + + @Override + public String getRequestServletPath(HttpServletRequest request) { + return request.getServletPath(); + } + + @Override + public Principal getRequestUserPrincipal(HttpServletRequest request) { + return request.getUserPrincipal(); + } + + @Override + public boolean isServletException(Throwable throwable) { + return throwable instanceof ServletException; + } +} diff --git a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletHttpServerTracer.java b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletHttpServerTracer.java new file mode 100644 index 000000000000..178de1ead149 --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletHttpServerTracer.java @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.servlet.javax; + +import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.instrumentation.servlet.ServletHttpServerTracer; +import javax.servlet.http.HttpServletRequest; + +public abstract class JavaxServletHttpServerTracer + extends ServletHttpServerTracer { + public JavaxServletHttpServerTracer(JavaxServletAccessor accessor) { + super(accessor); + } + + @Override + protected TextMapGetter getGetter() { + return JavaxHttpServletRequestGetter.GETTER; + } +} diff --git a/instrumentation/servlet/servlet-javax-common/library/src/test/java/RequestOnlyTracer.java b/instrumentation/servlet/servlet-javax-common/library/src/test/java/RequestOnlyTracer.java new file mode 100644 index 000000000000..22bf9435676d --- /dev/null +++ b/instrumentation/servlet/servlet-javax-common/library/src/test/java/RequestOnlyTracer.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; +import io.opentelemetry.instrumentation.servlet.javax.JavaxServletHttpServerTracer; +import javax.servlet.http.HttpServletRequest; + +public class RequestOnlyTracer extends JavaxServletHttpServerTracer { + public RequestOnlyTracer() { + super( + new JavaxServletAccessor() { + @Override + public Integer getRequestRemotePort(HttpServletRequest httpServletRequest) { + return null; + } + + @Override + public int getResponseStatus(Void unused) { + return 0; + } + + @Override + public boolean isResponseCommitted(Void unused) { + return false; + } + }); + } + + @Override + protected String getInstrumentationName() { + return null; + } +} diff --git a/instrumentation-core/servlet-2.2/src/test/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracerTest.java b/instrumentation/servlet/servlet-javax-common/library/src/test/java/ServletHttpServerTracerTest.java similarity index 79% rename from instrumentation-core/servlet-2.2/src/test/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracerTest.java rename to instrumentation/servlet/servlet-javax-common/library/src/test/java/ServletHttpServerTracerTest.java index e9f3211baadb..2dd8c5b992a9 100644 --- a/instrumentation-core/servlet-2.2/src/test/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracerTest.java +++ b/instrumentation/servlet/servlet-javax-common/library/src/test/java/ServletHttpServerTracerTest.java @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.servlet; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; @@ -14,13 +12,14 @@ import org.junit.jupiter.api.Test; public class ServletHttpServerTracerTest { + private static final RequestOnlyTracer tracer = new RequestOnlyTracer(); @Test void testGetSpanName_emptySpanName() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn(""); when(request.getMethod()).thenReturn("PUT"); - String spanName = ServletHttpServerTracer.getSpanName(request); + String spanName = tracer.getSpanName(request); assertThat(spanName).isEqualTo("HTTP PUT"); } @@ -28,8 +27,7 @@ void testGetSpanName_emptySpanName() { void testGetSpanName_nullSpanName() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn(null); - assertThatThrownBy(() -> ServletHttpServerTracer.getSpanName(request)) - .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> tracer.getSpanName(request)).isInstanceOf(NullPointerException.class); } @Test @@ -37,7 +35,7 @@ void testGetSpanName_nullContextPath() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn("/swizzler"); when(request.getContextPath()).thenReturn(null); - String spanName = ServletHttpServerTracer.getSpanName(request); + String spanName = tracer.getSpanName(request); assertThat(spanName).isEqualTo("/swizzler"); } @@ -46,7 +44,7 @@ void testGetSpanName_emptyContextPath() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn("/swizzler"); when(request.getContextPath()).thenReturn(""); - String spanName = ServletHttpServerTracer.getSpanName(request); + String spanName = tracer.getSpanName(request); assertThat(spanName).isEqualTo("/swizzler"); } @@ -55,7 +53,7 @@ void testGetSpanName_slashContextPath() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn("/swizzler"); when(request.getContextPath()).thenReturn("/"); - String spanName = ServletHttpServerTracer.getSpanName(request); + String spanName = tracer.getSpanName(request); assertThat(spanName).isEqualTo("/swizzler"); } @@ -64,7 +62,7 @@ void testGetSpanName_appendsSpanNameToContext() { HttpServletRequest request = mock(HttpServletRequest.class); when(request.getServletPath()).thenReturn("/swizzler"); when(request.getContextPath()).thenReturn("/path/to"); - String spanName = ServletHttpServerTracer.getSpanName(request); + String spanName = tracer.getSpanName(request); assertThat(spanName).isEqualTo("/path/to/swizzler"); } } diff --git a/instrumentation/spring/spring-webmvc-3.1/javaagent/spring-webmvc-3.1-javaagent.gradle b/instrumentation/spring/spring-webmvc-3.1/javaagent/spring-webmvc-3.1-javaagent.gradle index d5fce2dbb8cb..021fd55528d6 100644 --- a/instrumentation/spring/spring-webmvc-3.1/javaagent/spring-webmvc-3.1-javaagent.gradle +++ b/instrumentation/spring/spring-webmvc-3.1/javaagent/spring-webmvc-3.1-javaagent.gradle @@ -33,7 +33,7 @@ dependencies { // Include servlet instrumentation for verifying the tomcat requests testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testInstrumentation project(':instrumentation:tomcat-7.0:javaagent') testImplementation group: 'javax.validation', name: 'validation-api', version: '1.1.0.Final' diff --git a/instrumentation/spring/spring-webmvc-3.1/library/spring-webmvc-3.1-library.gradle b/instrumentation/spring/spring-webmvc-3.1/library/spring-webmvc-3.1-library.gradle index 3bc5df3f7086..bf0912b15172 100644 --- a/instrumentation/spring/spring-webmvc-3.1/library/spring-webmvc-3.1-library.gradle +++ b/instrumentation/spring/spring-webmvc-3.1/library/spring-webmvc-3.1-library.gradle @@ -1,7 +1,8 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" dependencies { - implementation project(':instrumentation-core:servlet-2.2') + implementation project(':instrumentation:servlet:servlet-common:library') + implementation project(':instrumentation:servlet:servlet-javax-common:library') compileOnly group: 'org.springframework', name: 'spring-webmvc', version: '3.1.0.RELEASE' compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0' diff --git a/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcServerTracer.java b/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcServerTracer.java index be9198414e5b..21f0a15907fa 100644 --- a/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcServerTracer.java +++ b/instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcServerTracer.java @@ -9,7 +9,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer; -import io.opentelemetry.instrumentation.servlet.HttpServletRequestGetter; +import io.opentelemetry.instrumentation.servlet.javax.JavaxHttpServletRequestGetter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -33,7 +33,7 @@ protected String peerHostIP(HttpServletRequest request) { @Override protected TextMapGetter getGetter() { - return HttpServletRequestGetter.GETTER; + return JavaxHttpServletRequestGetter.GETTER; } @Override diff --git a/instrumentation/struts-2.3/javaagent/struts-2.3-javaagent.gradle b/instrumentation/struts-2.3/javaagent/struts-2.3-javaagent.gradle index 51b12f456dee..b1ad13d67135 100644 --- a/instrumentation/struts-2.3/javaagent/struts-2.3-javaagent.gradle +++ b/instrumentation/struts-2.3/javaagent/struts-2.3-javaagent.gradle @@ -24,7 +24,7 @@ dependencies { testRuntimeOnly group: 'javax.servlet', name: 'jsp-api', version: '2.0' testInstrumentation project(":instrumentation:servlet:servlet-3.0:javaagent") - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testInstrumentation project(':instrumentation:jetty-8.0:javaagent') } diff --git a/instrumentation/tomcat-7.0/javaagent/tomcat-7.0-javaagent.gradle b/instrumentation/tomcat-7.0/javaagent/tomcat-7.0-javaagent.gradle index f8a32b71f17c..459442ef6e6e 100644 --- a/instrumentation/tomcat-7.0/javaagent/tomcat-7.0-javaagent.gradle +++ b/instrumentation/tomcat-7.0/javaagent/tomcat-7.0-javaagent.gradle @@ -13,7 +13,7 @@ muzzle { dependencies { library group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '7.0.4' implementation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') // Tests need at least version 9 to have necessary classes to configure the embedded tomcat... // ... but not newer that version 10, because its servlet 5. diff --git a/instrumentation/wicket-8.0/javaagent/wicket-8.0-javaagent.gradle b/instrumentation/wicket-8.0/javaagent/wicket-8.0-javaagent.gradle index 773afebafc74..18d49764e8f6 100644 --- a/instrumentation/wicket-8.0/javaagent/wicket-8.0-javaagent.gradle +++ b/instrumentation/wicket-8.0/javaagent/wicket-8.0-javaagent.gradle @@ -18,5 +18,5 @@ dependencies { testImplementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.0.0.v20110901' testInstrumentation project(":instrumentation:servlet:servlet-3.0:javaagent") - testInstrumentation project(":instrumentation:servlet:servlet-common:javaagent") + testInstrumentation project(":instrumentation:servlet:servlet-javax-common:javaagent") } diff --git a/settings.gradle b/settings.gradle index c96fbfe1d35d..8fa8efaffd35 100644 --- a/settings.gradle +++ b/settings.gradle @@ -226,9 +226,16 @@ include ':instrumentation:rxjava-2.0:testing' include ':instrumentation:rxjava-2.0:javaagent' include ':instrumentation:scala-executors:javaagent' include ':instrumentation:servlet:glassfish-testing' +include ':instrumentation:servlet:servlet-common:library' include ':instrumentation:servlet:servlet-common:javaagent' +include ':instrumentation:servlet:servlet-javax-common:library' +include ':instrumentation:servlet:servlet-javax-common:javaagent' +include ':instrumentation:servlet:servlet-2.2:library' include ':instrumentation:servlet:servlet-2.2:javaagent' +include ':instrumentation:servlet:servlet-3.0:library' include ':instrumentation:servlet:servlet-3.0:javaagent' +include ':instrumentation:servlet:servlet-jakarta:library' +include ':instrumentation:servlet:servlet-jakarta:javaagent' include ':instrumentation:spark-2.3:javaagent' include ':instrumentation:spring:spring-batch-3.0:javaagent' include ':instrumentation:spring:spring-core-2.0:javaagent' @@ -257,8 +264,6 @@ include ':instrumentation:rocketmq-client-4.8:javaagent' include ':instrumentation:rocketmq-client-4.8:library' include ':instrumentation:rocketmq-client-4.8:testing' -include ':instrumentation-core:servlet-2.2' - // benchmark include ':benchmark' include ':benchmark-integration' diff --git a/smoke-tests/matrix/build.gradle b/smoke-tests/matrix/build.gradle index 44ce5cf6ddb3..069dc917c64e 100644 --- a/smoke-tests/matrix/build.gradle +++ b/smoke-tests/matrix/build.gradle @@ -45,6 +45,7 @@ def linuxTargets = [ "jetty": [ [version: ["9.4.35"], vm: ["hotspot", "openj9"], jdk: ["8", "11", "15"]], [version: ["10.0.0"], vm: ["hotspot", "openj9"], jdk: ["11", "15"]], + [version: ["11.0.1"], vm: ["hotspot", "openj9"], jdk: ["11", "15"], war: "servlet-jakarta"] ], "tomcat": [ [version: ["7.0.107"], vm: ["hotspot", "openj9"], jdk: ["8"]], @@ -99,13 +100,14 @@ def windowsTargets = [ createDockerTasks(buildLinuxTestImagesTask, linuxTargets, false) createDockerTasks(buildWindowsTestImagesTask, windowsTargets, true) -def configureImage(Task parentTask, server, dockerfile, version, vm, jdk, Map extraArgs, isWindows = false) { - def dockerWorkingDir = new File(project.buildDir, "docker") +def configureImage(Task parentTask, server, dockerfile, version, vm, jdk, warProject, Map extraArgs, isWindows = false) { + // Using separate build directory for different war files allows using the same app.war filename + def dockerWorkingDir = new File(project.buildDir, warProject != null ? "docker-$warProject" : "docker") def dockerFileName = isWindows ? "${dockerfile}.windows.dockerfile" : "${dockerfile}.dockerfile" def platformSuffix = isWindows ? "-windows" : "" def prepareTask = tasks.register("${server}ImagePrepare-$version-jdk$jdk-$vm$platformSuffix", Copy) { - def warTask = project.tasks.war + def warTask = warProject != null ? project(":$warProject").tasks["war"] : project.tasks.war it.dependsOn(warTask) it.into(dockerWorkingDir) it.from("src/$dockerFileName") @@ -143,11 +145,12 @@ def createDockerTasks(Task parentTask, targets, isWindows) { matrices.forEach { entry -> def dockerfile = entry["dockerfile"]?.toString() ?: server def extraArgs = (entry["args"] ?: [:]) as Map + def warProject = entry["war"] entry.version.forEach { version -> entry.vm.forEach { vm -> entry.jdk.forEach { jdk -> - resultImages.add(configureImage(parentTask, server, dockerfile, version, vm, jdk, extraArgs, isWindows)) + resultImages.add(configureImage(parentTask, server, dockerfile, version, vm, jdk, warProject, extraArgs, isWindows)) } } } diff --git a/smoke-tests/matrix/servlet-jakarta/build.gradle b/smoke-tests/matrix/servlet-jakarta/build.gradle new file mode 100644 index 000000000000..6e4f5ce86fa2 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/build.gradle @@ -0,0 +1,15 @@ +plugins { + id "war" +} + +compileJava { + options.release.set(11) +} + +repositories { + jcenter() +} + +dependencies { + compileOnly("jakarta.servlet:jakarta.servlet-api:5.0.0") +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java new file mode 100644 index 000000000000..284e528dcf05 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java @@ -0,0 +1,54 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.AsyncContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +public class AsyncGreetingServlet extends GreetingServlet { + private static final BlockingQueue jobQueue = new LinkedBlockingQueue<>(); + private static final ExecutorService executor = Executors.newFixedThreadPool(2); + + @Override + public void init() throws ServletException { + executor.submit(new Runnable() { + @Override + public void run() { + try { + while (true) { + AsyncContext ac = jobQueue.take(); + executor.submit(() -> handleRequest(ac)); + } + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + }); + } + + @Override + public void destroy() { + executor.shutdownNow(); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + AsyncContext ac = req.startAsync(req, resp); + jobQueue.add(ac); + } + + private void handleRequest(AsyncContext ac) { + ac.dispatch("/greeting"); + } + +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java new file mode 100644 index 000000000000..74e05695266d --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java @@ -0,0 +1,21 @@ +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.ServletRequestEvent; +import jakarta.servlet.ServletRequestListener; + +public class ExceptionRequestListener implements ServletRequestListener { + + @Override + public void requestDestroyed(ServletRequestEvent sre) { + if ("true".equals(sre.getServletRequest().getParameter("throwOnRequestDestroyed"))) { + throw new RuntimeException("This is expected"); + } + } + + @Override + public void requestInitialized(ServletRequestEvent sre) { + if ("true".equals(sre.getServletRequest().getParameter("throwOnRequestInitialized"))) { + throw new RuntimeException("This is expected"); + } + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java new file mode 100644 index 000000000000..65f4784233a1 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ExceptionServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + throw new RuntimeException("This is expected"); + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java new file mode 100644 index 000000000000..add8bec40fd4 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ForwardServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher("/hello.txt").forward(req, resp); + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java new file mode 100644 index 000000000000..e4b9ead0833d --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Objects; + +public class GreetingServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String path = (req.getContextPath() + "/headers").replace("//", "/"); + URL url = new URL("http", "localhost", req.getLocalPort(), path); + URLConnection urlConnection = url.openConnection(); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + try (InputStream remoteInputStream = urlConnection.getInputStream()) { + long bytesRead = transfer(remoteInputStream, buffer); + String responseBody = buffer.toString("UTF-8"); + ServletOutputStream outputStream = resp.getOutputStream(); + outputStream.print( + bytesRead + " bytes read by " + urlConnection.getClass().getName() + "\n" + responseBody); + outputStream.flush(); + } + } + + // We have to run on Java 8, so no Java 9 stream transfer goodies for us. + private long transfer(InputStream from, OutputStream to) throws IOException { + Objects.requireNonNull(to, "out"); + long transferred = 0; + byte[] buffer = new byte[65535]; + int read; + while ((read = from.read(buffer, 0, buffer.length)) >= 0) { + to.write(buffer, 0, read); + transferred += read; + } + return transferred; + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java new file mode 100644 index 000000000000..75a6e17faf65 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +public class HeaderDumpingServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter response = resp.getWriter(); + Enumeration headerNames = req.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + response.write(headerName + ": "); + + List headers = Collections.list(req.getHeaders(headerName)); + if (headers.size() == 1) { + response.write(headers.get(0)); + } else { + response.write("["); + for (String header : headers) { + response.write(" " + header + ",\n"); + } + response.write("]"); + } + response.write("\n"); + } + + response.flush(); + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java new file mode 100644 index 000000000000..7973cc26f229 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class IncludeServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher("/hello.txt").include(req, resp); + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java new file mode 100644 index 000000000000..aa140d16ea09 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.smoketest.matrix; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class JspServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws IOException, ServletException { + RequestDispatcher resultView = req.getRequestDispatcher("test.jsp"); + resultView.forward(req, resp); + } +} diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000000..4ee1f5472fd0 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,66 @@ + + + io.opentelemetry.smoketest.matrix.ExceptionRequestListener + + + Headers + io.opentelemetry.smoketest.matrix.HeaderDumpingServlet + + + Greeting + io.opentelemetry.smoketest.matrix.GreetingServlet + + + AsyncGreeting + io.opentelemetry.smoketest.matrix.AsyncGreetingServlet + true + + + Exception + io.opentelemetry.smoketest.matrix.ExceptionServlet + + + Forward + io.opentelemetry.smoketest.matrix.ForwardServlet + + + Include + io.opentelemetry.smoketest.matrix.IncludeServlet + + + Jsp + io.opentelemetry.smoketest.matrix.JspServlet + + + Headers + /headers + + + Greeting + /greeting + + + AsyncGreeting + /asyncgreeting + + + Exception + /exception + + + Forward + /forward + + + Include + /include + + + Jsp + /jsp + + \ No newline at end of file diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt new file mode 100644 index 000000000000..5ab2f8a4323a --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp new file mode 100644 index 000000000000..bc2bb7ae28c5 --- /dev/null +++ b/smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp @@ -0,0 +1,10 @@ + +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Successful JSP test + + + This JSP demonstrates that Otel instrumentation agent does not break JSP compilation and loading. + + diff --git a/smoke-tests/matrix/settings.gradle b/smoke-tests/matrix/settings.gradle index 9a5efa406dbd..a0a03aa1a8b9 100644 --- a/smoke-tests/matrix/settings.gradle +++ b/smoke-tests/matrix/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'matrix' + +include ':servlet-jakarta' From a883125064f23c398ddd2f1965d430adb2db95b4 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Sat, 20 Mar 2021 08:09:22 +0200 Subject: [PATCH 02/11] Include correct servlet instrumentation module for grails tests --- .../grails-3.0/javaagent/grails-3.0-javaagent.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/grails-3.0/javaagent/grails-3.0-javaagent.gradle b/instrumentation/grails-3.0/javaagent/grails-3.0-javaagent.gradle index ce89a5690d5e..23ec631ffaa9 100644 --- a/instrumentation/grails-3.0/javaagent/grails-3.0-javaagent.gradle +++ b/instrumentation/grails-3.0/javaagent/grails-3.0-javaagent.gradle @@ -29,7 +29,7 @@ dependencies { library("org.grails:grails-plugin-url-mappings:$grailsVersion") testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent') - testInstrumentation project(':instrumentation:servlet:servlet-common:javaagent') + testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent') testInstrumentation project(':instrumentation:tomcat-7.0:javaagent') testInstrumentation project(':instrumentation:spring:spring-webmvc-3.1:javaagent') From 00f0169472b24dd375977b726b1a2e72c2e2fb6c Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Sat, 20 Mar 2021 10:10:53 +0200 Subject: [PATCH 03/11] Reapply spotless after rebase --- .../javaagent/instrumentation/servlet/v3_0/Servlet3Advice.java | 2 +- .../src/test/java/JakartaServletHttpServerTracerTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) 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 0260d4bcd2da..91588ae8cd7b 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 @@ -129,4 +129,4 @@ public static void stopSpan( tracer().end(context, (HttpServletResponse) response); } } -} \ No newline at end of file +} diff --git a/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java b/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java index 729775ed4131..73567a66fa8b 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java +++ b/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java @@ -13,7 +13,8 @@ import org.junit.jupiter.api.Test; public class JakartaServletHttpServerTracerTest { - private static final JakartaServletHttpServerTracer tracer = JakartaServletHttpServerTracer.tracer(); + private static final JakartaServletHttpServerTracer tracer = + JakartaServletHttpServerTracer.tracer(); @Test void testGetSpanName_emptySpanName() { From 0687775e151bad26e18c6fa6257b0c2545064926 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Sat, 20 Mar 2021 12:02:37 +0200 Subject: [PATCH 04/11] Fix checkstyle --- .../servlet/ServletAccessor.java | 36 +++++++++---------- .../servlet/ServletHttpServerTracer.java | 2 +- .../jakarta/JakartaServletAccessor.java | 2 +- .../servlet/javax/JavaxServletAccessor.java | 6 ++-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java index b413f9b8f6ce..b5e67aa2e07c 100644 --- a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java @@ -7,40 +7,40 @@ import java.security.Principal; -public interface ServletAccessor { - String getRequestContextPath(REQUEST request); +public interface ServletAccessor { + String getRequestContextPath(RequestT request); - String getRequestScheme(REQUEST request); + String getRequestScheme(RequestT request); - String getRequestServerName(REQUEST request); + String getRequestServerName(RequestT request); - int getRequestServerPort(REQUEST request); + int getRequestServerPort(RequestT request); - String getRequestURI(REQUEST request); + String getRequestUri(RequestT request); - String getRequestQueryString(REQUEST request); + String getRequestQueryString(RequestT request); - Object getRequestAttribute(REQUEST request, String name); + Object getRequestAttribute(RequestT request, String name); - void setRequestAttribute(REQUEST request, String name, Object value); + void setRequestAttribute(RequestT request, String name, Object value); - String getRequestProtocol(REQUEST request); + String getRequestProtocol(RequestT request); - String getRequestMethod(REQUEST request); + String getRequestMethod(RequestT request); - String getRequestRemoteAddr(REQUEST request); + String getRequestRemoteAddr(RequestT request); - String getRequestHeader(REQUEST request, String name); + String getRequestHeader(RequestT request, String name); - String getRequestServletPath(REQUEST request); + String getRequestServletPath(RequestT request); - Principal getRequestUserPrincipal(REQUEST request); + Principal getRequestUserPrincipal(RequestT request); - Integer getRequestRemotePort(REQUEST request); + Integer getRequestRemotePort(RequestT request); - int getResponseStatus(RESPONSE response); + int getResponseStatus(ResponseT response); - boolean isResponseCommitted(RESPONSE response); + boolean isResponseCommitted(ResponseT response); boolean isServletException(Throwable throwable); } diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java index 8754dfd73fc7..313817c9ead0 100644 --- a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java @@ -87,7 +87,7 @@ protected String url(REQUEST httpServletRequest) { null, accessor.getRequestServerName(httpServletRequest), accessor.getRequestServerPort(httpServletRequest), - accessor.getRequestURI(httpServletRequest), + accessor.getRequestUri(httpServletRequest), accessor.getRequestQueryString(httpServletRequest), null) .toString(); diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java index 83561ef2aec4..709b85bdfe6e 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java +++ b/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java @@ -38,7 +38,7 @@ public int getRequestServerPort(HttpServletRequest request) { } @Override - public String getRequestURI(HttpServletRequest request) { + public String getRequestUri(HttpServletRequest request) { return request.getRequestURI(); } diff --git a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java index 15b4bd16d515..9b612fafb004 100644 --- a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java +++ b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java @@ -10,8 +10,8 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; -public abstract class JavaxServletAccessor - implements ServletAccessor { +public abstract class JavaxServletAccessor + implements ServletAccessor { @Override public String getRequestContextPath(HttpServletRequest request) { return request.getContextPath(); @@ -33,7 +33,7 @@ public int getRequestServerPort(HttpServletRequest request) { } @Override - public String getRequestURI(HttpServletRequest request) { + public String getRequestUri(HttpServletRequest request) { return request.getRequestURI(); } From 80f6aa7c6a89bdc1c1f3c358867b37ee42a64865 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Sat, 20 Mar 2021 12:33:51 +0200 Subject: [PATCH 05/11] Spotless --- .../instrumentation/servlet/javax/JavaxServletAccessor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java index 9b612fafb004..c90a2761e21f 100644 --- a/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java +++ b/instrumentation/servlet/servlet-javax-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/javax/JavaxServletAccessor.java @@ -10,8 +10,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; -public abstract class JavaxServletAccessor - implements ServletAccessor { +public abstract class JavaxServletAccessor implements ServletAccessor { @Override public String getRequestContextPath(HttpServletRequest request) { return request.getContextPath(); From f4b44ff92bb6663c44ce05ec26dbdb961cdff751 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Mon, 22 Mar 2021 07:30:41 +0200 Subject: [PATCH 06/11] Addressed PR suggestions --- instrumentation/servlet/README.md | 4 +- .../v2_2/Servlet2InstrumentationModule.java | 2 +- .../library/servlet-2.2-library.gradle | 3 -- .../v2_2/Servlet2HttpServerTracer.java | 8 ++-- .../v3_0/Servlet3InstrumentationModule.java | 4 +- .../servlet/v3_0/TagSettingAsyncListener.java | 2 +- .../library/servlet-3.0-library.gradle | 3 -- .../v3_0/Servlet3HttpServerTracer.java | 2 +- .../javaagent/servlet-5.0-javaagent.gradle} | 2 +- .../JakartaServletInstrumentationModule.java | 12 +++--- .../v5_0}/RequestDispatcherAdvice.java | 34 +++++++++-------- .../v5_0}/RequestDispatcherTracer.java | 4 +- .../v5_0}/async/AsyncDispatchAdvice.java | 2 +- .../v5_0}/response/ResponseSendAdvice.java | 4 +- .../v5_0}/response/ResponseTracer.java | 4 +- .../service/JakartaServletServiceAdvice.java | 4 +- .../service/TagSettingAsyncListener.java | 4 +- .../library/servlet-5.0-library.gradle} | 3 -- .../JakartaHttpServletRequestGetter.java | 2 +- .../jakarta/v5_0}/JakartaServletAccessor.java | 2 +- .../v5_0}/JakartaServletHttpServerTracer.java | 4 +- .../JakartaServletHttpServerTracerTest.java | 2 +- .../async/AsyncContextInstrumentation.java | 2 +- .../RequestDispatcherAdviceHelper.java | 37 ++----------------- .../RequestDispatcherInstrumentation.java | 2 +- .../HttpServletResponseAdviceHelper.java | 2 +- .../HttpServletResponseInstrumentation.java | 2 +- .../ServletAndFilterInstrumentation.java | 2 +- .../library/servlet-common-library.gradle | 3 -- .../servlet/ServletHttpServerTracer.java | 2 +- .../javax/JavaxCommonServletAccessor.java | 30 --------------- .../JavaxServletInstrumentationModule.java | 4 +- .../dispatcher/RequestDispatcherAdvice.java | 31 +++++++++------- .../dispatcher/RequestDispatcherTracer.java | 2 +- .../javax/response/ResponseSendAdvice.java | 2 +- .../servlet-javax-common-library.gradle | 3 -- settings.gradle | 4 +- smoke-tests/matrix/build.gradle | 19 ++-------- smoke-tests/matrix/servlet-3.0/build.gradle | 15 ++++++++ .../matrix/AsyncGreetingServlet.java | 0 .../matrix/ExceptionRequestListener.java | 0 .../smoketest/matrix/ExceptionServlet.java | 0 .../smoketest/matrix/ForwardServlet.java | 0 .../smoketest/matrix/GreetingServlet.java | 0 .../matrix/HeaderDumpingServlet.java | 0 .../smoketest/matrix/IncludeServlet.java | 0 .../smoketest/matrix/JspServlet.java | 0 .../src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/hello.txt | 0 .../src/main/webapp/test.jsp | 0 .../build.gradle | 2 +- .../matrix/AsyncGreetingServlet.java | 0 .../matrix/ExceptionRequestListener.java | 0 .../smoketest/matrix/ExceptionServlet.java | 0 .../smoketest/matrix/ForwardServlet.java | 0 .../smoketest/matrix/GreetingServlet.java | 0 .../matrix/HeaderDumpingServlet.java | 0 .../smoketest/matrix/IncludeServlet.java | 0 .../smoketest/matrix/JspServlet.java | 0 .../src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/hello.txt | 0 .../src/main/webapp/test.jsp | 0 smoke-tests/matrix/settings.gradle | 3 +- 63 files changed, 105 insertions(+), 173 deletions(-) rename instrumentation/servlet/{servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle => servlet-5.0/javaagent/servlet-5.0-javaagent.gradle} (84%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/JakartaServletInstrumentationModule.java (74%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/RequestDispatcherAdvice.java (68%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/RequestDispatcherTracer.java (81%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/async/AsyncDispatchAdvice.java (96%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/response/ResponseSendAdvice.java (93%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/response/ResponseTracer.java (81%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/service/JakartaServletServiceAdvice.java (96%) rename instrumentation/servlet/{servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet => servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0}/service/TagSettingAsyncListener.java (90%) rename instrumentation/servlet/{servlet-jakarta/library/servlet-jakarta-library.gradle => servlet-5.0/library/servlet-5.0-library.gradle} (79%) rename instrumentation/servlet/{servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta => servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0}/JakartaHttpServletRequestGetter.java (91%) rename instrumentation/servlet/{servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta => servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0}/JakartaServletAccessor.java (97%) rename instrumentation/servlet/{servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta => servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0}/JakartaServletHttpServerTracer.java (97%) rename instrumentation/servlet/{servlet-jakarta => servlet-5.0}/library/src/test/java/JakartaServletHttpServerTracerTest.java (96%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/async/AsyncContextInstrumentation.java (95%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/dispatcher/RequestDispatcherAdviceHelper.java (50%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/dispatcher/RequestDispatcherInstrumentation.java (96%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/response/HttpServletResponseAdviceHelper.java (92%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/response/HttpServletResponseInstrumentation.java (95%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{ => v5_0}/service/ServletAndFilterInstrumentation.java (96%) delete mode 100644 instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java create mode 100644 smoke-tests/matrix/servlet-3.0/build.gradle rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java (100%) rename smoke-tests/matrix/{ => servlet-3.0}/src/main/webapp/WEB-INF/web.xml (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-3.0}/src/main/webapp/hello.txt (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-3.0}/src/main/webapp/test.jsp (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/build.gradle (90%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java (100%) rename smoke-tests/matrix/{servlet-jakarta => servlet-5.0}/src/main/webapp/WEB-INF/web.xml (100%) rename smoke-tests/matrix/{ => servlet-5.0}/src/main/webapp/hello.txt (100%) rename smoke-tests/matrix/{ => servlet-5.0}/src/main/webapp/test.jsp (100%) diff --git a/instrumentation/servlet/README.md b/instrumentation/servlet/README.md index f56601113a64..8aade0b23ba3 100644 --- a/instrumentation/servlet/README.md +++ b/instrumentation/servlet/README.md @@ -19,7 +19,7 @@ They are divided into the following sub-modules: - `servlet-javax-common` contains instrumentations/abstract tracer common for Servlet API versions `[2.2, 5)` - `servlet-2.2` contains instrumentations/tracer for Servlet API versions `[2.2, 3)` - `servlet-3.0` contains instrumentations/tracer for Servlet API versions `[3.0, 5)` - - `servlet-jakarta` contains instrumentations/tracer for Servlet API versions `[5,)` + - `servlet-5.0` contains instrumentations/tracer for Servlet API versions `[5,)` ## Implementation details @@ -58,7 +58,7 @@ This is the main target for `Servlet3Instrumentation` and `Servlet2Instrumentati `public void javax.servlet.http.HttpServlet#service(ServletRequest, ServletResponse)`. -These instrumentations are located in separate submodules `servlet-3.0`, `servlet-2.2` and `servlet-jakarta`, +These instrumentations are located in separate submodules `servlet-3.0`, `servlet-2.2` and `servlet-5.0`, because they and corresponding tests depend on different versions of the servlet specification. At last, request processing may reach the specific framework that your application uses. diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java index 77bf0831b2f7..b331c96041a5 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java @@ -10,7 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; diff --git a/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle b/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle index e10c3dbc8c80..62af68f0a6f0 100644 --- a/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle +++ b/instrumentation/servlet/servlet-2.2/library/servlet-2.2-library.gradle @@ -1,8 +1,5 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" -// need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-2.2" - dependencies { implementation deps.slf4j diff --git a/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java index 600e2bd92581..0900c3635c4d 100644 --- a/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java +++ b/instrumentation/servlet/servlet-2.2/library/src/main/java/io/opentelemetry/instrumentation/servlet/v2_2/Servlet2HttpServerTracer.java @@ -9,16 +9,14 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.servlet.ServletSpanNaming; import io.opentelemetry.instrumentation.api.tracer.ServerSpan; -import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; import io.opentelemetry.instrumentation.servlet.javax.JavaxServletHttpServerTracer; import javax.servlet.http.HttpServletRequest; public class Servlet2HttpServerTracer extends JavaxServletHttpServerTracer { - private static final Servlet2HttpServerTracer TRACER = - new Servlet2HttpServerTracer(Servlet2Accessor.INSTANCE); + private static final Servlet2HttpServerTracer TRACER = new Servlet2HttpServerTracer(); - public Servlet2HttpServerTracer(JavaxServletAccessor accessor) { - super(accessor); + public Servlet2HttpServerTracer() { + super(Servlet2Accessor.INSTANCE); } public static Servlet2HttpServerTracer tracer() { diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java index 082d2e63c517..5add4d67e580 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java @@ -8,8 +8,8 @@ import static java.util.Arrays.asList; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.async.AsyncContextInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.List; diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java index 181dbd8ec947..89019ad782f1 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/TagSettingAsyncListener.java @@ -14,7 +14,7 @@ public class TagSettingAsyncListener implements AsyncListener { private static final Servlet3HttpServerTracer servletHttpServerTracer = - new Servlet3HttpServerTracer(); + Servlet3HttpServerTracer.tracer(); private final AtomicBoolean responseHandled; private final Context context; diff --git a/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle b/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle index 0b60f6200974..2a6db3786ea0 100644 --- a/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle +++ b/instrumentation/servlet/servlet-3.0/library/servlet-3.0-library.gradle @@ -1,8 +1,5 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" -// need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-3.0" - dependencies { api(project(':instrumentation:servlet:servlet-javax-common:library')) diff --git a/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java index 74b50b93ba14..f17b9c6c13da 100644 --- a/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java +++ b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java @@ -22,7 +22,7 @@ public class Servlet3HttpServerTracer extends JavaxServletHttpServerTracer { private static final Servlet3HttpServerTracer TRACER = new Servlet3HttpServerTracer(); - public Servlet3HttpServerTracer() { + protected Servlet3HttpServerTracer() { super(Servlet3Accessor.INSTANCE); } diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle b/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle similarity index 84% rename from instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle rename to instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle index d757ca616a26..992eabaa805e 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/servlet-jakarta-javaagent.gradle +++ b/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle @@ -9,7 +9,7 @@ muzzle { } dependencies { - api(project(':instrumentation:servlet:servlet-jakarta:library')) + api(project(':instrumentation:servlet:servlet-5.0:library')) implementation(project(':instrumentation:servlet:servlet-common:javaagent')) compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '5.0.0' } diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java similarity index 74% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java index 0002a08cbe9b..4c303b2a0dc6 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/JakartaServletInstrumentationModule.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java @@ -3,15 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0; import static java.util.Collections.singletonMap; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.async.AsyncContextInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; @@ -23,7 +23,7 @@ public class JakartaServletInstrumentationModule extends InstrumentationModule { private static final String BASE_PACKAGE = "jakarta.servlet"; public JakartaServletInstrumentationModule() { - super("servlet", "servlet-jakarta"); + super("servlet", "servlet-5.0"); } @Override diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherAdvice.java similarity index 68% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherAdvice.java index 0527e8161a71..a1aed03378d7 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherAdvice.java @@ -3,16 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; +import static io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherTracer.tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletAccessor; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletRequest; -import jakarta.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import net.bytebuddy.asm.Advice; @@ -29,18 +28,17 @@ public static void start( Context parent = RequestDispatcherAdviceHelper.getStartParentContext( - JakartaServletAccessor.INSTANCE, (HttpServletRequest) request); + request.getAttribute(CONTEXT_ATTRIBUTE)); if (parent == null) { return; } try (Scope ignored = parent.makeCurrent()) { - context = RequestDispatcherTracer.tracer().startSpan(method); + context = tracer().startSpan(method); // save the original servlet span before overwriting the request attribute, so that it can - // be - // restored on method exit + // be restored on method exit originalContext = request.getAttribute(CONTEXT_ATTRIBUTE); // this tells the dispatched servlet to use the current span as the parent for its work @@ -57,13 +55,19 @@ public static void stop( @Advice.Local("otelScope") Scope scope, @Advice.Thrown Throwable throwable) { - RequestDispatcherAdviceHelper.stop( - RequestDispatcherTracer.tracer(), - JakartaServletAccessor.INSTANCE, - originalContext, - (HttpServletRequest) request, - context, - scope, - throwable); + scope.close(); + + // restore the original servlet span + // since spanWithScope is non-null here, originalContext must have been set with the + // prior + // servlet span (as opposed to remaining unset) + // TODO review this logic. Seems like manual context management + request.setAttribute(CONTEXT_ATTRIBUTE, originalContext); + + if (throwable != null) { + tracer().endExceptionally(context, throwable); + } else { + tracer().end(context); + } } } diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherTracer.java similarity index 81% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherTracer.java index 4b0c0687e761..a690df51d6f8 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherTracer.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-jakarta"; + return "io.opentelemetry.javaagent.servlet-javax-common"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncDispatchAdvice.java similarity index 96% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncDispatchAdvice.java index 1aee4607e9cd..db987c2079e3 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncDispatchAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncDispatchAdvice.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.async; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async; import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java similarity index 93% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java index 641a3d9a0612..b448d4c3590d 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseSendAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.response; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; -import static io.opentelemetry.javaagent.instrumentation.servlet.response.ResponseTracer.tracer; +import static io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.ResponseTracer.tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseTracer.java similarity index 81% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseTracer.java index e44a8fe94fc6..7f99d25ec4cc 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/ResponseTracer.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseTracer.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.response; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; @@ -18,7 +18,7 @@ public static ResponseTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-jakarta"; + return "io.opentelemetry.javaagent.servlet-5.0"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java similarity index 96% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java index 3bd99d272e5a..501cb3b55e34 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/JakartaServletServiceAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/JakartaServletServiceAdvice.java @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.service; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service; -import static io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer.tracer; +import static io.opentelemetry.instrumentation.servlet.jakarta.v5_0.JakartaServletHttpServerTracer.tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; diff --git a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/TagSettingAsyncListener.java similarity index 90% rename from instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/TagSettingAsyncListener.java index a67f27fd0be4..be1f98f3607b 100644 --- a/instrumentation/servlet/servlet-jakarta/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/TagSettingAsyncListener.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/TagSettingAsyncListener.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.service; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer; +import io.opentelemetry.instrumentation.servlet.jakarta.v5_0.JakartaServletHttpServerTracer; import jakarta.servlet.AsyncEvent; import jakarta.servlet.AsyncListener; import jakarta.servlet.http.HttpServletResponse; diff --git a/instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle b/instrumentation/servlet/servlet-5.0/library/servlet-5.0-library.gradle similarity index 79% rename from instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle rename to instrumentation/servlet/servlet-5.0/library/servlet-5.0-library.gradle index 3da00fc071d0..297499abdce0 100644 --- a/instrumentation/servlet/servlet-jakarta/library/servlet-jakarta-library.gradle +++ b/instrumentation/servlet/servlet-5.0/library/servlet-5.0-library.gradle @@ -1,8 +1,5 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" -// need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-jakarta" - dependencies { api(project(':instrumentation:servlet:servlet-common:library')) diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaHttpServletRequestGetter.java similarity index 91% rename from instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java rename to instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaHttpServletRequestGetter.java index b49588b23d4f..24ab41aab743 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaHttpServletRequestGetter.java +++ b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaHttpServletRequestGetter.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.servlet.jakarta; +package io.opentelemetry.instrumentation.servlet.jakarta.v5_0; import io.opentelemetry.context.propagation.TextMapGetter; import jakarta.servlet.http.HttpServletRequest; diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletAccessor.java similarity index 97% rename from instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java rename to instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletAccessor.java index 709b85bdfe6e..c4ed6d1d3c71 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletAccessor.java +++ b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletAccessor.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.servlet.jakarta; +package io.opentelemetry.instrumentation.servlet.jakarta.v5_0; import io.opentelemetry.instrumentation.servlet.ServletAccessor; import jakarta.servlet.ServletException; diff --git a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java similarity index 97% rename from instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java rename to instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java index d5dfe93983a4..457f48037d2e 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/JakartaServletHttpServerTracer.java +++ b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.servlet.jakarta; +package io.opentelemetry.instrumentation.servlet.jakarta.v5_0; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; @@ -133,7 +133,7 @@ public Context updateContext( @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-jakarta"; + return "io.opentelemetry.javaagent.servlet-5.0"; } @Override diff --git a/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java b/instrumentation/servlet/servlet-5.0/library/src/test/java/JakartaServletHttpServerTracerTest.java similarity index 96% rename from instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java rename to instrumentation/servlet/servlet-5.0/library/src/test/java/JakartaServletHttpServerTracerTest.java index 73567a66fa8b..11b64d9b9242 100644 --- a/instrumentation/servlet/servlet-jakarta/library/src/test/java/JakartaServletHttpServerTracerTest.java +++ b/instrumentation/servlet/servlet-5.0/library/src/test/java/JakartaServletHttpServerTracerTest.java @@ -8,7 +8,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import io.opentelemetry.instrumentation.servlet.jakarta.JakartaServletHttpServerTracer; +import io.opentelemetry.instrumentation.servlet.jakarta.v5_0.JakartaServletHttpServerTracer; import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java similarity index 95% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java index 2b3d6f445a31..9ee89066b58d 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/async/AsyncContextInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.async; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java similarity index 50% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java index 2efc48a333df..8b469c05b4fe 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherAdviceHelper.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java @@ -3,24 +3,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; - -import static io.opentelemetry.instrumentation.api.tracer.HttpServerTracer.CONTEXT_ATTRIBUTE; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.instrumentation.servlet.ServletAccessor; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; public class RequestDispatcherAdviceHelper { - public static Context getStartParentContext( - ServletAccessor accessor, REQUEST request) { - Context parentContext = Java8BytecodeBridge.currentContext(); + public static Context getStartParentContext(Object servletContextObject) { + Context parentContext = Context.current(); - Object servletContextObject = accessor.getRequestAttribute(request, CONTEXT_ATTRIBUTE); Context servletContext = servletContextObject instanceof Context ? (Context) servletContextObject : null; @@ -47,28 +40,4 @@ public static Context getStartParentContext( return parent; } - - public static void stop( - BaseTracer tracer, - ServletAccessor accessor, - Object originalContext, - REQUEST request, - Context context, - Scope scope, - Throwable throwable) { - scope.close(); - - // restore the original servlet span - // since spanWithScope is non-null here, originalContext must have been set with the - // prior - // servlet span (as opposed to remaining unset) - // TODO review this logic. Seems like manual context management - accessor.setRequestAttribute(request, CONTEXT_ATTRIBUTE, originalContext); - - if (throwable != null) { - tracer.endExceptionally(context, throwable); - } else { - tracer.end(context); - } - } } diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java similarity index 96% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java index 73afefbdb1b7..143751a2b532 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/dispatcher/RequestDispatcherInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.dispatcher; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java similarity index 92% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java index a1e073e9ad42..f251b1e793f4 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseAdviceHelper.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.response; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java similarity index 95% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java index ed644f612fa7..dfa05fe17cfc 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/response/HttpServletResponseInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.response; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java similarity index 96% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java index 7aaf6f9a58b9..8bf7ece2531f 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/service/ServletAndFilterInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.service; +package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle b/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle index dbdb5ba32d16..3c4725956024 100644 --- a/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle +++ b/instrumentation/servlet/servlet-common/library/servlet-common-library.gradle @@ -1,8 +1,5 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" -// need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-common" - dependencies { implementation deps.slf4j } diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java index 313817c9ead0..5f943a2d766a 100644 --- a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletHttpServerTracer.java @@ -29,7 +29,7 @@ public abstract class ServletHttpServerTracer private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES = Config.get() - .getBooleanProperty("otel.instrumentation.grpc.experimental-span-attributes", false); + .getBooleanProperty("otel.instrumentation.servlet.experimental-span-attributes", false); private final ServletAccessor accessor; diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java deleted file mode 100644 index 04b74dfa129e..000000000000 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxCommonServletAccessor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.servlet.javax; - -import io.opentelemetry.instrumentation.servlet.javax.JavaxServletAccessor; -import javax.servlet.http.HttpServletRequest; - -public class JavaxCommonServletAccessor extends JavaxServletAccessor { - public static final JavaxCommonServletAccessor INSTANCE = new JavaxCommonServletAccessor(); - - private JavaxCommonServletAccessor() {} - - @Override - public Integer getRequestRemotePort(HttpServletRequest httpServletRequest) { - return null; - } - - @Override - public int getResponseStatus(Void unused) { - return 0; - } - - @Override - public boolean isResponseCommitted(Void unused) { - return false; - } -} diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java index 75813d45eec5..4e8d48c24c07 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java @@ -8,8 +8,8 @@ import static java.util.Collections.singletonMap; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java index 519fb10a34ee..84bcee8ff50f 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java @@ -10,12 +10,10 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.instrumentation.servlet.dispatcher.RequestDispatcherAdviceHelper; -import io.opentelemetry.javaagent.instrumentation.servlet.javax.JavaxCommonServletAccessor; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherAdviceHelper; import java.lang.reflect.Method; import javax.servlet.RequestDispatcher; import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import net.bytebuddy.asm.Advice; public class RequestDispatcherAdvice { @@ -31,7 +29,7 @@ public static void start( Context parent = RequestDispatcherAdviceHelper.getStartParentContext( - JavaxCommonServletAccessor.INSTANCE, (HttpServletRequest) request); + request.getAttribute(CONTEXT_ATTRIBUTE)); if (parent == null) { return; @@ -41,8 +39,7 @@ public static void start( context = tracer().startSpan(method); // save the original servlet span before overwriting the request attribute, so that it can - // be - // restored on method exit + // be restored on method exit originalContext = request.getAttribute(CONTEXT_ATTRIBUTE); // this tells the dispatched servlet to use the current span as the parent for its work @@ -59,13 +56,19 @@ public static void stop( @Advice.Local("otelScope") Scope scope, @Advice.Thrown Throwable throwable) { - RequestDispatcherAdviceHelper.stop( - tracer(), - JavaxCommonServletAccessor.INSTANCE, - originalContext, - (HttpServletRequest) request, - context, - scope, - throwable); + scope.close(); + + // restore the original servlet span + // since spanWithScope is non-null here, originalContext must have been set with the + // prior + // servlet span (as opposed to remaining unset) + // TODO review this logic. Seems like manual context management + request.setAttribute(CONTEXT_ATTRIBUTE, originalContext); + + if (throwable != null) { + tracer().endExceptionally(context, throwable); + } else { + tracer().end(context); + } } } diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java index eb72f3859d97..ce46378eb2c7 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-jakarta"; + return "io.opentelemetry.javaagent.servlet-5.0"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java index b17886abbc9b..3f3ec968380b 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java @@ -12,7 +12,7 @@ import io.opentelemetry.javaagent.instrumentation.api.CallDepth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.servlet.response.HttpServletResponseAdviceHelper; +import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseAdviceHelper; import java.lang.reflect.Method; import javax.servlet.http.HttpServletResponse; import net.bytebuddy.asm.Advice; diff --git a/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle b/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle index 2231bece13c1..77b014c400a3 100644 --- a/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle +++ b/instrumentation/servlet/servlet-javax-common/library/servlet-javax-common-library.gradle @@ -1,8 +1,5 @@ apply from: "$rootDir/gradle/instrumentation-library.gradle" -// need to override archivesBaseName set in instrumentation-library.gradle -archivesBaseName = "servlet-javax-common" - dependencies { implementation deps.slf4j diff --git a/settings.gradle b/settings.gradle index 8fa8efaffd35..6a11c4a0301e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -234,8 +234,8 @@ include ':instrumentation:servlet:servlet-2.2:library' include ':instrumentation:servlet:servlet-2.2:javaagent' include ':instrumentation:servlet:servlet-3.0:library' include ':instrumentation:servlet:servlet-3.0:javaagent' -include ':instrumentation:servlet:servlet-jakarta:library' -include ':instrumentation:servlet:servlet-jakarta:javaagent' +include ':instrumentation:servlet:servlet-5.0:library' +include ':instrumentation:servlet:servlet-5.0:javaagent' include ':instrumentation:spark-2.3:javaagent' include ':instrumentation:spring:spring-batch-3.0:javaagent' include ':instrumentation:spring:spring-core-2.0:javaagent' diff --git a/smoke-tests/matrix/build.gradle b/smoke-tests/matrix/build.gradle index 069dc917c64e..55ef63983bfb 100644 --- a/smoke-tests/matrix/build.gradle +++ b/smoke-tests/matrix/build.gradle @@ -2,22 +2,9 @@ import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage import com.bmuschko.gradle.docker.tasks.image.DockerPushImage plugins { - id "war" id "com.bmuschko.docker-remote-api" version "6.7.0" } -compileJava { - options.release.set(8) -} - -repositories { - mavenCentral() -} - -dependencies { - implementation("javax.servlet:javax.servlet-api:3.0.1") -} - def buildLinuxTestImagesTask = tasks.create("buildLinuxTestImages") { group = "build" description = "Builds all Linux Docker images for the test matrix" @@ -45,7 +32,7 @@ def linuxTargets = [ "jetty": [ [version: ["9.4.35"], vm: ["hotspot", "openj9"], jdk: ["8", "11", "15"]], [version: ["10.0.0"], vm: ["hotspot", "openj9"], jdk: ["11", "15"]], - [version: ["11.0.1"], vm: ["hotspot", "openj9"], jdk: ["11", "15"], war: "servlet-jakarta"] + [version: ["11.0.1"], vm: ["hotspot", "openj9"], jdk: ["11", "15"], war: "servlet-5.0"] ], "tomcat": [ [version: ["7.0.107"], vm: ["hotspot", "openj9"], jdk: ["8"]], @@ -102,7 +89,7 @@ createDockerTasks(buildWindowsTestImagesTask, windowsTargets, true) def configureImage(Task parentTask, server, dockerfile, version, vm, jdk, warProject, Map extraArgs, isWindows = false) { // Using separate build directory for different war files allows using the same app.war filename - def dockerWorkingDir = new File(project.buildDir, warProject != null ? "docker-$warProject" : "docker") + def dockerWorkingDir = new File(project.buildDir, "docker-$warProject") def dockerFileName = isWindows ? "${dockerfile}.windows.dockerfile" : "${dockerfile}.dockerfile" def platformSuffix = isWindows ? "-windows" : "" @@ -145,7 +132,7 @@ def createDockerTasks(Task parentTask, targets, isWindows) { matrices.forEach { entry -> def dockerfile = entry["dockerfile"]?.toString() ?: server def extraArgs = (entry["args"] ?: [:]) as Map - def warProject = entry["war"] + def warProject = entry["war"] ?: "servlet-3.0" entry.version.forEach { version -> entry.vm.forEach { vm -> diff --git a/smoke-tests/matrix/servlet-3.0/build.gradle b/smoke-tests/matrix/servlet-3.0/build.gradle new file mode 100644 index 000000000000..1ea70d97a29d --- /dev/null +++ b/smoke-tests/matrix/servlet-3.0/build.gradle @@ -0,0 +1,15 @@ +plugins { + id "war" +} + +compileJava { + options.release.set(8) +} + +repositories { + mavenCentral() +} + +dependencies { + implementation("javax.servlet:javax.servlet-api:3.0.1") +} diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java diff --git a/smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java b/smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java similarity index 100% rename from smoke-tests/matrix/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java rename to smoke-tests/matrix/servlet-3.0/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java diff --git a/smoke-tests/matrix/src/main/webapp/WEB-INF/web.xml b/smoke-tests/matrix/servlet-3.0/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from smoke-tests/matrix/src/main/webapp/WEB-INF/web.xml rename to smoke-tests/matrix/servlet-3.0/src/main/webapp/WEB-INF/web.xml diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt b/smoke-tests/matrix/servlet-3.0/src/main/webapp/hello.txt similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/webapp/hello.txt rename to smoke-tests/matrix/servlet-3.0/src/main/webapp/hello.txt diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp b/smoke-tests/matrix/servlet-3.0/src/main/webapp/test.jsp similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/webapp/test.jsp rename to smoke-tests/matrix/servlet-3.0/src/main/webapp/test.jsp diff --git a/smoke-tests/matrix/servlet-jakarta/build.gradle b/smoke-tests/matrix/servlet-5.0/build.gradle similarity index 90% rename from smoke-tests/matrix/servlet-jakarta/build.gradle rename to smoke-tests/matrix/servlet-5.0/build.gradle index 6e4f5ce86fa2..180d58505485 100644 --- a/smoke-tests/matrix/servlet-jakarta/build.gradle +++ b/smoke-tests/matrix/servlet-5.0/build.gradle @@ -7,7 +7,7 @@ compileJava { } repositories { - jcenter() + mavenCentral() } dependencies { diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/AsyncGreetingServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionRequestListener.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ExceptionServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/ForwardServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/GreetingServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/HeaderDumpingServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/IncludeServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java b/smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java rename to smoke-tests/matrix/servlet-5.0/src/main/java/io/opentelemetry/smoketest/matrix/JspServlet.java diff --git a/smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml b/smoke-tests/matrix/servlet-5.0/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from smoke-tests/matrix/servlet-jakarta/src/main/webapp/WEB-INF/web.xml rename to smoke-tests/matrix/servlet-5.0/src/main/webapp/WEB-INF/web.xml diff --git a/smoke-tests/matrix/src/main/webapp/hello.txt b/smoke-tests/matrix/servlet-5.0/src/main/webapp/hello.txt similarity index 100% rename from smoke-tests/matrix/src/main/webapp/hello.txt rename to smoke-tests/matrix/servlet-5.0/src/main/webapp/hello.txt diff --git a/smoke-tests/matrix/src/main/webapp/test.jsp b/smoke-tests/matrix/servlet-5.0/src/main/webapp/test.jsp similarity index 100% rename from smoke-tests/matrix/src/main/webapp/test.jsp rename to smoke-tests/matrix/servlet-5.0/src/main/webapp/test.jsp diff --git a/smoke-tests/matrix/settings.gradle b/smoke-tests/matrix/settings.gradle index a0a03aa1a8b9..655ace030ef7 100644 --- a/smoke-tests/matrix/settings.gradle +++ b/smoke-tests/matrix/settings.gradle @@ -1,3 +1,4 @@ rootProject.name = 'matrix' -include ':servlet-jakarta' +include ':servlet-3.0' +include ':servlet-5.0' From d619556b0f65ccc644edfda0bcad18ecd3a22eab Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Mon, 22 Mar 2021 07:45:14 +0200 Subject: [PATCH 07/11] Fixed files in wrong package. --- .../servlet/v5_0/{ => dispatcher}/RequestDispatcherAdvice.java | 0 .../servlet/v5_0/{ => dispatcher}/RequestDispatcherTracer.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/{ => dispatcher}/RequestDispatcherAdvice.java (100%) rename instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/{ => dispatcher}/RequestDispatcherTracer.java (100%) diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java similarity index 100% rename from instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherAdvice.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java similarity index 100% rename from instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/RequestDispatcherTracer.java rename to instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java From fa059925d4dd61201e6c4b4ee9a92809d0b68bd7 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Mon, 22 Mar 2021 09:36:55 +0200 Subject: [PATCH 08/11] Fixed mixed up instrumentation names. --- .../servlet/v5_0/dispatcher/RequestDispatcherTracer.java | 2 +- .../servlet/javax/dispatcher/RequestDispatcherTracer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java index a690df51d6f8..3fd93098e6d6 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherTracer.java @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-javax-common"; + return "io.opentelemetry.javaagent.servlet-5.0"; } public Context startSpan(Method method) { diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java index ce46378eb2c7..466a77b98061 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-5.0"; + return "io.opentelemetry.javaagent.servlet-javax"; } public Context startSpan(Method method) { From e8c0b347e7bf12a597d19ee90113050dd902028b Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Mon, 22 Mar 2021 09:38:05 +0200 Subject: [PATCH 09/11] Fixed incomplete instrumentation name. --- .../servlet/javax/dispatcher/RequestDispatcherTracer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java index 466a77b98061..ca1bfdaccdcb 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherTracer.java @@ -18,7 +18,7 @@ public static RequestDispatcherTracer tracer() { @Override protected String getInstrumentationName() { - return "io.opentelemetry.javaagent.servlet-javax"; + return "io.opentelemetry.javaagent.servlet-javax-common"; } public Context startSpan(Method method) { From a1aa031d08bbec82339fa9a51788061503790d79 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Mon, 22 Mar 2021 13:21:35 +0200 Subject: [PATCH 10/11] Addressed PR suggestions --- .../v2_2/Servlet2InstrumentationModule.java | 2 +- .../v3_0/Servlet3InstrumentationModule.java | 4 ++-- .../JakartaServletInstrumentationModule.java | 8 ++++---- .../dispatcher/RequestDispatcherAdvice.java | 1 + .../v5_0/response/ResponseSendAdvice.java | 4 ++-- .../async/AsyncContextInstrumentation.java | 2 +- .../RequestDispatcherAdviceHelper.java | 18 +++++++++++++----- .../RequestDispatcherInstrumentation.java | 2 +- .../HttpServletResponseAdviceHelper.java | 12 +++--------- .../HttpServletResponseInstrumentation.java | 2 +- .../ServletAndFilterInstrumentation.java | 2 +- .../servlet/ServletAccessor.java | 9 +++++++++ .../JavaxServletInstrumentationModule.java | 4 ++-- .../dispatcher/RequestDispatcherAdvice.java | 2 +- .../javax/response/ResponseSendAdvice.java | 5 ++--- .../instrumentation/api/CallDepth.java | 2 +- 16 files changed, 45 insertions(+), 34 deletions(-) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/async/AsyncContextInstrumentation.java (95%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/dispatcher/RequestDispatcherAdviceHelper.java (61%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/dispatcher/RequestDispatcherInstrumentation.java (96%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/response/HttpServletResponseAdviceHelper.java (62%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/response/HttpServletResponseInstrumentation.java (95%) rename instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/{v5_0 => common}/service/ServletAndFilterInstrumentation.java (96%) diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java index b331c96041a5..c2d7ce1cbf9a 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v2_2/Servlet2InstrumentationModule.java @@ -10,7 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java index 5add4d67e580..a9e01ca855fd 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v3_0/Servlet3InstrumentationModule.java @@ -8,8 +8,8 @@ import static java.util.Arrays.asList; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async.AsyncContextInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.List; diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java index 4c303b2a0dc6..c1f253403e8b 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/JakartaServletInstrumentationModule.java @@ -8,10 +8,10 @@ import static java.util.Collections.singletonMap; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async.AsyncContextInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service.ServletAndFilterInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.async.AsyncContextInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.service.ServletAndFilterInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java index a1aed03378d7..4fa22037ddac 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdvice.java @@ -10,6 +10,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherAdviceHelper; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.ServletRequest; import java.lang.reflect.Method; diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java index b448d4c3590d..427db0087e23 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/ResponseSendAdvice.java @@ -12,6 +12,7 @@ import io.opentelemetry.javaagent.instrumentation.api.CallDepth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseAdviceHelper; import jakarta.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import net.bytebuddy.asm.Advice; @@ -39,7 +40,6 @@ public static void stopSpan( @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope, @Advice.Local("otelCallDepth") CallDepth callDepth) { - HttpServletResponseAdviceHelper.stopSpan( - tracer(), HttpServletResponse.class, throwable, context, scope, callDepth); + HttpServletResponseAdviceHelper.stopSpan(tracer(), throwable, context, scope, callDepth); } } diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/async/AsyncContextInstrumentation.java similarity index 95% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/async/AsyncContextInstrumentation.java index 9ee89066b58d..0a7a99e5fd67 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/async/AsyncContextInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/async/AsyncContextInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.async; +package io.opentelemetry.javaagent.instrumentation.servlet.common.async; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherAdviceHelper.java similarity index 61% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherAdviceHelper.java index 8b469c05b4fe..8cf2aeba4c08 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherAdviceHelper.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherAdviceHelper.java @@ -3,29 +3,37 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; +package io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; -import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer; public class RequestDispatcherAdviceHelper { + /** + * Determines if the advice for {@link RequestDispatcherInstrumentation} should create a new span + * and provides the context in which that span should be created. + * + * @param servletContextObject Value of the {@link HttpServerTracer#CONTEXT_ATTRIBUTE} attribute + * of the servlet request. + * @return The context in which the advice should create the dispatcher span in. Returns + * null in case a new span should not be created. + */ public static Context getStartParentContext(Object servletContextObject) { Context parentContext = Context.current(); Context servletContext = servletContextObject instanceof Context ? (Context) servletContextObject : null; - Span parentSpan = Java8BytecodeBridge.spanFromContext(parentContext); + Span parentSpan = Span.fromContext(parentContext); SpanContext parentSpanContext = parentSpan.getSpanContext(); if (!parentSpanContext.isValid() && servletContext == null) { // Don't want to generate a new top-level span return null; } - Span servletSpan = - servletContext != null ? Java8BytecodeBridge.spanFromContext(servletContext) : null; + Span servletSpan = servletContext != null ? Span.fromContext(servletContext) : null; Context parent; if (servletContext == null || (parentSpanContext.isValid() diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherInstrumentation.java similarity index 96% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherInstrumentation.java index 143751a2b532..cdb882265299 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/dispatcher/RequestDispatcherInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/dispatcher/RequestDispatcherInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher; +package io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseAdviceHelper.java similarity index 62% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseAdviceHelper.java index f251b1e793f4..20eef8935a1e 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseAdviceHelper.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseAdviceHelper.java @@ -3,24 +3,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; +package io.opentelemetry.javaagent.instrumentation.servlet.common.response; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; import io.opentelemetry.javaagent.instrumentation.api.CallDepth; -import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; public class HttpServletResponseAdviceHelper { public static void stopSpan( - BaseTracer tracer, - Class responseClass, - Throwable throwable, - Context context, - Scope scope, - CallDepth callDepth) { + BaseTracer tracer, Throwable throwable, Context context, Scope scope, CallDepth callDepth) { if (callDepth.decrementAndGet() == 0 && context != null) { - CallDepthThreadLocalMap.reset(responseClass); + callDepth.reset(); scope.close(); diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseInstrumentation.java similarity index 95% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseInstrumentation.java index dfa05fe17cfc..b28cb3304f31 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/response/HttpServletResponseInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/response/HttpServletResponseInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response; +package io.opentelemetry.javaagent.instrumentation.servlet.common.response; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/service/ServletAndFilterInstrumentation.java similarity index 96% rename from instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java rename to instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/service/ServletAndFilterInstrumentation.java index 8bf7ece2531f..431629b368fd 100644 --- a/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/v5_0/service/ServletAndFilterInstrumentation.java +++ b/instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/common/service/ServletAndFilterInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.servlet.v5_0.service; +package io.opentelemetry.javaagent.instrumentation.servlet.common.service; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType; import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; diff --git a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java index b5e67aa2e07c..cfb061342d8a 100644 --- a/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java +++ b/instrumentation/servlet/servlet-common/library/src/main/java/io/opentelemetry/instrumentation/servlet/ServletAccessor.java @@ -7,6 +7,15 @@ import java.security.Principal; +/** + * This interface is used to access methods of HttpServletRequest and HttpServletResponse classes in + * shared code that is used for both jakarta.servlet and javax.servlet versions of those classes. A + * wrapper class with extra information attached may be used as well in cases where the class itself + * does not provide some field (such as response status for Servlet API 2.2). + * + * @param HttpServletRequest class (or a wrapper) + * @param HttpServletResponse class (or a wrapper) + */ public interface ServletAccessor { String getRequestContextPath(RequestT request); diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java index 4e8d48c24c07..9f5355b689aa 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/JavaxServletInstrumentationModule.java @@ -8,8 +8,8 @@ import static java.util.Collections.singletonMap; import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherInstrumentation; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherInstrumentation; +import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseInstrumentation; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Arrays; diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java index 84bcee8ff50f..0fc36155e970 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/dispatcher/RequestDispatcherAdvice.java @@ -10,7 +10,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.dispatcher.RequestDispatcherAdviceHelper; +import io.opentelemetry.javaagent.instrumentation.servlet.common.dispatcher.RequestDispatcherAdviceHelper; import java.lang.reflect.Method; import javax.servlet.RequestDispatcher; import javax.servlet.ServletRequest; diff --git a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java index 3f3ec968380b..18ab3b050849 100644 --- a/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java +++ b/instrumentation/servlet/servlet-javax-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/javax/response/ResponseSendAdvice.java @@ -12,7 +12,7 @@ import io.opentelemetry.javaagent.instrumentation.api.CallDepth; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.servlet.v5_0.response.HttpServletResponseAdviceHelper; +import io.opentelemetry.javaagent.instrumentation.servlet.common.response.HttpServletResponseAdviceHelper; import java.lang.reflect.Method; import javax.servlet.http.HttpServletResponse; import net.bytebuddy.asm.Advice; @@ -40,7 +40,6 @@ public static void stopSpan( @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope, @Advice.Local("otelCallDepth") CallDepth callDepth) { - HttpServletResponseAdviceHelper.stopSpan( - tracer(), HttpServletResponse.class, throwable, context, scope, callDepth); + HttpServletResponseAdviceHelper.stopSpan(tracer(), throwable, context, scope, callDepth); } } diff --git a/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/CallDepth.java b/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/CallDepth.java index b03a6626ef75..999a87f76bf9 100644 --- a/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/CallDepth.java +++ b/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/CallDepth.java @@ -28,7 +28,7 @@ public int get() { return depth; } - void reset() { + public void reset() { depth = 0; } } From 0bab7bad17a6b766fa8fea0cbab6ed157badba45 Mon Sep 17 00:00:00 2001 From: Ago Allikmaa Date: Tue, 23 Mar 2021 11:52:31 +0200 Subject: [PATCH 11/11] Addressed PR suggestions --- .../servlet/v3_0/Servlet3HttpServerTracer.java | 13 ++++++------- .../javaagent/servlet-5.0-javaagent.gradle | 1 + .../v5_0/JakartaServletHttpServerTracer.java | 13 ++++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java index f17b9c6c13da..20dd96b20cbb 100644 --- a/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java +++ b/instrumentation/servlet/servlet-3.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/v3_0/Servlet3HttpServerTracer.java @@ -31,7 +31,7 @@ public static Servlet3HttpServerTracer tracer() { } public Context startSpan(Object servletOrFilter, HttpServletRequest request) { - Context context = startSpan(request, getSpanName(servletOrFilter, request, false)); + Context context = startSpan(request, getSpanName(servletOrFilter, request)); // server span name shouldn't be update when server span was created from a call to Servlet // if server span was created from a call to Filter then name may be updated from updateContext. if (servletOrFilter instanceof Servlet) { @@ -40,10 +40,9 @@ public Context startSpan(Object servletOrFilter, HttpServletRequest request) { return context; } - private String getSpanName( - Object servletOrFilter, HttpServletRequest request, boolean allowNull) { - String spanName = getSpanName(servletOrFilter, request); - if (spanName == null && !allowNull) { + private String getSpanName(Object servletOrFilter, HttpServletRequest request) { + String spanName = getSpanNameFromPath(servletOrFilter, request); + if (spanName == null) { String contextPath = request.getContextPath(); if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { return "HTTP " + request.getMethod(); @@ -53,7 +52,7 @@ private String getSpanName( return spanName; } - private static String getSpanName(Object servletOrFilter, HttpServletRequest request) { + private static String getSpanNameFromPath(Object servletOrFilter, HttpServletRequest request) { // we are only interested in Servlets if (!(servletOrFilter instanceof Servlet)) { return null; @@ -119,7 +118,7 @@ public Context updateContext( Context context, Object servletOrFilter, HttpServletRequest request) { Span span = ServerSpan.fromContextOrNull(context); if (span != null && ServletSpanNaming.shouldUpdateServerSpanName(context)) { - String spanName = getSpanName(servletOrFilter, request, true); + String spanName = getSpanNameFromPath(servletOrFilter, request); if (spanName != null) { span.updateName(spanName); ServletSpanNaming.setServletUpdatedServerSpanName(context); diff --git a/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle b/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle index 992eabaa805e..e7c2ee8c1b5e 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle +++ b/instrumentation/servlet/servlet-5.0/javaagent/servlet-5.0-javaagent.gradle @@ -5,6 +5,7 @@ muzzle { group = "jakarta.servlet" module = 'jakarta.servlet-api' versions = "[5.0.0,)" + assertInverse = true } } diff --git a/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java index 457f48037d2e..012075f2ded8 100644 --- a/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java +++ b/instrumentation/servlet/servlet-5.0/library/src/main/java/io/opentelemetry/instrumentation/servlet/jakarta/v5_0/JakartaServletHttpServerTracer.java @@ -33,7 +33,7 @@ public static JakartaServletHttpServerTracer tracer() { } public Context startSpan(Object servletOrFilter, HttpServletRequest request) { - Context context = startSpan(request, getSpanName(servletOrFilter, request, false)); + Context context = startSpan(request, getSpanName(servletOrFilter, request)); // server span name shouldn't be update when server span was created from a call to Servlet // if server span was created from a call to Filter then name may be updated from updateContext. if (servletOrFilter instanceof Servlet) { @@ -42,10 +42,9 @@ public Context startSpan(Object servletOrFilter, HttpServletRequest request) { return context; } - private String getSpanName( - Object servletOrFilter, HttpServletRequest request, boolean allowNull) { - String spanName = getSpanName(servletOrFilter, request); - if (spanName == null && !allowNull) { + private String getSpanName(Object servletOrFilter, HttpServletRequest request) { + String spanName = getSpanNameFromPath(servletOrFilter, request); + if (spanName == null) { String contextPath = request.getContextPath(); if (contextPath == null || contextPath.isEmpty() || contextPath.equals("/")) { return "HTTP " + request.getMethod(); @@ -55,7 +54,7 @@ private String getSpanName( return spanName; } - private static String getSpanName(Object servletOrFilter, HttpServletRequest request) { + private static String getSpanNameFromPath(Object servletOrFilter, HttpServletRequest request) { // we are only interested in Servlets if (!(servletOrFilter instanceof Servlet)) { return null; @@ -121,7 +120,7 @@ public Context updateContext( Context context, Object servletOrFilter, HttpServletRequest request) { Span span = ServerSpan.fromContextOrNull(context); if (span != null && ServletSpanNaming.shouldUpdateServerSpanName(context)) { - String spanName = getSpanName(servletOrFilter, request, true); + String spanName = getSpanNameFromPath(servletOrFilter, request); if (spanName != null) { span.updateName(spanName); ServletSpanNaming.setServletUpdatedServerSpanName(context);