Remove url from HttpServerAttributesExtractor (#4209)

* Remove url from HttpServerAttributesExtractor

* Remove UriBuilder

* Tracers too

* apache-camel

* Finatra

* jsp

* Ratpack

* Ratpack library

* Ratpack

* Spark

* Feedback

* Fix Undertow

* Vertx

* vertx-web

* play-2.4

* webflux

* jaxrs

* Spotless

* Update semantic-conventions.md

* Update smoke tests

* More realistic target

* Remove outdated doc

* Wording
This commit is contained in:
Trask Stalnaker 2021-10-03 09:17:23 -07:00 committed by GitHub
parent c421b66d56
commit 92394ad9ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 383 additions and 365 deletions

View File

@ -8,12 +8,12 @@ are implemented by Java autoinstrumentation and which ones are not.
| Attribute | Required | Implemented? |
|---|:---:|:---:|
| `http.method` | Y | + |
| `http.url` | N | + |
| `http.target` | N | - [1] |
| `http.host` | N | - [1] |
| `http.scheme` | N | - [1] |
| `http.url` | N | - [1] |
| `http.target` | N | + [1] |
| `http.host` | N | + [1] |
| `http.scheme` | N | + [1] |
| `http.status_code` | Y | + |
| `http.flavor` | N | + [3] |
| `http.flavor` | N | + [2] |
| `http.user_agent` | N | + |
| `http.request_content_length` | N | - |
| `http.request_content_length_uncompressed` | N | - |
@ -23,12 +23,12 @@ are implemented by Java autoinstrumentation and which ones are not.
| `http.route` | N | - |
| `http.client_ip` | N | + |
**[1]:** As the majority of Java frameworks don't provide a standard way to obtain "The full request
target as passed in a HTTP request line or equivalent.", we don't set `http.target` semantic
attribute. As either it or `http.url` is required, we set the latter. This, in turn, makes setting
`http.schema` and `http.host` unnecessary duplication. Therefore, we do not set them as well.
**[1]:** Most server instrumentations capture `http.scheme`, `http.host`, and `http.target`
(and do not capture `http.url`).
Netty instrumentation is currently the only exception to this rule. Netty instrumentation
captures `http.url` (and does not capture `http.scheme`, `http.host`, or `http.target`).
**[3]:** In case of Armeria, return values are [SessionProtocol](https://github.com/line/armeria/blob/master/core/src/main/java/com/linecorp/armeria/common/SessionProtocol.java),
**[2]:** In case of Armeria, return values are [SessionProtocol](https://github.com/line/armeria/blob/master/core/src/main/java/com/linecorp/armeria/common/SessionProtocol.java),
not values defined by spec.
@ -42,19 +42,16 @@ not values defined by spec.
| `http.host` | N | - [1] |
| `http.scheme` | N | - [1] |
| `http.status_code` | Y | + |
| `http.flavor` | N | + [3] |
| `http.flavor` | N | + [2] |
| `http.user_agent` | N | + |
| `http.request_content_length` | N | - |
| `http.request_content_length_uncompressed` | N | - |
| `http.response_content_length` | N | - |
| `http.response_content_length_uncompressed` | N | - |
**[1]:** As the majority of Java frameworks don't provide a standard way to obtain "The full request
target as passed in a HTTP request line or equivalent.", we don't set `http.target` semantic
attribute. As either it or `http.url` is required, we set the latter. This, in turn, makes setting
`http.schema` and `http.host` unnecessary duplication. Therefore, we do not set them as well.
**[1]:** `http.scheme`, `http.host` and `http.target` are unnecessary since `http.url` is captured.
**[3]:** In case of Armeria, return values are [SessionProtocol](https://github.com/line/armeria/blob/master/core/src/main/java/com/linecorp/armeria/common/SessionProtocol.java),
**[2]:** In case of Armeria, return values are [SessionProtocol](https://github.com/line/armeria/blob/master/core/src/main/java/com/linecorp/armeria/common/SessionProtocol.java),
not values defined by spec.
## RPC

View File

@ -31,9 +31,6 @@ public abstract class HttpServerAttributesExtractor<REQUEST, RESPONSE>
set(attributes, SemanticAttributes.HTTP_HOST, host(request));
set(attributes, SemanticAttributes.HTTP_TARGET, target(request));
set(attributes, SemanticAttributes.HTTP_ROUTE, route(request));
// TODO: this is specific to clients, should we remove this?
set(attributes, SemanticAttributes.HTTP_URL, url(request));
}
@Override
@ -49,10 +46,6 @@ public abstract class HttpServerAttributesExtractor<REQUEST, RESPONSE>
// Attributes that always exist in a request
// TODO: this is specific to clients, should we remove this?
@Nullable
protected abstract String url(REQUEST request);
@Nullable
protected abstract String target(REQUEST request);

View File

@ -1,53 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.internal;
import org.checkerframework.checker.nullness.qual.Nullable;
// internal until decisions made on
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/3700
public class UriBuilder {
// TODO (trask) investigate and document implications of URI encoding, see
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/4008#discussion_r698027851
//
// note: currently path must be empty or start with "/" but that can be relaxed if needed
public static String uri(
String scheme, String host, int serverPort, String path, @Nullable String query) {
boolean isDefaultPort =
(scheme.equals("http") && serverPort == 80)
|| (scheme.equals("https") && serverPort == 443);
// +3 is space for "://"
int length = scheme.length() + 3 + host.length() + path.length();
if (!isDefaultPort && serverPort != -1) {
// +6 is space for ":" and max port number (65535)
length += 6;
}
if (query != null) {
// the +1 is space for "?"
length += 1 + query.length();
}
StringBuilder url = new StringBuilder(length);
url.append(scheme);
url.append("://");
url.append(host);
if (!isDefaultPort && serverPort != -1) {
url.append(':');
url.append(serverPort);
}
url.append(path);
if (query != null) {
url.append('?');
url.append(query);
}
return url.toString();
}
private UriBuilder() {}
}

View File

@ -169,24 +169,15 @@ public abstract class HttpServerTracer<REQUEST, RESPONSE, CONNECTION, STORAGE> e
spanBuilder.setAttribute(
SemanticAttributes.HTTP_USER_AGENT, requestHeader(request, USER_AGENT));
setUrl(spanBuilder, request);
// TODO set resource name from URL.
}
/*
https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md
HTTP semantic convention recommends setting http.scheme, http.host, http.target attributes
instead of http.url because it "is usually not readily available on the server side but would have
to be assembled in a cumbersome and sometimes lossy process from other information".
But in Java world there is no standard way to access "The full request target as passed in a HTTP request line or equivalent"
which is the recommended value for http.target attribute. Therefore we cannot use any of the
recommended combinations of attributes and are forced to use http.url.
*/
private void setUrl(SpanBuilder spanBuilder, REQUEST request) {
spanBuilder.setAttribute(SemanticAttributes.HTTP_URL, url(request));
String url = url(request);
if (url != null) {
// netty instrumentation uses this
spanBuilder.setAttribute(SemanticAttributes.HTTP_URL, url);
} else {
spanBuilder.setAttribute(SemanticAttributes.HTTP_SCHEME, scheme(request));
spanBuilder.setAttribute(SemanticAttributes.HTTP_HOST, host(request));
spanBuilder.setAttribute(SemanticAttributes.HTTP_TARGET, target(request));
}
}
protected void onConnectionAndRequest(
@ -297,7 +288,17 @@ public abstract class HttpServerTracer<REQUEST, RESPONSE, CONNECTION, STORAGE> e
protected abstract TextMapGetter<REQUEST> getGetter();
protected abstract String url(REQUEST request);
// netty still uses this, otherwise should prefer scheme/host/target
@Nullable
protected String url(REQUEST request) {
return null;
}
protected abstract String scheme(REQUEST request);
protected abstract String host(REQUEST request);
protected abstract String target(REQUEST request);
protected abstract String method(REQUEST request);

View File

@ -25,11 +25,6 @@ class HttpServerAttributesExtractorTest {
return request.get("method");
}
@Override
protected String url(Map<String, String> request) {
return request.get("url");
}
@Override
protected String target(Map<String, String> request) {
return request.get("target");
@ -99,7 +94,7 @@ class HttpServerAttributesExtractorTest {
Map<String, String> request = new HashMap<>();
request.put("method", "POST");
request.put("url", "http://github.com");
request.put("target", "github.com");
request.put("target", "/repositories/1");
request.put("host", "github.com:80");
request.put("scheme", "https");
request.put("userAgent", "okhttp 3.x");
@ -120,8 +115,7 @@ class HttpServerAttributesExtractorTest {
assertThat(attributes.build())
.containsOnly(
entry(SemanticAttributes.HTTP_METHOD, "POST"),
entry(SemanticAttributes.HTTP_URL, "http://github.com"),
entry(SemanticAttributes.HTTP_TARGET, "github.com"),
entry(SemanticAttributes.HTTP_TARGET, "/repositories/1"),
entry(SemanticAttributes.HTTP_HOST, "github.com:80"),
entry(SemanticAttributes.HTTP_SCHEME, "https"),
entry(SemanticAttributes.HTTP_USER_AGENT, "okhttp 3.x"),
@ -131,8 +125,7 @@ class HttpServerAttributesExtractorTest {
assertThat(attributes.build())
.containsOnly(
entry(SemanticAttributes.HTTP_METHOD, "POST"),
entry(SemanticAttributes.HTTP_URL, "http://github.com"),
entry(SemanticAttributes.HTTP_TARGET, "github.com"),
entry(SemanticAttributes.HTTP_TARGET, "/repositories/1"),
entry(SemanticAttributes.HTTP_HOST, "github.com:80"),
entry(SemanticAttributes.HTTP_ROUTE, "/repositories/{id}"),
entry(SemanticAttributes.HTTP_SCHEME, "https"),

View File

@ -1,63 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.internal;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
public class UriBuilderTest {
@ParameterizedTest
@ArgumentsSource(Parameters.class)
public void test(String scheme, String host, int port, String path, String query)
throws URISyntaxException {
assertThat(UriBuilder.uri(scheme, host, port, path, query))
.isEqualTo(new URI(scheme, null, host, port, path, query, null).toString());
}
// can't use parameterized test above because URI.toString() encodes the port when it is supplied,
// even it's the default port
@Test
public void testHttpDefaultPort() {
assertThat(UriBuilder.uri("http", "myhost", 80, "/mypath", "myquery"))
.isEqualTo("http://myhost/mypath?myquery");
}
// can't use parameterized test above because URI.toString() encodes the port when it is supplied,
// even it's the default port
@Test
public void testHttpsDefaultPort() {
assertThat(UriBuilder.uri("https", "myhost", 443, "/mypath", "myquery"))
.isEqualTo("https://myhost/mypath?myquery");
}
private static class Parameters implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(
Arguments.of("http", "myhost", -1, "/mypath", "myquery"), // test default http port
Arguments.of("http", "myhost", 8080, "/mypath", "myquery"), // test non-default http port
Arguments.of("https", "myhost", -1, "/mypath", "myquery"), // test default https port
Arguments.of(
"https", "myhost", 8443, "/mypath", "myquery"), // test non-default https port
Arguments.of("http", "myhost", -1, "/", "myquery"), // test root path
Arguments.of("http", "myhost", -1, "", "myquery"), // test empty path
Arguments.of("http", "myhost", -1, "/mypath", ""), // test empty query string
Arguments.of("http", "myhost", -1, "/mypath", null) // test null query string
);
}
}
}

View File

@ -8,9 +8,11 @@ package io.opentelemetry.javaagent.instrumentation.akkahttp.server;
import akka.http.javadsl.model.HttpHeader;
import akka.http.scaladsl.model.HttpRequest;
import akka.http.scaladsl.model.HttpResponse;
import akka.http.scaladsl.model.Uri;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer;
import scala.Option;
public class AkkaHttpServerTracer
extends HttpServerTracer<HttpRequest, HttpResponse, HttpRequest, Void> {
@ -44,8 +46,24 @@ public class AkkaHttpServerTracer
}
@Override
protected String url(HttpRequest httpRequest) {
return httpRequest.uri().toString();
protected String scheme(HttpRequest httpRequest) {
return httpRequest.uri().scheme();
}
@Override
protected String host(HttpRequest httpRequest) {
Uri.Authority authority = httpRequest.uri().authority();
return authority.host().address() + ":" + authority.port();
}
@Override
protected String target(HttpRequest httpRequest) {
String target = httpRequest.uri().path().toString();
Option<String> queryString = httpRequest.uri().rawQueryString();
if (queryString.isDefined()) {
target += "?" + queryString.get();
}
return target;
}
@Override

View File

@ -87,7 +87,9 @@ class RestCamelTest extends AgentInstrumentationSpecification implements RetryOn
kind SERVER
parentSpanId(span(1).spanId)
attributes {
"$SemanticAttributes.HTTP_URL.key" "http://localhost:$port/api/firstModule/unit/unitOne"
"$SemanticAttributes.HTTP_SCHEME.key" "http"
"$SemanticAttributes.HTTP_HOST.key" "localhost:$port"
"$SemanticAttributes.HTTP_TARGET.key" "/api/firstModule/unit/unitOne"
"$SemanticAttributes.HTTP_STATUS_CODE.key" 200
"$SemanticAttributes.HTTP_USER_AGENT.key" String
"$SemanticAttributes.HTTP_FLAVOR.key" "1.1"

View File

@ -124,7 +124,9 @@ class TwoServicesWithDirectClientCamelTest extends AgentInstrumentationSpecifica
attributes {
"$SemanticAttributes.HTTP_METHOD.key" "POST"
"$SemanticAttributes.HTTP_STATUS_CODE.key" 200
"$SemanticAttributes.HTTP_URL.key" "http://127.0.0.1:$portTwo/serviceTwo"
"$SemanticAttributes.HTTP_SCHEME.key" "http"
"$SemanticAttributes.HTTP_HOST.key" "127.0.0.1:$portTwo"
"$SemanticAttributes.HTTP_TARGET.key" "/serviceTwo"
"$SemanticAttributes.NET_PEER_PORT.key" Number
"$SemanticAttributes.NET_PEER_IP.key" "127.0.0.1"
"$SemanticAttributes.HTTP_USER_AGENT.key" "Jakarta Commons-HttpClient/3.1"

View File

@ -24,11 +24,6 @@ final class ArmeriaHttpServerAttributesExtractor
return ctx.method().name();
}
@Override
protected String url(RequestContext ctx) {
return request(ctx).uri().toString();
}
@Override
protected String target(RequestContext ctx) {
return request(ctx).path();

View File

@ -38,13 +38,10 @@ abstract class AbstractArmeriaHttpServerTest extends HttpServerTest<Server> {
@Override
List<AttributeKey<?>> extraAttributes() {
[
SemanticAttributes.HTTP_HOST,
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH,
SemanticAttributes.HTTP_RESPONSE_CONTENT_LENGTH,
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_SCHEME,
SemanticAttributes.HTTP_SERVER_NAME,
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.NET_PEER_NAME,
SemanticAttributes.NET_TRANSPORT
]

View File

@ -113,7 +113,9 @@ class DropwizardTest extends HttpServerTest<DropwizardTestSupport> implements Ag
// dropwizard reports peer ip as the client ip
"${SemanticAttributes.NET_PEER_IP.key}" TEST_CLIENT_IP
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST}" "localhost:${port}"
"${SemanticAttributes.HTTP_TARGET}" endpoint.resolvePath(address).getPath() + "${endpoint == QUERY_PARAM ? "?${endpoint.body}" : ""}"
"${SemanticAttributes.HTTP_METHOD.key}" method
"${SemanticAttributes.HTTP_STATUS_CODE.key}" endpoint.status
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -10,10 +10,12 @@ import com.twitter.util.Await
import com.twitter.util.Closable
import com.twitter.util.Duration
import com.twitter.util.Promise
import io.opentelemetry.api.common.AttributeKey
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 static io.opentelemetry.api.trace.SpanKind.INTERNAL
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.NOT_FOUND
@ -94,4 +96,11 @@ class FinatraServerLatestTest extends HttpServerTest<HttpServer> implements Agen
}
}
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -7,10 +7,12 @@ import com.twitter.finatra.http.HttpServer
import com.twitter.util.Await
import com.twitter.util.Closable
import com.twitter.util.Duration
import io.opentelemetry.api.common.AttributeKey
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 java.util.concurrent.TimeUnit
@ -78,4 +80,11 @@ class FinatraServerTest extends HttpServerTest<HttpServer> implements AgentTestT
}
}
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -8,8 +8,6 @@ package io.opentelemetry.javaagent.instrumentation.grizzly;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer;
import java.net.URI;
import java.net.URISyntaxException;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.http.HttpRequestPacket;
import org.glassfish.grizzly.http.HttpResponsePacket;
@ -55,22 +53,23 @@ public class GrizzlyHttpServerTracer
}
@Override
protected String url(HttpRequestPacket httpRequest) {
try {
return new URI(
(httpRequest.isSecure() ? "https://" : "http://")
+ httpRequest.serverName()
+ ":"
+ httpRequest.getServerPort()
+ httpRequest.getRequestURI()
+ (httpRequest.getQueryString() != null
? "?" + httpRequest.getQueryString()
: ""))
.toString();
} catch (URISyntaxException e) {
logger.warn("Failed to construct request URI", e);
return null;
protected String scheme(HttpRequestPacket httpRequest) {
return httpRequest.isSecure() ? "https" : "http";
}
@Override
protected String host(HttpRequestPacket httpRequest) {
return httpRequest.serverName() + ":" + httpRequest.getServerPort();
}
@Override
protected String target(HttpRequestPacket httpRequest) {
String target = httpRequest.getRequestURI();
String queryString = httpRequest.getQueryString();
if (queryString != null) {
target += "?" + queryString;
}
return target;
}
@Override

View File

@ -273,7 +273,9 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" { it == null || it == "127.0.0.1" } // Optional
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" fullUrl.toString()
"${SemanticAttributes.HTTP_SCHEME.key}" fullUrl.getScheme()
"${SemanticAttributes.HTTP_HOST.key}" fullUrl.getHost() + ":" + fullUrl.getPort()
"${SemanticAttributes.HTTP_TARGET.key}" fullUrl.getPath() + (fullUrl.getQuery() != null ? "?" + fullUrl.getQuery() : "")
"${SemanticAttributes.HTTP_METHOD.key}" method
"${SemanticAttributes.HTTP_STATUS_CODE.key}" statusCode
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -89,7 +89,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -139,7 +141,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/getQuery.jsp?$queryString"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/getQuery.jsp?$queryString"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -185,7 +189,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/post.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/post.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "POST"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -240,7 +246,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 500
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -300,7 +308,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/includes/includeHtml.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/includes/includeHtml.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -341,7 +351,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/includes/includeMulti.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/includes/includeMulti.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -414,7 +426,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/$jspFileName"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 500
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -456,7 +470,9 @@ class JspInstrumentationBasicTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/$staticFile"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/$staticFile"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -86,7 +86,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/$forwardFromFileName"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/$forwardFromFileName"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -148,7 +150,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/forwards/forwardToHtml.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/forwards/forwardToHtml.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -189,7 +193,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/forwards/forwardToIncludeMulti.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/forwards/forwardToIncludeMulti.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -278,7 +284,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/forwards/forwardToJspForward.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/forwards/forwardToJspForward.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -353,7 +361,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/forwards/forwardToCompileError.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/forwards/forwardToCompileError.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 500
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -407,7 +417,9 @@ class JspInstrumentationForwardTests extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/$jspWebappContext/forwards/forwardToNonExistent.jsp"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/$jspWebappContext/forwards/forwardToNonExistent.jsp"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 404
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -8,8 +8,6 @@ package io.opentelemetry.javaagent.instrumentation.liberty.dispatcher;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer;
import java.net.URI;
import java.net.URISyntaxException;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -68,21 +66,23 @@ public class LibertyDispatcherTracer
}
@Override
protected String url(LibertyRequestWrapper libertyRequestWrapper) {
try {
return new URI(
libertyRequestWrapper.getScheme(),
null,
libertyRequestWrapper.getServerName(),
libertyRequestWrapper.getServerPort(),
libertyRequestWrapper.getRequestUri(),
libertyRequestWrapper.getQueryString(),
null)
.toString();
} catch (URISyntaxException e) {
logger.debug("Failed to construct request URI", e);
return null;
protected String scheme(LibertyRequestWrapper libertyRequestWrapper) {
return libertyRequestWrapper.getScheme();
}
@Override
protected String host(LibertyRequestWrapper libertyRequestWrapper) {
return libertyRequestWrapper.getServerName() + ":" + libertyRequestWrapper.getServerPort();
}
@Override
protected String target(LibertyRequestWrapper libertyRequestWrapper) {
String target = libertyRequestWrapper.getRequestUri();
String queryString = libertyRequestWrapper.getQueryString();
if (queryString != null) {
target += "?" + queryString;
}
return target;
}
@Override

View File

@ -13,6 +13,7 @@ import io.opentelemetry.instrumentation.api.tracer.HttpServerTracer;
import io.opentelemetry.javaagent.instrumentation.netty.v3_8.ChannelTraceContext;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
@ -60,6 +61,24 @@ public class NettyHttpServerTracer
}
}
@Override
@Nullable
protected String scheme(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String host(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String target(HttpRequest request) {
return null;
}
@Override
protected String peerHostIp(Channel channel) {
SocketAddress socketAddress = channel.getRemoteAddress();

View File

@ -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
@ -160,4 +162,11 @@ class Netty38ServerTest extends HttpServerTest<ServerBootstrap> implements Agent
boolean testConcurrency() {
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -17,6 +17,7 @@ import io.opentelemetry.javaagent.instrumentation.netty.common.server.NettyReque
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpServerTracer
extends HttpServerTracer<HttpRequest, HttpResponse, Channel, Channel> {
@ -71,6 +72,24 @@ public class NettyHttpServerTracer
}
}
@Override
@Nullable
protected String scheme(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String host(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String target(HttpRequest request) {
return null;
}
@Override
protected String peerHostIp(Channel channel) {
SocketAddress socketAddress = channel.remoteAddress();

View File

@ -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
@ -130,4 +132,11 @@ class Netty40ServerTest extends HttpServerTest<EventLoopGroup> implements AgentT
boolean testConcurrency() {
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -17,6 +17,7 @@ import io.opentelemetry.instrumentation.netty.v4_1.AttributeKeys;
import io.opentelemetry.javaagent.instrumentation.netty.common.server.NettyRequestExtractAdapter;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpServerTracer
extends HttpServerTracer<HttpRequest, HttpResponse, Channel, Channel> {
@ -71,6 +72,24 @@ public class NettyHttpServerTracer
}
}
@Override
@Nullable
protected String scheme(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String host(HttpRequest request) {
return null;
}
@Override
@Nullable
protected String target(HttpRequest request) {
return null;
}
@Override
protected String peerHostIp(Channel channel) {
SocketAddress socketAddress = channel.remoteAddress();

View File

@ -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
@ -129,4 +131,11 @@ class Netty41ServerTest extends HttpServerTest<EventLoopGroup> implements AgentT
boolean testConcurrency() {
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -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.mvc.Results
import play.routing.RoutingDsl
import play.server.Server
@ -97,4 +99,11 @@ class PlayServerTest extends HttpServerTest<Server> implements AgentTestTrait {
String expectedServerSpanName(ServerEndpoint endpoint) {
return "HTTP GET"
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -5,8 +5,10 @@
package server
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.instrumentation.ratpack.server.AbstractRatpackRoutesTest
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import ratpack.server.RatpackServerSpec
class RatpackRoutesTest extends AbstractRatpackRoutesTest implements AgentTestTrait {
@ -18,4 +20,11 @@ class RatpackRoutesTest extends AbstractRatpackRoutesTest implements AgentTestTr
boolean hasHandlerSpan() {
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.ratpack;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.net.URI;
import org.checkerframework.checker.nullness.qual.Nullable;
import ratpack.handling.Context;
import ratpack.http.Request;
@ -20,27 +21,6 @@ final class RatpackHttpAttributesExtractor
return request.getMethod().getName();
}
@Override
@Nullable
protected String url(Request request) {
// TODO(anuraaga): We should probably just not fill this
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/3700
Context ratpackContext = request.get(Context.class);
if (ratpackContext == null) {
return null;
}
PublicAddress publicAddress = ratpackContext.get(PublicAddress.class);
if (publicAddress == null) {
return null;
}
return publicAddress
.builder()
.path(request.getPath())
.params(request.getQueryParams())
.build()
.toString();
}
@Override
protected String target(Request request) {
// Uri is the path + query string, not a full URL
@ -50,7 +30,16 @@ final class RatpackHttpAttributesExtractor
@Override
@Nullable
protected String host(Request request) {
return null;
Context ratpackContext = request.get(Context.class);
if (ratpackContext == null) {
return null;
}
PublicAddress publicAddress = ratpackContext.get(PublicAddress.class);
if (publicAddress == null) {
return null;
}
URI uri = publicAddress.get();
return uri.getHost() + ":" + uri.getPort();
}
@Override
@ -63,7 +52,15 @@ final class RatpackHttpAttributesExtractor
@Override
@Nullable
protected String scheme(Request request) {
return null;
Context ratpackContext = request.get(Context.class);
if (ratpackContext == null) {
return null;
}
PublicAddress publicAddress = ratpackContext.get(PublicAddress.class);
if (publicAddress == null) {
return null;
}
return publicAddress.get().getScheme();
}
@Override

View File

@ -29,8 +29,7 @@ class RatpackAsyncHttpServerTest extends AbstractRatpackAsyncHttpServerTest impl
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.NET_TRANSPORT,
SemanticAttributes.NET_TRANSPORT
]
}
}

View File

@ -29,8 +29,7 @@ class RatpackForkedHttpServerTest extends AbstractRatpackForkedHttpServerTest im
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.NET_TRANSPORT,
SemanticAttributes.NET_TRANSPORT
]
}
}

View File

@ -29,8 +29,7 @@ class RatpackHttpServerTest extends AbstractRatpackHttpServerTest implements Lib
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.NET_TRANSPORT,
SemanticAttributes.NET_TRANSPORT
]
}
}

View File

@ -29,8 +29,7 @@ class RatpackRoutesTest extends AbstractRatpackRoutesTest implements LibraryTest
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.NET_TRANSPORT,
SemanticAttributes.NET_TRANSPORT
]
}
}

View File

@ -5,10 +5,12 @@
package io.opentelemetry.instrumentation.ratpack.server
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.api.trace.StatusCode
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 ratpack.error.ServerErrorHandler
import ratpack.handling.Context
import ratpack.server.RatpackServer
@ -143,4 +145,11 @@ abstract class AbstractRatpackHttpServerTest extends HttpServerTest<RatpackServe
String expectedServerSpanName(ServerEndpoint endpoint) {
return endpoint.status == 404 ? "/" : endpoint == PATH_PARAM ? "/path/:id/param" : endpoint.path
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -104,15 +104,19 @@ abstract class AbstractRatpackRoutesTest extends InstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" { it == null || it == "127.0.0.1" }
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:${app.bindPort}/${path}"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
"${SemanticAttributes.HTTP_USER_AGENT.key}" String
if (extraAttributes.contains(SemanticAttributes.HTTP_HOST)) {
if (extraAttributes.contains(SemanticAttributes.HTTP_URL)) {
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:${app.bindPort}/${path}"
} else {
"${SemanticAttributes.HTTP_SCHEME}" "http"
"${SemanticAttributes.HTTP_HOST}" "localhost:${app.bindPort}"
"${SemanticAttributes.HTTP_TARGET}" "/$path"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) {
"${SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH}" Long
}
@ -124,15 +128,9 @@ abstract class AbstractRatpackRoutesTest extends InstrumentationSpecification {
// currently reports '/*' which is a fallback route.
"${SemanticAttributes.HTTP_ROUTE}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SCHEME)) {
"${SemanticAttributes.HTTP_SCHEME}" "http"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) {
"${SemanticAttributes.HTTP_SERVER_NAME}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_TARGET)) {
"${SemanticAttributes.HTTP_TARGET}" "/$path"
}
if (extraAttributes.contains(SemanticAttributes.NET_PEER_NAME)) {
"${SemanticAttributes.NET_PEER_NAME}" "localhost"
}

View File

@ -20,11 +20,6 @@ final class RestletHttpAttributesExtractor
return request.getMethod().toString();
}
@Override
protected String url(Request request) {
return request.getOriginalRef().toString();
}
@Override
protected @Nullable String target(Request request) {
Reference ref = request.getOriginalRef();
@ -33,8 +28,9 @@ final class RestletHttpAttributesExtractor
}
@Override
protected @Nullable String host(Request request) {
return null;
protected String host(Request request) {
Reference originalRef = request.getOriginalRef();
return originalRef.getHostDomain() + ":" + originalRef.getHostPort();
}
@Override

View File

@ -136,9 +136,7 @@ abstract class AbstractRestletServerTest extends HttpServerTest<Server> {
@Override
List<AttributeKey<?>> extraAttributes() {
[
SemanticAttributes.HTTP_TARGET,
SemanticAttributes.HTTP_SCHEME,
SemanticAttributes.NET_TRANSPORT,
SemanticAttributes.NET_TRANSPORT
]
}

View File

@ -6,7 +6,6 @@
package io.opentelemetry.javaagent.instrumentation.servlet;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.internal.UriBuilder;
import io.opentelemetry.instrumentation.servlet.ServletAccessor;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -24,44 +23,26 @@ public class ServletHttpAttributesExtractor<REQUEST, RESPONSE>
return accessor.getRequestMethod(requestContext.request());
}
@Override
protected @Nullable String url(ServletRequestContext<REQUEST> requestContext) {
REQUEST request = requestContext.request();
return UriBuilder.uri(
accessor.getRequestScheme(request),
accessor.getRequestServerName(request),
accessor.getRequestServerPort(request),
accessor.getRequestUri(request),
accessor.getRequestQueryString(request));
}
@Override
protected @Nullable String target(ServletRequestContext<REQUEST> requestContext) {
/*
String target = httpServletRequest.getRequestURI();
String queryString = httpServletRequest.getQueryString();
REQUEST request = requestContext.request();
String target = accessor.getRequestUri(request);
String queryString = accessor.getRequestQueryString(request);
if (queryString != null) {
target += "?" + queryString;
}
return target;
*/
return null;
}
@Override
protected @Nullable String host(ServletRequestContext<REQUEST> requestContext) {
/*
REQUEST request = requestContext.request();
return accessor.getRequestServerName(request) + ":" + accessor.getRequestServerPort(request);
*/
return null;
}
@Override
protected @Nullable String scheme(ServletRequestContext<REQUEST> requestContext) {
// return accessor.getRequestScheme(requestContext.request());
return null;
return accessor.getRequestScheme(requestContext.request());
}
@Override

View File

@ -48,7 +48,9 @@ class SparkJavaBasedTest extends AgentInstrumentationSpecification {
attributes {
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.NET_PEER_PORT.key}" Long
"${SemanticAttributes.HTTP_URL.key}" "http://localhost:$port/param/asdf1234"
"${SemanticAttributes.HTTP_SCHEME.key}" "http"
"${SemanticAttributes.HTTP_HOST.key}" "localhost:$port"
"${SemanticAttributes.HTTP_TARGET.key}" "/param/asdf1234"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -5,8 +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
import util.SpringWebfluxTestUtil
@ -69,4 +71,11 @@ abstract class SpringWebFluxServerTest extends HttpServerTest<ConfigurableApplic
Class<?> expectedExceptionClass() {
return IllegalStateException
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
}

View File

@ -58,11 +58,6 @@ final class SpringWebMvcHttpAttributesExtractor
return null;
}
@Override
protected @Nullable String url(HttpServletRequest request) {
return null;
}
@Override
protected @Nullable String target(HttpServletRequest request) {
String target = request.getRequestURI();

View File

@ -6,7 +6,6 @@
package io.opentelemetry.javaagent.instrumentation.tomcat.common;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.internal.UriBuilder;
import org.apache.coyote.Request;
import org.apache.coyote.Response;
import org.apache.tomcat.util.buf.MessageBytes;
@ -20,36 +19,25 @@ public class TomcatHttpAttributesExtractor
return request.method().toString();
}
@Override
protected String url(Request request) {
MessageBytes schemeMessageBytes = request.scheme();
String scheme = schemeMessageBytes.isNull() ? "http" : schemeMessageBytes.toString();
String host = request.serverName().toString();
int serverPort = request.getServerPort();
String path = request.requestURI().toString();
String query = request.queryString().toString();
return UriBuilder.uri(scheme, host, serverPort, path, query);
}
@Override
protected @Nullable String target(Request request) {
return null;
String target = request.requestURI().toString();
String queryString = request.queryString().toString();
if (queryString != null) {
target += "?" + queryString;
}
return target;
}
@Override
protected @Nullable String host(Request request) {
// return request.serverName().toString() + ":" + request.getServerPort();
return null;
return request.serverName().toString() + ":" + request.getServerPort();
}
@Override
protected @Nullable String scheme(Request request) {
/*
MessageBytes schemeMessageBytes = request.scheme();
return schemeMessageBytes.isNull() ? "http" : schemeMessageBytes.toString();
*/
return null;
}
@Override

View File

@ -63,16 +63,6 @@ public class UndertowHttpAttributesExtractor
return null;
}
@Override
protected String url(HttpServerExchange exchange) {
String result = exchange.getRequestURL();
if (exchange.getQueryString() == null || exchange.getQueryString().isEmpty()) {
return result;
} else {
return result + "?" + exchange.getQueryString();
}
}
@Override
protected @Nullable String target(HttpServerExchange exchange) {
String requestPath = exchange.getRequestPath();

View File

@ -134,7 +134,9 @@ class UndertowServerTest extends HttpServerTest<Undertow> implements AgentTestTr
"${SemanticAttributes.NET_PEER_PORT.key}" { it instanceof Long }
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.HTTP_CLIENT_IP.key}" TEST_CLIENT_IP
"${SemanticAttributes.HTTP_URL.key}" uri.toString()
"${SemanticAttributes.HTTP_SCHEME.key}" uri.getScheme()
"${SemanticAttributes.HTTP_HOST.key}" uri.getHost() + ":" + uri.getPort()
"${SemanticAttributes.HTTP_TARGET.key}" uri.getPath()
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
@ -187,7 +189,9 @@ class UndertowServerTest extends HttpServerTest<Undertow> implements AgentTestTr
"${SemanticAttributes.NET_PEER_PORT.key}" { it instanceof Long }
"${SemanticAttributes.NET_PEER_IP.key}" "127.0.0.1"
"${SemanticAttributes.HTTP_CLIENT_IP.key}" TEST_CLIENT_IP
"${SemanticAttributes.HTTP_URL.key}" uri.toString()
"${SemanticAttributes.HTTP_SCHEME.key}" uri.getScheme()
"${SemanticAttributes.HTTP_HOST.key}" uri.getHost() + ":" + uri.getPort()
"${SemanticAttributes.HTTP_TARGET.key}" uri.getPath()
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"

View File

@ -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.Future
import io.vertx.core.Vertx
@ -78,6 +80,13 @@ class VertxRxHttpServerTest extends HttpServerTest<Vertx> implements AgentTestTr
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
protected Class<AbstractVerticle> verticle() {
return VertxReactiveWebServer
}

View File

@ -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
@ -58,6 +60,13 @@ abstract class AbstractVertxHttpServerTest extends HttpServerTest<Vertx> impleme
return true
}
@Override
List<AttributeKey<?>> extraAttributes() {
return [
SemanticAttributes.HTTP_URL
]
}
@Override
String expectedServerSpanName(ServerEndpoint endpoint) {
switch (endpoint) {

View File

@ -99,10 +99,13 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/app/headers')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/greeting") == 1
traces.countFilteredAttributes("http.target", "/app/greeting") == 1
and: "Client and server spans for the remote call"
traces.countFilteredAttributes("http.url", "http://localhost:8080/app/headers") == 2
and: "Client span for the remote call"
traces.countFilteredAttributes("http.url", "http://localhost:8080/app/headers") == 1
and: "Server span for the remote call"
traces.countFilteredAttributes("http.target", "/app/headers") == 1
and: "Number of spans with http protocol version"
traces.countFilteredAttributes("http.flavor", "1.1") == 3
@ -140,7 +143,7 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/app/hello.txt')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/hello.txt") == 1
traces.countFilteredAttributes("http.target", "/app/hello.txt") == 1
and: "Number of spans tagged with current otel library version"
traces.countFilteredResourceAttributes("telemetry.auto.version", currentAgentVersion) == 1
@ -174,7 +177,7 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/app/file-that-does-not-exist')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/file-that-does-not-exist") == 1
traces.countFilteredAttributes("http.target", "/app/file-that-does-not-exist") == 1
and: "Number of spans tagged with current otel library version"
traces.countFilteredResourceAttributes("telemetry.auto.version", currentAgentVersion) == traces.countSpans()
@ -210,7 +213,7 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/app/WEB-INF/web.xml')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/WEB-INF/web.xml") == 1
traces.countFilteredAttributes("http.target", "/app/WEB-INF/web.xml") == 1
and: "Number of spans with http protocol version"
traces.countFilteredAttributes("http.flavor", "1.1") == 1
@ -252,7 +255,7 @@ abstract class AppServerTest extends SmokeTest {
traces.countFilteredEventAttributes('exception.message', 'This is expected') == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/exception") == 1
traces.countFilteredAttributes("http.target", "/app/exception") == 1
and: "Number of spans tagged with current otel library version"
traces.countFilteredResourceAttributes("telemetry.auto.version", currentAgentVersion) == 1
@ -286,7 +289,7 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/this-is-definitely-not-there-but-there-should-be-a-trace-nevertheless')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/this-is-definitely-not-there-but-there-should-be-a-trace-nevertheless") == 1
traces.countFilteredAttributes("http.target", "/this-is-definitely-not-there-but-there-should-be-a-trace-nevertheless") == 1
and: "Number of spans with http protocol version"
traces.countFilteredAttributes("http.flavor", "1.1") == 1
@ -327,10 +330,13 @@ abstract class AppServerTest extends SmokeTest {
traces.countSpansByName(getSpanName('/app/headers')) == 1
and: "The span for the initial web request"
traces.countFilteredAttributes("http.url", "http://localhost:${containerManager.getTargetMappedPort(8080)}/app/asyncgreeting") == 1
traces.countFilteredAttributes("http.target", "/app/asyncgreeting") == 1
and: "Client and server spans for the remote call"
traces.countFilteredAttributes("http.url", "http://localhost:8080/app/headers") == 2
and: "Client span for the remote call"
traces.countFilteredAttributes("http.url", "http://localhost:8080/app/headers") == 1
and: "Server span for the remote call"
traces.countFilteredAttributes("http.target", "/app/headers") == 1
and: "Number of spans with http protocol version"
traces.countFilteredAttributes("http.flavor", "1.1") == 3

View File

@ -569,15 +569,20 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
"${SemanticAttributes.NET_PEER_PORT.key}" { it == null || it instanceof Long }
"${SemanticAttributes.NET_PEER_IP.key}" { it == null || it == "127.0.0.1" } // Optional
"${SemanticAttributes.HTTP_CLIENT_IP.key}" { it == null || it == TEST_CLIENT_IP }
"${SemanticAttributes.HTTP_URL.key}" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }
"${SemanticAttributes.HTTP_METHOD.key}" method
"${SemanticAttributes.HTTP_STATUS_CODE.key}" endpoint.status
"${SemanticAttributes.HTTP_FLAVOR.key}" { it == "1.1" || it == "2.0" }
"${SemanticAttributes.HTTP_USER_AGENT.key}" TEST_USER_AGENT
if (extraAttributes.contains(SemanticAttributes.HTTP_HOST)) {
if (extraAttributes.contains(SemanticAttributes.HTTP_URL)) {
// netty instrumentation uses this
"${SemanticAttributes.HTTP_URL.key}" { it == "${endpoint.resolve(address)}" || it == "${endpoint.resolveWithoutFragment(address)}" }
} else {
"${SemanticAttributes.HTTP_HOST}" "localhost:${port}"
"${SemanticAttributes.HTTP_SCHEME}" "http"
"${SemanticAttributes.HTTP_TARGET}" endpoint.resolvePath(address).getPath() + "${endpoint == QUERY_PARAM ? "?${endpoint.body}" : ""}"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) {
"${SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH}" Long
}
@ -589,15 +594,9 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
// currently reports '/*' which is a fallback route.
"${SemanticAttributes.HTTP_ROUTE}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SCHEME)) {
"${SemanticAttributes.HTTP_SCHEME}" "http"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) {
"${SemanticAttributes.HTTP_SERVER_NAME}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_TARGET)) {
"${SemanticAttributes.HTTP_TARGET}" endpoint.path + "${endpoint == QUERY_PARAM ? "?${endpoint.body}" : ""}"
}
if (extraAttributes.contains(SemanticAttributes.NET_PEER_NAME)) {
// "localhost" on linux, "127.0.0.1" on windows
"${SemanticAttributes.NET_PEER_NAME.key}" { it == "localhost" || it == "127.0.0.1" }
@ -620,15 +619,20 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
"${SemanticAttributes.NET_PEER_PORT.key}" { it == null || it instanceof Long }
"${SemanticAttributes.NET_PEER_IP.key}" { it == null || it == "127.0.0.1" } // Optional
"${SemanticAttributes.HTTP_CLIENT_IP.key}" { it == null || it == TEST_CLIENT_IP }
"${SemanticAttributes.HTTP_URL.key}" endpoint.resolve(address).toString() + "?id=$requestId"
"${SemanticAttributes.HTTP_METHOD.key}" "GET"
"${SemanticAttributes.HTTP_STATUS_CODE.key}" 200
"${SemanticAttributes.HTTP_FLAVOR.key}" "1.1"
"${SemanticAttributes.HTTP_USER_AGENT.key}" TEST_USER_AGENT
if (extraAttributes.contains(SemanticAttributes.HTTP_HOST)) {
if (extraAttributes.contains(SemanticAttributes.HTTP_URL)) {
// netty instrumentation uses this
"${SemanticAttributes.HTTP_URL.key}" endpoint.resolve(address).toString() + "?id=$requestId"
} else {
"${SemanticAttributes.HTTP_HOST}" "localhost:${port}"
"${SemanticAttributes.HTTP_SCHEME}" "http"
"${SemanticAttributes.HTTP_TARGET}" endpoint.resolvePath(address).getPath() + "?id=$requestId"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH)) {
"${SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH}" Long
}
@ -640,15 +644,9 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
// currently reports '/*' which is a fallback route.
"${SemanticAttributes.HTTP_ROUTE}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SCHEME)) {
"${SemanticAttributes.HTTP_SCHEME}" "http"
}
if (extraAttributes.contains(SemanticAttributes.HTTP_SERVER_NAME)) {
"${SemanticAttributes.HTTP_SERVER_NAME}" String
}
if (extraAttributes.contains(SemanticAttributes.HTTP_TARGET)) {
"${SemanticAttributes.HTTP_TARGET}" endpoint.path + "?id=$requestId"
}
if (extraAttributes.contains(SemanticAttributes.NET_PEER_NAME)) {
"${SemanticAttributes.NET_PEER_NAME}" "localhost"
}