Flavor extractor
MODIFY
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractor.java
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientAttributesExtractor.java
package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.api.common.AttributesBuilder;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -34,10 +36,22 @@ public abstract class HttpClientAttributesExtractor<REQUEST, RESPONSE>
@Nullable RESPONSE response,
@Nullable Throwable error) {
super.onEnd(attributes, request, response, error);
+ set(attributes, SemanticAttributes.HTTP_FLAVOR, flavor(request, response));
}
// Attributes that always exist in a request
@Nullable
protected abstract String url(REQUEST request);
+
+ // Attributes which are not always available when the request is ready.
+
+ /**
+ * Extracts the {@code http.flavor} span attribute.
+ *
+ * <p>This is called from {@link Instrumenter#end(Context, Object, Object, Throwable)}, whether
+ * {@code response} is {@code null} or not.
+ */
+ @Nullable
+ protected abstract String flavor(REQUEST request, @Nullable RESPONSE response);
}

MODIFY
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpCommonAttributesExtractor.java
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpCommonAttributesExtractor.java
@@ -44,7 +44,6 @@ public abstract class HttpCommonAttributesExtractor<REQUEST, RESPONSE>
attributes,
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,
requestContentLengthUncompressed(request, response));
- set(attributes, SemanticAttributes.HTTP_FLAVOR, flavor(request, response));
if (response != null) {
Integer statusCode = statusCode(request, response);
if (statusCode != null) {
@@ -90,15 +89,6 @@ public abstract class HttpCommonAttributesExtractor<REQUEST, RESPONSE>
protected abstract Long requestContentLengthUncompressed(
REQUEST request, @Nullable RESPONSE response);
- /**
- * Extracts the {@code http.flavor} span attribute.
- *
- * <p>This is called from {@link Instrumenter#end(Context, Object, Object, Throwable)}, whether
- * {@code response} is {@code null} or not.
- */
- @Nullable
- protected abstract String flavor(REQUEST request, @Nullable RESPONSE response);
-
/**
* Extracts the {@code http.status_code} span attribute.
*

MODIFY
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractor.java
instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractor.java
@@ -27,6 +27,7 @@ public abstract class HttpServerAttributesExtractor<REQUEST, RESPONSE>
protected final void onStart(AttributesBuilder attributes, REQUEST request) {
super.onStart(attributes, request);
+ set(attributes, SemanticAttributes.HTTP_FLAVOR, flavor(request));
set(attributes, SemanticAttributes.HTTP_SCHEME, scheme(request));
set(attributes, SemanticAttributes.HTTP_HOST, host(request));
set(attributes, SemanticAttributes.HTTP_TARGET, target(request));
@@ -46,6 +47,9 @@ public abstract class HttpServerAttributesExtractor<REQUEST, RESPONSE>
// Attributes that always exist in a request
+ @Nullable
+ protected abstract String flavor(REQUEST request);
+
@Nullable
protected abstract String target(REQUEST request);

MODIFY
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractorTest.java
instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerAttributesExtractorTest.java
@@ -72,7 +72,7 @@ class HttpServerAttributesExtractorTest {
}
@Override
- protected String flavor(Map<String, String> request, Map<String, String> response) {
+ protected String flavor(Map<String, String> request) {
return request.get("flavor");
}
@@ -114,6 +114,7 @@ class HttpServerAttributesExtractorTest {
extractor.onStart(attributes, request);
assertThat(attributes.build())
.containsOnly(
+ entry(SemanticAttributes.HTTP_FLAVOR, "http/2"),
entry(SemanticAttributes.HTTP_METHOD, "POST"),
entry(SemanticAttributes.HTTP_TARGET, "/repositories/1"),
entry(SemanticAttributes.HTTP_HOST, "github.com:80"),

MODIFY
instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaHttpServerAttributesExtractor.java
instrumentation/armeria-1.3/library/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/ArmeriaHttpServerAttributesExtractor.java
@@ -74,7 +74,7 @@ final class ArmeriaHttpServerAttributesExtractor
}
@Override
- protected String flavor(RequestContext ctx, @Nullable RequestLog requestLog) {
+ protected String flavor(RequestContext ctx) {
SessionProtocol protocol = ctx.sessionProtocol();
if (protocol.isMultiplex()) {
return SemanticAttributes.HttpFlavorValues.HTTP_2_0;

MODIFY
instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherHttpAttributesExtractor.java
instrumentation/liberty/liberty-dispatcher/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/liberty/dispatcher/LibertyDispatcherHttpAttributesExtractor.java
@@ -38,8 +38,7 @@ public class LibertyDispatcherHttpAttributesExtractor
}
@Override
- protected @Nullable String flavor(
- LibertyRequest libertyRequest, @Nullable LibertyResponse libertyResponse) {
+ protected @Nullable String flavor(LibertyRequest libertyRequest) {
String flavor = libertyRequest.getProtocol();
if (flavor != null) {
// remove HTTP/ prefix to comply with semantic conventions

MODIFY
instrumentation/ratpack-1.4/library/src/main/java/io/opentelemetry/instrumentation/ratpack/RatpackHttpAttributesExtractor.java
instrumentation/ratpack-1.4/library/src/main/java/io/opentelemetry/instrumentation/ratpack/RatpackHttpAttributesExtractor.java
@@ -83,7 +83,7 @@ final class RatpackHttpAttributesExtractor
@Override
@Nullable
- protected String flavor(Request request, @Nullable Response response) {
+ protected String flavor(Request request) {
switch (request.getProtocol()) {
case "HTTP/1.0":
return SemanticAttributes.HttpFlavorValues.HTTP_1_0;

MODIFY
instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java
instrumentation/restlet/restlet-1.0/library/src/main/java/io/opentelemetry/instrumentation/restlet/v1_0/RestletHttpAttributesExtractor.java
@@ -60,7 +60,7 @@ final class RestletHttpAttributesExtractor
}
@Override
- protected @Nullable String flavor(Request request, @Nullable Response response) {
+ protected @Nullable String flavor(Request request) {
String version = (String) request.getAttributes().get("org.restlet.http.version");
switch (version) {
case "HTTP/1.0":

MODIFY
instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletHttpAttributesExtractor.java
instrumentation/servlet/servlet-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/servlet/ServletHttpAttributesExtractor.java
@@ -71,9 +71,7 @@ public class ServletHttpAttributesExtractor<REQUEST, RESPONSE>
}
@Override
- protected @Nullable String flavor(
- ServletRequestContext<REQUEST> requestContext,
- @Nullable ServletResponseContext<RESPONSE> responseContext) {
+ protected @Nullable String flavor(ServletRequestContext<REQUEST> requestContext) {
String flavor = accessor.getRequestProtocol(requestContext.request());
if (flavor != null) {
// remove HTTP/ prefix to comply with semantic conventions

MODIFY
instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcHttpAttributesExtractor.java
instrumentation/spring/spring-webmvc-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/webmvc/SpringWebMvcHttpAttributesExtractor.java
@@ -35,8 +35,7 @@ final class SpringWebMvcHttpAttributesExtractor
}
@Override
- protected @Nullable String flavor(
- HttpServletRequest request, @Nullable HttpServletResponse response) {
+ protected @Nullable String flavor(HttpServletRequest request) {
return request.getProtocol();
}

MODIFY
instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatHttpAttributesExtractor.java
instrumentation/tomcat/tomcat-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/tomcat/common/TomcatHttpAttributesExtractor.java
@@ -61,7 +61,7 @@ public class TomcatHttpAttributesExtractor
}
@Override
- protected @Nullable String flavor(Request request, @Nullable Response response) {
+ protected @Nullable String flavor(Request request) {
String flavor = request.protocol().toString();
if (flavor != null) {
// remove HTTP/ prefix to comply with semantic conventions

MODIFY
instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttpAttributesExtractor.java
instrumentation/undertow-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/undertow/UndertowHttpAttributesExtractor.java
@@ -36,7 +36,7 @@ public class UndertowHttpAttributesExtractor
}
@Override
- protected String flavor(HttpServerExchange exchange, @Nullable HttpServerExchange unused) {
+ protected String flavor(HttpServerExchange exchange) {
String flavor = exchange.getProtocol().toString();
// remove HTTP/ prefix to comply with semantic conventions
if (flavor.startsWith("HTTP/")) {

Flavor extractor (#4274)