diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/ServletInstrumentation.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/ServletInstrumentation.java index 6e9877d6347..103ff1acd50 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/ServletInstrumentation.java +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/ServletInstrumentation.java @@ -18,6 +18,7 @@ import io.undertow.server.HttpServerExchange; import io.undertow.servlet.handlers.ServletPathMatch; import io.undertow.servlet.handlers.ServletRequestContext; +import javax.servlet.DispatcherType; import javax.servlet.ServletRequest; import javax.servlet.http.MappingMatch; import net.bytebuddy.asm.Advice; @@ -64,7 +65,8 @@ public static class DispatchAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void enter( @Advice.Argument(0) final HttpServerExchange exchange, - @Advice.Argument(1) final ServletRequestContext servletRequestContext) { + @Advice.Argument(1) final ServletRequestContext servletRequestContext, + @Advice.Argument(3) final DispatcherType dispatcherType) { ContextContinuation continuation = exchange.getAttachment(DATADOG_UNDERTOW_CONTINUATION); if (continuation != null) { AgentSpan undertowSpan = spanFromContext(continuation.context()); @@ -73,21 +75,27 @@ public static void enter( undertowSpan.setSpanName(SERVLET_REQUEST); undertowSpan.setTag(SERVLET_CONTEXT, request.getServletContext().getContextPath()); - String relativePath = exchange.getRelativePath(); + // Forward, include, error and async dispatches happen inside the original request, so they + // must not rename it: the root span keeps describing what the client asked for. + if (dispatcherType == DispatcherType.REQUEST + || UndertowDecorator.UNDERTOW_DISPATCH_RENAME_RESOURCE) { + String relativePath = exchange.getRelativePath(); - ServletPathMatch servletPathMatch = servletRequestContext.getServletPathMatch(); - if (UndertowDecorator.UNDERTOW_LEGACY_TRACING - && servletPathMatch != null - && servletPathMatch.getMappingMatch() != MappingMatch.DEFAULT) { - // Set the route unless the mapping match is default, this way we prevent setting route - // for a non-existing resource. Otherwise, it'd set a non-existing resource name with - // higher priority than 404 resource, so it wouldn't be able to set resource 404 later in - // the onResponse instrumentation. - HTTP_RESOURCE_DECORATOR.withRoute( - undertowSpan, exchange.getRequestMethod().toString(), relativePath, false); + ServletPathMatch servletPathMatch = servletRequestContext.getServletPathMatch(); + if (UndertowDecorator.UNDERTOW_LEGACY_TRACING + && servletPathMatch != null + && servletPathMatch.getMappingMatch() != MappingMatch.DEFAULT) { + // Set the route unless the mapping match is default, this way we prevent setting route + // for a non-existing resource. Otherwise, it'd set a non-existing resource name with + // higher priority than 404 resource, so it wouldn't be able to set resource 404 later + // in + // the onResponse instrumentation. + HTTP_RESOURCE_DECORATOR.withRoute( + undertowSpan, exchange.getRequestMethod().toString(), relativePath, false); + } + // The servlet.path tag is expected even for a non-existing resource. + undertowSpan.setTag(SERVLET_PATH, relativePath); } - // The servlet.path tag is expected even for a non-existing resource. - undertowSpan.setTag(SERVLET_PATH, relativePath); } } } diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/groovy/UndertowServletTest.groovy b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/groovy/UndertowServletTest.groovy index 54b39c886c0..c1037796653 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/groovy/UndertowServletTest.groovy +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/groovy/UndertowServletTest.groovy @@ -5,6 +5,8 @@ import datadog.trace.agent.test.naming.TestingGenericHttpNamingConventions import datadog.trace.bootstrap.blocking.BlockingActionHelper import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.core.DDSpan +import datadog.trace.instrumentation.undertow.ForwardingServlet +import datadog.trace.instrumentation.undertow.IncludingServlet import io.undertow.Handlers import io.undertow.Undertow import io.undertow.UndertowOptions @@ -14,6 +16,7 @@ import io.undertow.servlet.api.ServletContainer import io.undertow.servlet.api.ServletInfo import io.undertow.websockets.jsr.WebSocketDeploymentInfo import okhttp3.MediaType +import okhttp3.Request import okhttp3.RequestBody import spock.lang.IgnoreIf @@ -45,6 +48,8 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.WEBSOC abstract class UndertowServletTest extends HttpServerTest { private static final CONTEXT = "ctx" + private static final String FORWARDING_PATH = "/dispatch/forward" + private static final String INCLUDING_PATH = "/dispatch/include" private final static String MULTIPART_CONTENT_TYPE = 'multipart/form-data; charset=utf-8; boundary=------------------------943d3207457896a3' @@ -70,6 +75,8 @@ abstract class UndertowServletTest extends HttpServerTest { .setDeploymentName("servletContext.war") .addServlet(new ServletInfo("SuccessServlet", SuccessServlet).addMapping(SUCCESS.getPath())) .addServlet(new ServletInfo("ForwardedServlet", ForwardedServlet).addMapping(FORWARDED.getPath())) + .addServlet(new ServletInfo("ForwardingServlet", ForwardingServlet).addMapping(FORWARDING_PATH)) + .addServlet(new ServletInfo("IncludingServlet", IncludingServlet).addMapping(INCLUDING_PATH)) .addServlet(new ServletInfo("QueryEncodedBothServlet", QueryEncodedBothServlet).addMapping(QUERY_ENCODED_BOTH.getPath())) .addServlet(new ServletInfo("QueryEncodedServlet", QueryEncodedServlet).addMapping(QUERY_ENCODED_QUERY.getPath())) .addServlet(new ServletInfo("QueryParamServlet", QueryServlet).addMapping(QUERY_PARAM.getPath())) @@ -290,6 +297,10 @@ abstract class UndertowServletTest extends HttpServerTest { true } + def dispatchRenamesResource() { + false + } + @Override Serializable expectedServerSpanRoute(ServerEndpoint endpoint) { if (!generateHttpRoute()) { @@ -331,6 +342,36 @@ abstract class UndertowServletTest extends HttpServerTest { body = null } + def "internal #dispatch keeps the original request's resource and servlet path"() { + setup: + def request = new Request.Builder().url(address.resolve(path.substring(1)).toURL()).get().build() + + when: + def response = client.newCall(request).execute() + + then: + response.code() == SUCCESS.status + response.body().string() == SUCCESS.body + + when: + TEST_WRITER.waitForTraces(1) + DDSpan serverSpan = TEST_WRITER.flatten().find { + it.parentId == 0 + } + + then: + // with the opt-out, a forward renames the request to its target; an include leaves the path alone + def namedPath = dispatchRenamesResource() && dispatch == "forward" ? SUCCESS.path : path + serverSpan.resourceName.toString() == (generateHttpRoute() ? "GET $namedPath" : "GET /$CONTEXT$path") + serverSpan.tags["servlet.path"] == namedPath + serverSpan.tags[Tags.HTTP_ROUTE] == (generateHttpRoute() ? namedPath : null) + + where: + dispatch | path + "forward" | FORWARDING_PATH + "include" | INCLUDING_PATH + } + // Pins the block-telemetry-3 wiring added to FormDataParserInstrumentation (urlencoded body, // DoParseAdvice.after) and MultiPartUploadHandlerInstrumentation (multipart body, // ParseBlockingAdvice.after): both now check the boolean returned by @@ -422,3 +463,16 @@ class UndertowServletNoHttpRouteForkedTest extends UndertowServletTest implement class UndertowServletV1ForkedTest extends UndertowServletTest implements TestingGenericHttpNamingConventions.ServerV1 { } + +class UndertowServletDispatchRenameForkedTest extends UndertowServletTest implements TestingGenericHttpNamingConventions.ServerV0 { + @Override + def dispatchRenamesResource() { + true + } + + @Override + protected void configurePreAgent() { + super.configurePreAgent() + injectSysConfig("trace.undertow.dispatch.rename-resource", "true") + } +} diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java new file mode 100644 index 00000000000..67f8a625bb5 --- /dev/null +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java @@ -0,0 +1,18 @@ +package datadog.trace.instrumentation.undertow; + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Forwards to the success servlet through an internal {@code RequestDispatcher}. */ +public class ForwardingServlet extends HttpServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher(SUCCESS.getPath()).forward(req, resp); + } +} diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java new file mode 100644 index 00000000000..2c8ffb4dfd6 --- /dev/null +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java @@ -0,0 +1,18 @@ +package datadog.trace.instrumentation.undertow; + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Includes to the success servlet through an internal {@code RequestDispatcher}. */ +public class IncludingServlet extends HttpServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher(SUCCESS.getPath()).include(req, resp); + } +} diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/main/java/datadog/trace/instrumentation/undertow/JakartaServletInstrumentation.java b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/main/java/datadog/trace/instrumentation/undertow/JakartaServletInstrumentation.java index e429c961a11..d77f50c125e 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/main/java/datadog/trace/instrumentation/undertow/JakartaServletInstrumentation.java +++ b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/main/java/datadog/trace/instrumentation/undertow/JakartaServletInstrumentation.java @@ -16,6 +16,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import io.undertow.server.HttpServerExchange; import io.undertow.servlet.handlers.ServletRequestContext; +import jakarta.servlet.DispatcherType; import jakarta.servlet.ServletRequest; import net.bytebuddy.asm.Advice; @@ -56,7 +57,8 @@ public static class DispatchAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void enter( @Advice.Argument(0) final HttpServerExchange exchange, - @Advice.Argument(1) final ServletRequestContext servletRequestContext) { + @Advice.Argument(1) final ServletRequestContext servletRequestContext, + @Advice.Argument(3) final DispatcherType dispatcherType) { ContextContinuation continuation = exchange.getAttachment(DATADOG_UNDERTOW_CONTINUATION); if (continuation != null) { AgentSpan undertowSpan = spanFromContext(continuation.context()); @@ -65,7 +67,12 @@ public static void enter( undertowSpan.setSpanName(SERVLET_REQUEST); undertowSpan.setTag(SERVLET_CONTEXT, request.getServletContext().getContextPath()); - undertowSpan.setTag(SERVLET_PATH, exchange.getRelativePath()); + // Forward, include, error and async dispatches happen inside the original request, so they + // must not overwrite the original servlet path. + if (dispatcherType == DispatcherType.REQUEST + || UndertowDecorator.UNDERTOW_DISPATCH_RENAME_RESOURCE) { + undertowSpan.setTag(SERVLET_PATH, exchange.getRelativePath()); + } } } } diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/groovy/UndertowServletTest.groovy b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/groovy/UndertowServletTest.groovy index 4287b8a8ebe..ae58883b2ba 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/groovy/UndertowServletTest.groovy +++ b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/groovy/UndertowServletTest.groovy @@ -1,6 +1,9 @@ import datadog.trace.agent.test.asserts.TraceAssert import datadog.trace.agent.test.base.HttpServerTest import datadog.trace.agent.test.base.WebsocketServer +import datadog.trace.core.DDSpan +import datadog.trace.instrumentation.undertow.ForwardingServlet +import datadog.trace.instrumentation.undertow.IncludingServlet import io.undertow.Handlers import io.undertow.Undertow import io.undertow.UndertowOptions @@ -10,6 +13,7 @@ import io.undertow.servlet.api.ServletContainer import io.undertow.servlet.api.ServletInfo import io.undertow.websockets.jsr.WebSocketDeploymentInfo import jakarta.servlet.MultipartConfigElement +import okhttp3.Request import java.nio.ByteBuffer @@ -30,6 +34,8 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.USER_B class UndertowServletTest extends HttpServerTest { private static final CONTEXT = "ctx" + private static final String FORWARDING_PATH = "/dispatch/forward" + private static final String INCLUDING_PATH = "/dispatch/include" class UndertowServer implements WebsocketServer { def port = 0 @@ -46,6 +52,8 @@ class UndertowServletTest extends HttpServerTest { .setDeploymentName("servletContext.war") .addServlet(new ServletInfo("SuccessServlet", SuccessServlet).addMapping(SUCCESS.getPath())) .addServlet(new ServletInfo("ForwardedServlet", ForwardedServlet).addMapping(FORWARDED.getPath())) + .addServlet(new ServletInfo("ForwardingServlet", ForwardingServlet).addMapping(FORWARDING_PATH)) + .addServlet(new ServletInfo("IncludingServlet", IncludingServlet).addMapping(INCLUDING_PATH)) .addServlet(new ServletInfo("QueryEncodedBothServlet", QueryEncodedBothServlet).addMapping(QUERY_ENCODED_BOTH.getPath())) .addServlet(new ServletInfo("QueryEncodedServlet", QueryEncodedServlet).addMapping(QUERY_ENCODED_QUERY.getPath())) .addServlet(new ServletInfo("QueryParamServlet", QueryServlet).addMapping(QUERY_PARAM.getPath())) @@ -246,4 +254,49 @@ class UndertowServletTest extends HttpServerTest { throw new UnsupportedOperationException("responseSpan not implemented for " + endpoint) } } + + def dispatchRenamesResource() { + false + } + + def "internal #dispatch keeps the original request's resource and servlet path"() { + setup: + def request = new Request.Builder().url(address.resolve(path.substring(1)).toURL()).get().build() + + when: + def response = client.newCall(request).execute() + + then: + response.code() == SUCCESS.status + response.body().string() == SUCCESS.body + + when: + TEST_WRITER.waitForTraces(1) + DDSpan serverSpan = TEST_WRITER.flatten().find { + it.parentId == 0 + } + + then: + // with the opt-out, a forward overwrites servlet.path with its target; an include leaves it alone + serverSpan.resourceName.toString() == "GET /$CONTEXT$path" + serverSpan.tags["servlet.path"] == (dispatchRenamesResource() && dispatch == "forward" ? SUCCESS.path : path) + + where: + dispatch | path + "forward" | FORWARDING_PATH + "include" | INCLUDING_PATH + } +} + +class UndertowServletDispatchRenameForkedTest extends UndertowServletTest { + @Override + def dispatchRenamesResource() { + true + } + + @Override + protected void configurePreAgent() { + super.configurePreAgent() + injectSysConfig("trace.undertow.dispatch.rename-resource", "true") + } } diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java new file mode 100644 index 00000000000..5632058057a --- /dev/null +++ b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/ForwardingServlet.java @@ -0,0 +1,18 @@ +package datadog.trace.instrumentation.undertow; + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** Forwards to the success servlet through an internal {@code RequestDispatcher}. */ +public class ForwardingServlet extends HttpServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher(SUCCESS.getPath()).forward(req, resp); + } +} diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java new file mode 100644 index 00000000000..7d6d09c5938 --- /dev/null +++ b/dd-java-agent/instrumentation/undertow/undertow-2.2/src/test/java/datadog/trace/instrumentation/undertow/IncludingServlet.java @@ -0,0 +1,18 @@ +package datadog.trace.instrumentation.undertow; + +import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** Includes to the success servlet through an internal {@code RequestDispatcher}. */ +public class IncludingServlet extends HttpServlet { + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) + throws ServletException, IOException { + req.getRequestDispatcher(SUCCESS.getPath()).include(req, resp); + } +} diff --git a/dd-java-agent/instrumentation/undertow/undertow-common/src/main/java/datadog/trace/instrumentation/undertow/UndertowDecorator.java b/dd-java-agent/instrumentation/undertow/undertow-common/src/main/java/datadog/trace/instrumentation/undertow/UndertowDecorator.java index e55f76a59c2..d85f55c6343 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-common/src/main/java/datadog/trace/instrumentation/undertow/UndertowDecorator.java +++ b/dd-java-agent/instrumentation/undertow/undertow-common/src/main/java/datadog/trace/instrumentation/undertow/UndertowDecorator.java @@ -43,6 +43,8 @@ public class UndertowDecorator UTF8BytesString.create(DECORATE.operationName()); public static final boolean UNDERTOW_LEGACY_TRACING = Config.get().isLegacyTracingEnabled(true, "undertow"); + public static final boolean UNDERTOW_DISPATCH_RENAME_RESOURCE = + Config.get().isUndertowDispatchRenameResource(); @Override protected String[] instrumentationNames() { diff --git a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java index 0035fcc32e3..cc8aa0d2de7 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java @@ -99,6 +99,8 @@ public final class ConfigDefaults { static final boolean DEFAULT_CLIENT_IP_ENABLED = false; + static final boolean DEFAULT_UNDERTOW_DISPATCH_RENAME_RESOURCE = false; + static final int DEFAULT_CLOCK_SYNC_PERIOD = 30; // seconds static final boolean DEFAULT_TRACE_LAMBDA_SNAPSTART_CLOCK_RESYNC_ENABLED = false; diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java index 137e9805519..6076ff33452 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java @@ -154,6 +154,13 @@ public final class TraceInstrumentationConfig { public static final String SERVLET_PRINCIPAL_ENABLED = "trace.servlet.principal.enabled"; public static final String SERVLET_ASYNC_TIMEOUT_ERROR = "trace.servlet.async-timeout.error"; + /** + * Restores the old Undertow behavior of renaming the request (resource, route and servlet.path) + * to the target of an internal forward, include, error or async dispatch. + */ + public static final String UNDERTOW_DISPATCH_RENAME_RESOURCE = + "trace.undertow.dispatch.rename-resource"; + public static final String SERVLET_ROOT_CONTEXT_SERVICE_NAME = "trace.servlet.root-context.service.name"; diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index ee09c1e9e2f..c197db955c4 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -197,6 +197,7 @@ import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_RESOLVER_ENABLED; import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_STATS_INTERVAL; import static datadog.trace.api.ConfigDefaults.DEFAULT_TRACE_X_DATADOG_TAGS_MAX_LENGTH; +import static datadog.trace.api.ConfigDefaults.DEFAULT_UNDERTOW_DISPATCH_RENAME_RESOURCE; import static datadog.trace.api.ConfigDefaults.DEFAULT_WEBSOCKET_MESSAGES_INHERIT_SAMPLING; import static datadog.trace.api.ConfigDefaults.DEFAULT_WEBSOCKET_MESSAGES_SEPARATE_TRACES; import static datadog.trace.api.ConfigDefaults.DEFAULT_WEBSOCKET_TAG_SESSION_ID; @@ -652,6 +653,7 @@ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING; import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES; import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_TAG_SESSION_ID; +import static datadog.trace.api.config.TraceInstrumentationConfig.UNDERTOW_DISPATCH_RENAME_RESOURCE; import static datadog.trace.api.config.TracerConfig.AGENT_HOST; import static datadog.trace.api.config.TracerConfig.AGENT_NAMED_PIPE; import static datadog.trace.api.config.TracerConfig.AGENT_PORT_LEGACY; @@ -1340,6 +1342,7 @@ public static String getHostName() { private final boolean servletPrincipalEnabled; private final boolean servletAsyncTimeoutError; + private final boolean undertowDispatchRenameResource; private final boolean springDataRepositoryInterfaceResourceName; @@ -3213,6 +3216,9 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment()) TRACE_X_DATADOG_TAGS_MAX_LENGTH, DEFAULT_TRACE_X_DATADOG_TAGS_MAX_LENGTH); servletAsyncTimeoutError = configProvider.getBoolean(SERVLET_ASYNC_TIMEOUT_ERROR, true); + undertowDispatchRenameResource = + configProvider.getBoolean( + UNDERTOW_DISPATCH_RENAME_RESOURCE, DEFAULT_UNDERTOW_DISPATCH_RENAME_RESOURCE); logLevel = configProvider.getString(TRACE_LOG_LEVEL, null, LOG_LEVEL); debugEnabled = configProvider.getBoolean(TRACE_DEBUG, false); @@ -5222,6 +5228,10 @@ public boolean isServletAsyncTimeoutError() { return servletAsyncTimeoutError; } + public boolean isUndertowDispatchRenameResource() { + return undertowDispatchRenameResource; + } + public ProtocolVersion getProtocolVersion() { return protocolVersion; } @@ -7001,6 +7011,8 @@ public String toString() { + servletPrincipalEnabled + ", servletAsyncTimeoutError=" + servletAsyncTimeoutError + + ", undertowDispatchRenameResource=" + + undertowDispatchRenameResource + ", datadogTagsLimit=" + xDatadogTagsMaxLength + ", traceAgentProtocolVersion=" diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 4b6663c7fe0..c72d475762f 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -11452,6 +11452,14 @@ "aliases": ["DD_TRACE_INTEGRATION_UNDERTOW_2_2_ENABLED", "DD_INTEGRATION_UNDERTOW_2_2_ENABLED"] } ], + "DD_TRACE_UNDERTOW_DISPATCH_RENAME_RESOURCE": [ + { + "version": "A", + "type": "boolean", + "default": "false", + "aliases": [] + } + ], "DD_TRACE_UNDERTOW_ENABLED": [ { "version": "A",