diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/server/ServerSpanNaming.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/server/ServerSpanNaming.java index 4f1204fb210b..16658016d55e 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/server/ServerSpanNaming.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/server/ServerSpanNaming.java @@ -9,13 +9,15 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextKey; import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import javax.annotation.Nullable; +// TODO: move to ...instrumenter.http and rename to HttpRouteHolder (?) /** Helper container for tracking whether instrumentation should update server span name or not. */ public final class ServerSpanNaming { private static final ContextKey CONTEXT_KEY = - ContextKey.named("opentelemetry-servlet-span-naming-key"); + ContextKey.named("opentelemetry-http-server-route-key"); public static ContextCustomizer get() { return (context, request, startAttributes) -> { @@ -27,9 +29,7 @@ public static ContextCustomizer get() { } private volatile Source updatedBySource; - // Length of the currently set name. This is used when setting name from a servlet filter - // to pick the most descriptive (longest) name. - private volatile int nameLength; + @Nullable private volatile String route; private ServerSpanNaming(Source initialSource) { this.updatedBySource = initialSource; @@ -78,7 +78,7 @@ public static void updateServerSpanName( if (serverSpanNaming == null) { String name = serverSpanName.get(context, arg1, arg2); if (name != null && !name.isEmpty()) { - serverSpan.updateName(name); + updateSpanData(serverSpan, name); } return; } @@ -91,15 +91,33 @@ public static void updateServerSpanName( if (name != null && !name.isEmpty() && (!onlyIfBetterName || serverSpanNaming.isBetterName(name))) { - serverSpan.updateName(name); + updateSpanData(serverSpan, name); serverSpanNaming.updatedBySource = source; - serverSpanNaming.nameLength = name.length(); + serverSpanNaming.route = name; } } } + // TODO: instead of calling setAttribute() consider storing the route in context end retrieving it + // in the AttributesExtractor + private static void updateSpanData(Span serverSpan, String route) { + serverSpan.updateName(route); + serverSpan.setAttribute(SemanticAttributes.HTTP_ROUTE, route); + } + + // This is used when setting name from a servlet filter to pick the most descriptive (longest) + // route. private boolean isBetterName(String name) { - return name.length() > nameLength; + String route = this.route; + int routeLength = route == null ? 0 : route.length(); + return name.length() > routeLength; + } + + // TODO: use that in HttpServerMetrics + @Nullable + public static String getRoute(Context context) { + ServerSpanNaming serverSpanNaming = context.get(CONTEXT_KEY); + return serverSpanNaming == null ? null : serverSpanNaming.route; } public enum Source { diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/test/groovy/AkkaHttpServerInstrumentationTest.groovy b/instrumentation/akka/akka-http-10.0/javaagent/src/test/groovy/AkkaHttpServerInstrumentationTest.groovy index 8c822910573f..43c8e45b03b2 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/test/groovy/AkkaHttpServerInstrumentationTest.groovy +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/test/groovy/AkkaHttpServerInstrumentationTest.groovy @@ -3,8 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest implements AgentTestTrait { @@ -28,6 +30,13 @@ abstract class AkkaHttpServerInstrumentationTest extends HttpServerTest boolean testCapturedHttpHeaders() { false } + + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } } class AkkaHttpServerInstrumentationTestSync extends AkkaHttpServerInstrumentationTest { diff --git a/instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/decorators/HttpSpanDecorator.java b/instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/decorators/HttpSpanDecorator.java index c047388eb007..5e36238cc572 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/decorators/HttpSpanDecorator.java +++ b/instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/decorators/HttpSpanDecorator.java @@ -121,6 +121,7 @@ private static boolean shouldUpdateServerSpanName( private void updateServerSpanName(Span serverSpan, Exchange exchange, Endpoint endpoint) { String path = getPath(exchange, endpoint); if (path != null) { + // TODO should update SERVER span name/route using ServerSpanNaming serverSpan.updateName(path); } } diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy index c75f4b96fd4f..75b8f2f35fca 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/RestCamelTest.groovy @@ -5,8 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP - import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait import io.opentelemetry.instrumentation.test.utils.PortUtils @@ -20,6 +18,7 @@ import spock.lang.Shared import static io.opentelemetry.api.trace.SpanKind.CLIENT import static io.opentelemetry.api.trace.SpanKind.INTERNAL import static io.opentelemetry.api.trace.SpanKind.SERVER +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP class RestCamelTest extends AgentInstrumentationSpecification implements RetryOnAddressAlreadyInUseTrait { @@ -100,6 +99,8 @@ class RestCamelTest extends AgentInstrumentationSpecification implements RetryOn "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + // TODO: camel instrumentation does not use ServerSpanNaming to update the route, so the matched route is provided by the servlet instrumentation + "$SemanticAttributes.HTTP_ROUTE" "/*" } } it.span(3) { diff --git a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy index 5f560ce9b150..866b7b485490 100644 --- a/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy +++ b/instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/TwoServicesWithDirectClientCamelTest.groovy @@ -5,8 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP - import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.instrumentation.test.RetryOnAddressAlreadyInUseTrait import io.opentelemetry.instrumentation.test.utils.PortUtils @@ -22,6 +20,7 @@ import spock.lang.Shared import static io.opentelemetry.api.trace.SpanKind.CLIENT import static io.opentelemetry.api.trace.SpanKind.INTERNAL import static io.opentelemetry.api.trace.SpanKind.SERVER +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP class TwoServicesWithDirectClientCamelTest extends AgentInstrumentationSpecification implements RetryOnAddressAlreadyInUseTrait { @@ -136,6 +135,8 @@ class TwoServicesWithDirectClientCamelTest extends AgentInstrumentationSpecifica "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" Long + // TODO: camel instrumentation does not use ServerSpanNaming to update the route, so the matched route is provided by the servlet instrumentation + "$SemanticAttributes.HTTP_ROUTE" "/*" } } it.span(5) { diff --git a/instrumentation/armeria-1.3/testing/src/main/groovy/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.groovy b/instrumentation/armeria-1.3/testing/src/main/groovy/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.groovy index 3f2af2d06eef..f9826b34071a 100644 --- a/instrumentation/armeria-1.3/testing/src/main/groovy/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.groovy +++ b/instrumentation/armeria-1.3/testing/src/main/groovy/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.groovy @@ -29,6 +29,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.INDEXED_CHILD +import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.REDIRECT @@ -38,12 +39,23 @@ abstract class AbstractArmeriaHttpServerTest extends HttpServerTest { abstract ServerBuilder configureServer(ServerBuilder serverBuilder) + @Override + String expectedHttpRoute(ServerEndpoint endpoint) { + switch (endpoint) { + case NOT_FOUND: + // TODO(anuraaga): Revisit this when applying instrumenters to more libraries, Armeria + // currently reports '/*' which is a fallback route. + return "/*" + default: + return super.expectedHttpRoute(endpoint) + } + } + @Override List> extraAttributes() { [ SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH, - SemanticAttributes.HTTP_ROUTE, SemanticAttributes.HTTP_SERVER_NAME, SemanticAttributes.NET_PEER_NAME, SemanticAttributes.NET_TRANSPORT diff --git a/instrumentation/dropwizard/dropwizard-testing/src/test/groovy/DropwizardTest.groovy b/instrumentation/dropwizard/dropwizard-testing/src/test/groovy/DropwizardTest.groovy index 9e78c51028d5..1d4627eec81d 100644 --- a/instrumentation/dropwizard/dropwizard-testing/src/test/groovy/DropwizardTest.groovy +++ b/instrumentation/dropwizard/dropwizard-testing/src/test/groovy/DropwizardTest.groovy @@ -93,14 +93,14 @@ class DropwizardTest extends HttpServerTest implements Ag } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { - case PATH_PARAM: - return "/path/{id}/param" case NOT_FOUND: - return "/*" + return getContextPath() + "/*" + case PATH_PARAM: + return getContextPath() + "/path/{id}/param" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/grails-3.0/javaagent/src/test/groovy/test/GrailsTest.groovy b/instrumentation/grails-3.0/javaagent/src/test/groovy/test/GrailsTest.groovy index 23787aa963cf..57fb71364ef1 100644 --- a/instrumentation/grails-3.0/javaagent/src/test/groovy/test/GrailsTest.groovy +++ b/instrumentation/grails-3.0/javaagent/src/test/groovy/test/GrailsTest.groovy @@ -66,7 +66,7 @@ class GrailsTest extends HttpServerTest implemen } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { if (endpoint == PATH_PARAM) { return getContextPath() + "/test/path" } else if (endpoint == QUERY_PARAM) { diff --git a/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyFilterchainServerTest.groovy b/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyFilterchainServerTest.groovy index 0e63f0bb9df2..ff744ac694b8 100644 --- a/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyFilterchainServerTest.groovy +++ b/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyFilterchainServerTest.groovy @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest -import java.nio.charset.StandardCharsets +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.glassfish.grizzly.filterchain.BaseFilter import org.glassfish.grizzly.filterchain.FilterChain import org.glassfish.grizzly.filterchain.FilterChainBuilder @@ -25,6 +26,7 @@ import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder import org.glassfish.grizzly.utils.DelayedExecutor import org.glassfish.grizzly.utils.IdleTimeoutFilter +import java.nio.charset.StandardCharsets import java.util.concurrent.Executors import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.AUTH_REQUIRED @@ -61,6 +63,18 @@ class GrizzlyFilterchainServerTest extends HttpServerTest implements transport.shutdownNow() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + + @Override + String expectedServerSpanName(ServerEndpoint endpoint) { + return "HTTP GET" + } + @Override boolean testException() { // justification: grizzly async closes the channel which @@ -230,9 +244,4 @@ class GrizzlyFilterchainServerTest extends HttpServerTest implements } } } - - @Override - String expectedServerSpanName(ServerEndpoint endpoint) { - return "HTTP GET" - } } diff --git a/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyTest.groovy b/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyTest.groovy index c88bfef50708..842a117065e5 100644 --- a/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyTest.groovy +++ b/instrumentation/grizzly-2.0/javaagent/src/test/groovy/GrizzlyTest.groovy @@ -3,8 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.glassfish.grizzly.http.server.HttpHandler import org.glassfish.grizzly.http.server.HttpServer import org.glassfish.grizzly.http.server.Request @@ -42,6 +44,18 @@ class GrizzlyTest extends HttpServerTest implements AgentTestTrait { return server } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + + @Override + String expectedServerSpanName(ServerEndpoint endpoint) { + return "HTTP GET" + } + @Override void stopServer(HttpServer server) { server.stop() @@ -108,11 +122,6 @@ class GrizzlyTest extends HttpServerTest implements AgentTestTrait { } } - @Override - String expectedServerSpanName(ServerEndpoint endpoint) { - return "HTTP GET" - } - static class ExceptionHttpHandler extends HttpHandler { @Override diff --git a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JaxRsAnnotations1InstrumentationTest.groovy b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JaxRsAnnotations1InstrumentationTest.groovy index bdf62cfad0cb..d9c42bc4b67b 100644 --- a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JaxRsAnnotations1InstrumentationTest.groovy +++ b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JaxRsAnnotations1InstrumentationTest.groovy @@ -36,6 +36,7 @@ class JaxRsAnnotations1InstrumentationTest extends AgentInstrumentationSpecifica kind SERVER hasNoParent() attributes { + "$SemanticAttributes.HTTP_ROUTE" paramName } } span(1) { diff --git a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JerseyTest.groovy b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JerseyTest.groovy index bb9abd849713..a6d8c33ed0be 100644 --- a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JerseyTest.groovy +++ b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/test/groovy/JerseyTest.groovy @@ -38,9 +38,10 @@ class JerseyTest extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 2) { span(0) { - name expectedSpanName + name expectedRoute kind SERVER attributes { + "$SemanticAttributes.HTTP_ROUTE" expectedRoute } } @@ -56,7 +57,7 @@ class JerseyTest extends AgentInstrumentationSpecification { } where: - resource | expectedSpanName | controllerName | expectedResponse + resource | expectedRoute | controllerName | expectedResponse "/test/hello/bob" | "/test/hello/{name}" | "Test1.hello" | "Test1 bob!" "/test2/hello/bob" | "/test2/hello/{name}" | "Test2.hello" | "Test2 bob!" "/test3/hi/bob" | "/test3/hi/{name}" | "Test3.hello" | "Test3 bob!" @@ -76,9 +77,10 @@ class JerseyTest extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 2) { span(0) { - name expectedSpanName + name expectedRoute kind SERVER attributes { + "$SemanticAttributes.HTTP_ROUTE" expectedRoute } } span(1) { @@ -94,7 +96,7 @@ class JerseyTest extends AgentInstrumentationSpecification { } where: - resource | expectedSpanName | controller1Name | expectedResponse - "/test3/nested" | "/test3/nested" | "Test3.nested" | "Test3 nested!" + resource | expectedRoute | controller1Name | expectedResponse + "/test3/nested" | "/test3/nested" | "Test3.nested" | "Test3 nested!" } } diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy index e7a20dac5ea9..26ee99f3ccfd 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy @@ -135,6 +135,7 @@ abstract class JaxRsFilterTest extends AgentInstrumentationSpecification { kind SERVER if (!runsOnServer()) { attributes { + "$SemanticAttributes.HTTP_ROUTE" parentResourceName } } } diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy index d1ef4ff0c592..664cc359e92a 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP - import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.asserts.TraceAssert @@ -20,6 +18,7 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP import static java.util.concurrent.TimeUnit.SECONDS import static org.junit.jupiter.api.Assumptions.assumeTrue @@ -287,6 +286,7 @@ abstract class JaxRsHttpServerTest extends HttpServerTest implements Agent "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP "$SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional + "$SemanticAttributes.HTTP_ROUTE" path if (fullUrl.getPath().endsWith(ServerEndpoint.CAPTURE_HEADERS.getPath())) { "http.request.header.x_test_request" { it == ["test"] } "http.response.header.x_test_response" { it == ["test"] } diff --git a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxrsAnnotationsInstrumentationTest.groovy b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxrsAnnotationsInstrumentationTest.groovy index 914f23a3a2df..7680c4adbac4 100644 --- a/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxrsAnnotationsInstrumentationTest.groovy +++ b/instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxrsAnnotationsInstrumentationTest.groovy @@ -36,6 +36,7 @@ abstract class JaxrsAnnotationsInstrumentationTest extends AgentInstrumentationS kind SERVER hasNoParent() attributes { + "$SemanticAttributes.HTTP_ROUTE" paramName } } span(1) { diff --git a/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy b/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy index 2ed3640d1e43..03eebf390de4 100644 --- a/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy +++ b/instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy @@ -141,6 +141,13 @@ class JettyHandlerTest extends HttpServerTest implements AgentTestTrait } } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { "HTTP GET" diff --git a/instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy b/instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy index 5f61ba719c52..01ddd49e451b 100644 --- a/instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy +++ b/instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy @@ -142,6 +142,13 @@ class JettyHandlerTest extends HttpServerTest implements AgentTestTrait } } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { "HTTP GET" diff --git a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy index ea8994e09cf5..4b6eb4d56360 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy +++ b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationBasicTests.groovy @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP - import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.instrumentation.test.utils.PortUtils import io.opentelemetry.semconv.trace.attributes.SemanticAttributes @@ -23,6 +21,7 @@ import java.nio.file.Files import static io.opentelemetry.api.trace.SpanKind.SERVER import static io.opentelemetry.api.trace.StatusCode.ERROR +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP //TODO should this be HttpServerTest? class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { @@ -85,15 +84,17 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/$jspFileName" + hasNoParent() - name "/$jspWebappContext/$jspFileName" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/$jspFileName" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" @@ -101,6 +102,7 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -140,21 +142,24 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/getQuery.jsp" + hasNoParent() - name "/$jspWebappContext/getQuery.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/getQuery.jsp?$queryString" + "$SemanticAttributes.HTTP_TARGET" "$route?$queryString" "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -190,15 +195,17 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/post.jsp" + hasNoParent() - name "/$jspWebappContext/post.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/post.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "POST" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" @@ -206,6 +213,7 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" Long + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -237,8 +245,10 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/$jspFileName" + hasNoParent() - name "/$jspWebappContext/$jspFileName" + name route kind SERVER status ERROR event(0) { @@ -258,13 +268,14 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/$jspFileName" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 500 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -314,21 +325,24 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/includes/includeHtml.jsp" + hasNoParent() - name "/$jspWebappContext/includes/includeHtml.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/includes/includeHtml.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -359,21 +373,24 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 7) { span(0) { + def route = "/$jspWebappContext/includes/includeMulti.jsp" + hasNoParent() - name "/$jspWebappContext/includes/includeMulti.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/includes/includeMulti.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -434,8 +451,10 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 2) { span(0) { + def route = "/$jspWebappContext/$jspFileName" + hasNoParent() - name "/$jspWebappContext/$jspFileName" + name route kind SERVER status ERROR errorEvent(JasperException, String) @@ -444,13 +463,14 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/$jspFileName" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 500 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -482,8 +502,10 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 1) { span(0) { + def route = "/$jspWebappContext/*" + hasNoParent() - name "/$jspWebappContext/*" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" @@ -497,6 +519,7 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification { "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } } diff --git a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy index 4755f92c7ff7..10499218d552 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy +++ b/instrumentation/jsp-2.3/javaagent/src/test/groovy/JspInstrumentationForwardTests.groovy @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP - import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification import io.opentelemetry.instrumentation.test.utils.PortUtils import io.opentelemetry.semconv.trace.attributes.SemanticAttributes @@ -21,6 +19,7 @@ import java.nio.file.Files import static io.opentelemetry.api.trace.SpanKind.SERVER import static io.opentelemetry.api.trace.StatusCode.ERROR import static io.opentelemetry.api.trace.StatusCode.UNSET +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { @@ -83,21 +82,24 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 5) { span(0) { + def route = "/$jspWebappContext/$forwardFromFileName" + hasNoParent() - name "/$jspWebappContext/$forwardFromFileName" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/$forwardFromFileName" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -149,21 +151,24 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 3) { span(0) { + def route = "/$jspWebappContext/forwards/forwardToHtml.jsp" + hasNoParent() - name "/$jspWebappContext/forwards/forwardToHtml.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/forwards/forwardToHtml.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -194,21 +199,24 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 9) { span(0) { + def route = "/$jspWebappContext/forwards/forwardToIncludeMulti.jsp" + hasNoParent() - name "/$jspWebappContext/forwards/forwardToIncludeMulti.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/forwards/forwardToIncludeMulti.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -287,21 +295,24 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 7) { span(0) { + def route = "/$jspWebappContext/forwards/forwardToJspForward.jsp" + hasNoParent() - name "/$jspWebappContext/forwards/forwardToJspForward.jsp" + name route kind SERVER attributes { "$SemanticAttributes.NET_PEER_IP" "127.0.0.1" "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/forwards/forwardToJspForward.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 200 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -364,8 +375,10 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 4) { span(0) { + def route = "/$jspWebappContext/forwards/forwardToCompileError.jsp" + hasNoParent() - name "/$jspWebappContext/forwards/forwardToCompileError.jsp" + name route kind SERVER status ERROR errorEvent(JasperException, String) @@ -374,13 +387,14 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/forwards/forwardToCompileError.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 500 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { @@ -423,8 +437,10 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { assertTraces(1) { trace(0, 4) { span(0) { + def route = "/$jspWebappContext/forwards/forwardToNonExistent.jsp" + hasNoParent() - name "/$jspWebappContext/forwards/forwardToNonExistent.jsp" + name route kind SERVER status UNSET attributes { @@ -432,13 +448,14 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification { "$SemanticAttributes.NET_PEER_PORT" Long "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_HOST" "localhost:$port" - "$SemanticAttributes.HTTP_TARGET" "/$jspWebappContext/forwards/forwardToNonExistent.jsp" + "$SemanticAttributes.HTTP_TARGET" route "$SemanticAttributes.HTTP_METHOD" "GET" "$SemanticAttributes.HTTP_STATUS_CODE" 404 "$SemanticAttributes.HTTP_FLAVOR" "1.1" "$SemanticAttributes.HTTP_USER_AGENT" String "$SemanticAttributes.HTTP_SERVER_NAME" String "$SemanticAttributes.NET_TRANSPORT" IP_TCP + "$SemanticAttributes.HTTP_ROUTE" route } } span(1) { diff --git a/instrumentation/ktor-1.0/library/src/test/groovy/io/opentelemetry/instrumentation/ktor/v1_0/KtorHttpServerTest.groovy b/instrumentation/ktor-1.0/library/src/test/groovy/io/opentelemetry/instrumentation/ktor/v1_0/KtorHttpServerTest.groovy index b238fb3a6778..4b2b5bb569b2 100644 --- a/instrumentation/ktor-1.0/library/src/test/groovy/io/opentelemetry/instrumentation/ktor/v1_0/KtorHttpServerTest.groovy +++ b/instrumentation/ktor-1.0/library/src/test/groovy/io/opentelemetry/instrumentation/ktor/v1_0/KtorHttpServerTest.groovy @@ -13,7 +13,7 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import java.util.concurrent.TimeUnit -import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND +import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM class KtorHttpServerTest extends HttpServerTest implements LibraryTestTrait { @@ -34,13 +34,24 @@ class KtorHttpServerTest extends HttpServerTest implements Li return false } + @Override + boolean testPathParam() { + true + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { + def route = expectedHttpRoute(endpoint) + return route == null ? "HTTP GET" : route + } + + @Override + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { - case NOT_FOUND: - return "HTTP GET" + case PATH_PARAM: + return getContextPath() + "/path/{id}/param" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy b/instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy index 24ff07ac42b1..6d47e4e1bf19 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy +++ b/instrumentation/netty/netty-3.8/javaagent/src/test/groovy/Netty38ServerTest.groovy @@ -3,8 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.jboss.netty.bootstrap.ServerBootstrap import org.jboss.netty.buffer.ChannelBuffer import org.jboss.netty.buffer.ChannelBuffers @@ -159,6 +161,13 @@ class Netty38ServerTest extends HttpServerTest implements Agent server?.shutdown() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy b/instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy index 5b9794092b93..9b04cbfd9c8a 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy +++ b/instrumentation/netty/netty-4.0/javaagent/src/test/groovy/Netty40ServerTest.groovy @@ -24,8 +24,10 @@ import io.netty.handler.codec.http.QueryStringDecoder import io.netty.handler.logging.LogLevel import io.netty.handler.logging.LoggingHandler import io.netty.util.CharsetUtil +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE @@ -128,6 +130,13 @@ class Netty40ServerTest extends HttpServerTest implements AgentT server?.shutdownGracefully() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy b/instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy index 878970c488a7..86b5635ba81b 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy +++ b/instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ServerTest.groovy @@ -23,8 +23,10 @@ import io.netty.handler.codec.http.QueryStringDecoder import io.netty.handler.logging.LogLevel import io.netty.handler.logging.LoggingHandler import io.netty.util.CharsetUtil +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE @@ -127,6 +129,13 @@ class Netty41ServerTest extends HttpServerTest implements AgentT server?.shutdownGracefully() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/play/play-2.4/javaagent/src/test/groovy/server/PlayServerTest.groovy b/instrumentation/play/play-2.4/javaagent/src/test/groovy/server/PlayServerTest.groovy index 511ed72ab6d2..ee8e305fa2f2 100644 --- a/instrumentation/play/play-2.4/javaagent/src/test/groovy/server/PlayServerTest.groovy +++ b/instrumentation/play/play-2.4/javaagent/src/test/groovy/server/PlayServerTest.groovy @@ -5,12 +5,13 @@ package server - +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.trace.StatusCode import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.asserts.TraceAssert import io.opentelemetry.instrumentation.test.base.HttpServerTest import io.opentelemetry.sdk.trace.data.SpanData +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import play.mvc.Results import play.routing.RoutingDsl import play.server.Server @@ -102,6 +103,13 @@ class PlayServerTest extends HttpServerTest implements AgentTestTrait { } } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/play/play-2.6/javaagent/src/test/groovy/server/PlayServerTest.groovy b/instrumentation/play/play-2.6/javaagent/src/test/groovy/server/PlayServerTest.groovy index 4fda5a0179e9..12b5984165a8 100644 --- a/instrumentation/play/play-2.6/javaagent/src/test/groovy/server/PlayServerTest.groovy +++ b/instrumentation/play/play-2.6/javaagent/src/test/groovy/server/PlayServerTest.groovy @@ -5,11 +5,13 @@ package server +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.trace.StatusCode import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.asserts.TraceAssert import io.opentelemetry.instrumentation.test.base.HttpServerTest import io.opentelemetry.sdk.trace.data.SpanData +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import play.BuiltInComponents import play.Mode import play.mvc.Controller @@ -99,6 +101,13 @@ class PlayServerTest extends HttpServerTest implements AgentTestTrait { } } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "akka.request" diff --git a/instrumentation/ratpack/ratpack-1.4/testing/src/main/groovy/io/opentelemetry/instrumentation/ratpack/server/AbstractRatpackHttpServerTest.groovy b/instrumentation/ratpack/ratpack-1.4/testing/src/main/groovy/io/opentelemetry/instrumentation/ratpack/server/AbstractRatpackHttpServerTest.groovy index 803e456e8fbf..e3b467ec3b42 100644 --- a/instrumentation/ratpack/ratpack-1.4/testing/src/main/groovy/io/opentelemetry/instrumentation/ratpack/server/AbstractRatpackHttpServerTest.groovy +++ b/instrumentation/ratpack/ratpack-1.4/testing/src/main/groovy/io/opentelemetry/instrumentation/ratpack/server/AbstractRatpackHttpServerTest.groovy @@ -152,7 +152,7 @@ abstract class AbstractRatpackHttpServerTest extends HttpServerTest> extraAttributes() { return [ - SemanticAttributes.HTTP_ROUTE, SemanticAttributes.NET_TRANSPORT ] } diff --git a/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractRestletServerTest.groovy b/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractRestletServerTest.groovy index ac3e0723df08..2bc102d49d4b 100644 --- a/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractRestletServerTest.groovy +++ b/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractRestletServerTest.groovy @@ -165,14 +165,14 @@ abstract class AbstractRestletServerTest extends HttpServerTest { } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" case NOT_FOUND: return getContextPath() + "/*" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractServletServerTest.groovy b/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractServletServerTest.groovy index 5d90ef82d63d..689a11e19b77 100644 --- a/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractServletServerTest.groovy +++ b/instrumentation/restlet/restlet-1.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v1_0/AbstractServletServerTest.groovy @@ -71,18 +71,17 @@ abstract class AbstractServletServerTest extends HttpServerTest { } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" case NOT_FOUND: return getContextPath() + "/*" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } - static class TestApp extends Application { @Override diff --git a/instrumentation/restlet/restlet-2.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v2_0/AbstractRestletServerTest.groovy b/instrumentation/restlet/restlet-2.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v2_0/AbstractRestletServerTest.groovy index 31a1bec1814f..56b244bdd037 100644 --- a/instrumentation/restlet/restlet-2.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v2_0/AbstractRestletServerTest.groovy +++ b/instrumentation/restlet/restlet-2.0/testing/src/main/groovy/io/opentelemetry/instrumentation/restlet/v2_0/AbstractRestletServerTest.groovy @@ -178,14 +178,14 @@ abstract class AbstractRestletServerTest extends HttpServerTest { } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" case NOT_FOUND: return getContextPath() + "/*" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/servlet/servlet-2.2/javaagent/src/test/groovy/JettyServlet2Test.groovy b/instrumentation/servlet/servlet-2.2/javaagent/src/test/groovy/JettyServlet2Test.groovy index 1a72d3f227ad..ac52e59955b8 100644 --- a/instrumentation/servlet/servlet-2.2/javaagent/src/test/groovy/JettyServlet2Test.groovy +++ b/instrumentation/servlet/servlet-2.2/javaagent/src/test/groovy/JettyServlet2Test.groovy @@ -71,6 +71,13 @@ class JettyServlet2Test extends HttpServerTest implements AgentTestTrait return new URI("http://localhost:$port/$CONTEXT/") } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override List> extraAttributes() { [ diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3Test.groovy b/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3Test.groovy index 8d1c9f1408c4..73d4c48bd21e 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3Test.groovy +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3Test.groovy @@ -18,6 +18,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.INDEXED_CHILD +import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.REDIRECT import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS @@ -60,6 +61,16 @@ abstract class AbstractServlet3Test extends HttpServerTest> extraAttributes() { [ diff --git a/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy b/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy index 12132e310b78..2036f65c33c4 100644 --- a/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy +++ b/instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy @@ -3,7 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.asserts.TraceAssert +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.eclipse.jetty.server.Server import org.eclipse.jetty.server.handler.ErrorHandler import org.eclipse.jetty.servlet.ServletHandler @@ -38,6 +40,13 @@ class JettyServletHandlerTest extends AbstractServlet3Test> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { if (endpoint == ServerEndpoint.CAPTURE_PARAMETERS) { diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5Test.groovy b/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5Test.groovy index df5adfd5489b..a4c8f54b936f 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5Test.groovy +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5Test.groovy @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.CAPTURE_PARAMETERS - import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.asserts.TraceAssert @@ -15,9 +13,11 @@ import jakarta.servlet.Servlet import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.AUTH_REQUIRED import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.CAPTURE_HEADERS +import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.CAPTURE_PARAMETERS import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.INDEXED_CHILD +import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.REDIRECT import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS @@ -69,6 +69,16 @@ abstract class AbstractServlet5Test extends HttpServerTest> extraAttributes() { [ diff --git a/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy b/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy index 517770d73ec2..5b1530ea481c 100644 --- a/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy +++ b/instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/JettyServletHandlerTest.groovy @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import jakarta.servlet.Servlet import jakarta.servlet.ServletException import jakarta.servlet.http.HttpServletRequest @@ -14,6 +16,13 @@ import spock.lang.IgnoreIf @IgnoreIf({ !jvm.java11Compatible }) class JettyServletHandlerTest extends AbstractServlet5Test { + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { if (ServerEndpoint.CAPTURE_PARAMETERS == endpoint) { diff --git a/instrumentation/spark-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/sparkjava/RoutesInstrumentation.java b/instrumentation/spark-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/sparkjava/RoutesInstrumentation.java index 0cc0cd0b8276..17480bcf36c7 100644 --- a/instrumentation/spark-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/sparkjava/RoutesInstrumentation.java +++ b/instrumentation/spark-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/sparkjava/RoutesInstrumentation.java @@ -43,6 +43,7 @@ public static void routeMatchEnricher(@Advice.Return RouteMatch routeMatch) { Span span = Java8BytecodeBridge.currentSpan(); if (span != null && routeMatch != null) { + // TODO should update SERVER span name/route using ServerSpanNaming span.updateName(routeMatch.getMatchUri()); } } diff --git a/instrumentation/spring/spring-webflux-5.0/javaagent/src/test/groovy/server/base/SpringWebFluxServerTest.groovy b/instrumentation/spring/spring-webflux-5.0/javaagent/src/test/groovy/server/base/SpringWebFluxServerTest.groovy index 0eb00a6815ee..627e6d807af0 100644 --- a/instrumentation/spring/spring-webflux-5.0/javaagent/src/test/groovy/server/base/SpringWebFluxServerTest.groovy +++ b/instrumentation/spring/spring-webflux-5.0/javaagent/src/test/groovy/server/base/SpringWebFluxServerTest.groovy @@ -5,9 +5,10 @@ package server.base - +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.springframework.boot.SpringApplication import org.springframework.context.ConfigurableApplicationContext @@ -34,6 +35,13 @@ abstract class SpringWebFluxServerTest extends HttpServerTest> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { switch (endpoint) { diff --git a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/boot/SpringBootBasedTest.groovy b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/boot/SpringBootBasedTest.groovy index f7d9d1f7b821..041f1494c56b 100644 --- a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/boot/SpringBootBasedTest.groovy +++ b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/boot/SpringBootBasedTest.groovy @@ -88,7 +88,7 @@ class SpringBootBasedTest extends HttpServerTest } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" @@ -97,7 +97,7 @@ class SpringBootBasedTest extends HttpServerTest case LOGIN: return getContextPath() + "/*" default: - return super.expectedServerSpanName(endpoint) + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/filter/ServletFilterTest.groovy b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/filter/ServletFilterTest.groovy index ceccaa1d70cf..6ac9a61f8ea8 100644 --- a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/filter/ServletFilterTest.groovy +++ b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/test/groovy/test/filter/ServletFilterTest.groovy @@ -90,14 +90,14 @@ class ServletFilterTest extends HttpServerTest i } @Override - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" case NOT_FOUND: return getContextPath() + "/**" default: - return super.expectedServerSpanName(endpoint) + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/struts-2.3/javaagent/src/test/groovy/Struts2ActionSpanTest.groovy b/instrumentation/struts-2.3/javaagent/src/test/groovy/Struts2ActionSpanTest.groovy index af4234e8b425..44f943cf4f6c 100644 --- a/instrumentation/struts-2.3/javaagent/src/test/groovy/Struts2ActionSpanTest.groovy +++ b/instrumentation/struts-2.3/javaagent/src/test/groovy/Struts2ActionSpanTest.groovy @@ -71,14 +71,14 @@ class Struts2ActionSpanTest extends HttpServerTest implements AgentTestT } } - String expectedServerSpanName(ServerEndpoint endpoint) { + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { case PATH_PARAM: return getContextPath() + "/path/{id}/param" case NOT_FOUND: return getContextPath() + "/*" default: - return endpoint.resolvePath(address).path + return super.expectedHttpRoute(endpoint) } } diff --git a/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatAsyncTest.groovy b/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatAsyncTest.groovy index 061339682624..7d5e75e4cc55 100644 --- a/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatAsyncTest.groovy +++ b/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatAsyncTest.groovy @@ -99,6 +99,16 @@ class TomcatAsyncTest extends HttpServerTest implements AgentTestTrait { AsyncServlet } + @Override + String expectedHttpRoute(ServerEndpoint endpoint) { + switch (endpoint) { + case NOT_FOUND: + return getContextPath() + "/*" + default: + return super.expectedHttpRoute(endpoint) + } + } + @Override List> extraAttributes() { [ diff --git a/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatHandlerTest.groovy b/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatHandlerTest.groovy index 5c3a890f6b2b..42465803d4a8 100644 --- a/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatHandlerTest.groovy +++ b/instrumentation/tomcat/tomcat-10.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v10_0/TomcatHandlerTest.groovy @@ -35,12 +35,8 @@ class TomcatHandlerTest extends HttpServerTest implements AgentTestTrait @Override String expectedServerSpanName(ServerEndpoint endpoint) { - switch (endpoint) { - case NOT_FOUND: - return "HTTP GET" - default: - return endpoint.resolvePath(address).path - } + def route = expectedHttpRoute(endpoint) + return route == null ? "HTTP GET" : route } @Override diff --git a/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatAsyncTest.groovy b/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatAsyncTest.groovy index 6ff261d90e22..0508b6f9d50e 100644 --- a/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatAsyncTest.groovy +++ b/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatAsyncTest.groovy @@ -99,6 +99,16 @@ class TomcatAsyncTest extends HttpServerTest implements AgentTestTrait { AsyncServlet } + @Override + String expectedHttpRoute(ServerEndpoint endpoint) { + switch (endpoint) { + case NOT_FOUND: + return getContextPath() + "/*" + default: + return super.expectedHttpRoute(endpoint) + } + } + @Override List> extraAttributes() { [ diff --git a/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatHandlerTest.groovy b/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatHandlerTest.groovy index 62778c397d94..4b65c6bdc199 100644 --- a/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatHandlerTest.groovy +++ b/instrumentation/tomcat/tomcat-7.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/tomcat/v7_0/TomcatHandlerTest.groovy @@ -35,12 +35,8 @@ class TomcatHandlerTest extends HttpServerTest implements AgentTestTrait @Override String expectedServerSpanName(ServerEndpoint endpoint) { - switch (endpoint) { - case NOT_FOUND: - return "HTTP GET" - default: - return endpoint.resolvePath(address).path - } + def route = expectedHttpRoute(endpoint) + return route == null ? "HTTP GET" : route } @Override diff --git a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy index 07cb067c4382..aefe85cb0ee9 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy +++ b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerDispatchTest.groovy @@ -96,6 +96,13 @@ class UndertowServerDispatchTest extends HttpServerTest implements Age undertow.stop() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy index 497e5159fd13..9b411bcf1288 100644 --- a/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy +++ b/instrumentation/undertow-1.4/javaagent/src/test/groovy/UndertowServerTest.groovy @@ -105,6 +105,13 @@ class UndertowServerTest extends HttpServerTest implements AgentTestTr undertow.stop() } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { return "HTTP GET" diff --git a/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/latestDepTest/groovy/server/VertxRxHttpServerTest.groovy b/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/latestDepTest/groovy/server/VertxRxHttpServerTest.groovy index 53000de116ee..fd8432c26b77 100644 --- a/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/latestDepTest/groovy/server/VertxRxHttpServerTest.groovy +++ b/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/latestDepTest/groovy/server/VertxRxHttpServerTest.groovy @@ -5,8 +5,10 @@ package server +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import io.vertx.core.DeploymentOptions import io.vertx.core.Promise import io.vertx.core.Vertx @@ -62,6 +64,13 @@ class VertxRxHttpServerTest extends HttpServerTest implements AgentTestTr return true } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { switch (endpoint) { diff --git a/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/version35Test/groovy/server/VertxRxHttpServerTest.groovy b/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/version35Test/groovy/server/VertxRxHttpServerTest.groovy index 4e3fcc9b82f1..d002287998a6 100644 --- a/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/version35Test/groovy/server/VertxRxHttpServerTest.groovy +++ b/instrumentation/vertx/vertx-reactive-3.5/javaagent/src/version35Test/groovy/server/VertxRxHttpServerTest.groovy @@ -5,9 +5,10 @@ package server - +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import io.vertx.core.DeploymentOptions import io.vertx.core.Future import io.vertx.core.Vertx @@ -63,6 +64,13 @@ class VertxRxHttpServerTest extends HttpServerTest implements AgentTestTr return true } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { switch (endpoint) { diff --git a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RoutingContextHandlerWrapper.java b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RoutingContextHandlerWrapper.java index 70e753c59b19..66330d648b4d 100644 --- a/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RoutingContextHandlerWrapper.java +++ b/instrumentation/vertx/vertx-web-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/RoutingContextHandlerWrapper.java @@ -33,8 +33,7 @@ public void handle(RoutingContext context) { Span serverSpan = ServerSpan.fromContextOrNull(Context.current()); try { if (serverSpan != null) { - // TODO should update only SERVER span using - // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/465 + // TODO should update SERVER span name/route using ServerSpanNaming serverSpan.updateName(context.currentRoute().getPath()); } } catch (RuntimeException ex) { diff --git a/instrumentation/vertx/vertx-web-3.0/testing/src/main/groovy/server/AbstractVertxHttpServerTest.groovy b/instrumentation/vertx/vertx-web-3.0/testing/src/main/groovy/server/AbstractVertxHttpServerTest.groovy index 7e2b8a4bed4f..8087cf512d95 100644 --- a/instrumentation/vertx/vertx-web-3.0/testing/src/main/groovy/server/AbstractVertxHttpServerTest.groovy +++ b/instrumentation/vertx/vertx-web-3.0/testing/src/main/groovy/server/AbstractVertxHttpServerTest.groovy @@ -5,8 +5,10 @@ package server +import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.instrumentation.test.AgentTestTrait import io.opentelemetry.instrumentation.test.base.HttpServerTest +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import io.vertx.core.AbstractVerticle import io.vertx.core.DeploymentOptions import io.vertx.core.Vertx @@ -59,6 +61,13 @@ abstract class AbstractVertxHttpServerTest extends HttpServerTest impleme return false } + @Override + Set> httpAttributes(ServerEndpoint endpoint) { + def attributes = super.httpAttributes(endpoint) + attributes.remove(SemanticAttributes.HTTP_ROUTE) + attributes + } + @Override String expectedServerSpanName(ServerEndpoint endpoint) { switch (endpoint) { diff --git a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/asserts/AttributesAssert.groovy b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/asserts/AttributesAssert.groovy index 8e9ab37b3735..c9c270ec4d1a 100644 --- a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/asserts/AttributesAssert.groovy +++ b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/asserts/AttributesAssert.groovy @@ -36,11 +36,11 @@ class AttributesAssert { assertedAttributes.add(name) def value = attributes.get(name) if (expected instanceof Pattern) { - assert value =~ expected + assert value =~ expected, "value '$value' does not match regex '$expected'" } else if (expected instanceof Class) { - assert ((Class) expected).isInstance(value) + assert ((Class) expected).isInstance(value), "value '$value' is not an instance of $expected.name" } else if (expected instanceof Closure) { - assert ((Closure) expected).call(value) + assert ((Closure) expected).call(value), "value '$value' fails the passed predicate" } else { assert value == expected } diff --git a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy index 9d4b1e46b308..8f8ed3916a7f 100644 --- a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy +++ b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy @@ -66,11 +66,16 @@ abstract class HttpServerTest extends InstrumentationSpecification imple } String expectedServerSpanName(ServerEndpoint endpoint) { + def route = expectedHttpRoute(endpoint) + return route == null ? getContextPath() + "/*" : route + } + + String expectedHttpRoute(ServerEndpoint endpoint) { switch (endpoint) { + case NOT_FOUND: + return null case PATH_PARAM: return getContextPath() + "/path/:id/param" - case NOT_FOUND: - return getContextPath() + "/*" default: return endpoint.resolvePath(address).path } @@ -152,6 +157,12 @@ abstract class HttpServerTest extends InstrumentationSpecification imple return true } + /** A list of additional HTTP server span attributes extracted by the instrumentation per URI. */ + Set> httpAttributes(ServerEndpoint endpoint) { + [SemanticAttributes.HTTP_ROUTE] as Set + } + + // TODO: remove that method and use httpAttributes everywhere; similar to HttpClientTest List> extraAttributes() { [] } @@ -650,7 +661,7 @@ abstract class HttpServerTest extends InstrumentationSpecification imple // parent span must be cast otherwise it breaks debugging classloading (junit loads it early) void serverSpan(TraceAssert trace, int index, String traceID = null, String parentID = null, String method = "GET", Long responseContentLength = null, ServerEndpoint endpoint = SUCCESS) { - def extraAttributes = extraAttributes() + def httpAttributes = extraAttributes() + this.httpAttributes(endpoint) trace.span(index) { name expectedServerSpanName(endpoint) kind SpanKind.SERVER // can't use static import because of SERVER type parameter @@ -674,7 +685,7 @@ abstract class HttpServerTest extends InstrumentationSpecification imple } } attributes { - if (extraAttributes.contains(SemanticAttributes.NET_TRANSPORT)) { + if (httpAttributes.contains(SemanticAttributes.NET_TRANSPORT)) { "$SemanticAttributes.NET_TRANSPORT" IP_TCP } // net.peer.name resolves to "127.0.0.1" on windows which is same as net.peer.ip so then not captured @@ -692,26 +703,25 @@ abstract class HttpServerTest extends InstrumentationSpecification imple "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_TARGET" endpoint.resolvePath(address).getPath() + "${endpoint == QUERY_PARAM ? "?${endpoint.body}" : ""}" - if (extraAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) { "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" Long } else { "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional } - if (extraAttributes.contains(SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH)) { "$SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH" Long } else { "$SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional } - if (extraAttributes.contains(SemanticAttributes.HTTP_ROUTE)) { - // TODO(anuraaga): Revisit this when applying instrumenters to more libraries, Armeria - // currently reports '/*' which is a fallback route. - "$SemanticAttributes.HTTP_ROUTE" String - } - if (extraAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) { "$SemanticAttributes.HTTP_SERVER_NAME" String } + if (httpAttributes.contains(SemanticAttributes.HTTP_ROUTE)) { + "$SemanticAttributes.HTTP_ROUTE" { it == expectedHttpRoute(endpoint) } + } + if (endpoint == CAPTURE_HEADERS) { "http.request.header.x_test_request" { it == ["test"] } "http.response.header.x_test_response" { it == ["test"] } @@ -724,14 +734,14 @@ abstract class HttpServerTest extends InstrumentationSpecification imple } void indexedServerSpan(TraceAssert trace, Object parent, int requestId) { - def extraAttributes = extraAttributes() ServerEndpoint endpoint = INDEXED_CHILD + def httpAttributes = extraAttributes() + this.httpAttributes(endpoint) trace.span(1) { name expectedServerSpanName(endpoint) kind SpanKind.SERVER // can't use static import because of SERVER type parameter childOf((SpanData) parent) attributes { - if (extraAttributes.contains(SemanticAttributes.NET_TRANSPORT)) { + if (httpAttributes.contains(SemanticAttributes.NET_TRANSPORT)) { "$SemanticAttributes.NET_TRANSPORT" IP_TCP } // net.peer.name resolves to "127.0.0.1" on windows which is same as net.peer.ip so then not captured @@ -749,26 +759,29 @@ abstract class HttpServerTest extends InstrumentationSpecification imple "$SemanticAttributes.HTTP_SCHEME" "http" "$SemanticAttributes.HTTP_TARGET" endpoint.resolvePath(address).getPath() + "?id=$requestId" - if (extraAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) { "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" Long } else { "$SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional } - if (extraAttributes.contains(SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH)) { "$SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH" Long } else { "$SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH" { it == null || it instanceof Long } // Optional } - if (extraAttributes.contains(SemanticAttributes.HTTP_ROUTE)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_ROUTE)) { // TODO(anuraaga): Revisit this when applying instrumenters to more libraries, Armeria // currently reports '/*' which is a fallback route. "$SemanticAttributes.HTTP_ROUTE" String } - if (extraAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) { + if (httpAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) { "$SemanticAttributes.HTTP_SERVER_NAME" String } + if (httpAttributes.contains(SemanticAttributes.HTTP_ROUTE)) { + "$SemanticAttributes.HTTP_ROUTE" { it == expectedHttpRoute(endpoint) } + } } } }