Stable semconv final (?) polishing, JavaDoc updates, minor changes (#9815)

This commit is contained in:
Mateusz Rzeszutek 2023-11-07 17:10:36 +01:00 committed by GitHub
parent 020e4abbf0
commit 33275b1522
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 235 additions and 145 deletions

View File

@ -10,6 +10,7 @@ import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorU
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.internal.HttpAttributes;
import io.opentelemetry.instrumentation.api.instrumenter.net.internal.InternalNetClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalNetworkAttributesExtractor;
@ -23,19 +24,19 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client">HTTP
* client attributes</a>. Instrumentation of HTTP client frameworks should extend this class,
* defining {@link REQUEST} and {@link RESPONSE} with the actual request / response types of the
* instrumented library. If an attribute is not available in this library, it is appropriate to
* return {@code null} from the protected attribute methods, but implement as many as possible for
* best compliance with the OpenTelemetry specification.
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-client">HTTP
* client attributes</a>.
*/
public final class HttpClientAttributesExtractor<REQUEST, RESPONSE>
extends HttpCommonAttributesExtractor<
REQUEST, RESPONSE, HttpClientAttributesGetter<REQUEST, RESPONSE>>
implements SpanKeyProvider {
/** Creates the HTTP client attributes extractor with default configuration. */
/**
* Creates the HTTP client attributes extractor with default configuration.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> AttributesExtractor<REQUEST, RESPONSE> create(
HttpClientAttributesGetter<REQUEST, RESPONSE> httpAttributesGetter) {
return builder(httpAttributesGetter).build();

View File

@ -10,6 +10,7 @@ import static java.util.Collections.emptyList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.net.internal.InternalNetClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.AddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalNetworkAttributesExtractor;
@ -54,12 +55,11 @@ public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> {
/**
* Configures the HTTP request headers that will be captured as span attributes as described in <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-client">HTTP
* semantic conventions</a>.
*
* <p>The HTTP request header values will be captured under the {@code http.request.header.<name>}
* attribute key. The {@code <name>} part in the attribute key is the normalized header name:
* lowercase, with dashes replaced by underscores.
* <p>The HTTP request header values will be captured under the {@code http.request.header.<key>}
* attribute key. The {@code <key>} part in the attribute key is the lowercase header name.
*
* @param requestHeaders A list of HTTP header names.
*/
@ -73,12 +73,12 @@ public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> {
/**
* Configures the HTTP response headers that will be captured as span attributes as described in
* <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes">HTTP
* semantic conventions</a>.
*
* <p>The HTTP response header values will be captured under the {@code
* http.response.header.<name>} attribute key. The {@code <name>} part in the attribute key is the
* normalized header name: lowercase, with dashes replaced by underscores.
* http.response.header.<key>} attribute key. The {@code <key>} part in the attribute key is the
* lowercase header name.
*
* @param responseHeaders A list of HTTP header names.
*/
@ -122,6 +122,8 @@ public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> {
/**
* Returns a new {@link HttpClientAttributesExtractor} with the settings of this {@link
* HttpClientAttributesExtractorBuilder}.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public AttributesExtractor<REQUEST, RESPONSE> build() {
return new HttpClientAttributesExtractor<>(this);

View File

@ -15,6 +15,7 @@ import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
@ -24,7 +25,7 @@ import javax.annotation.Nullable;
/**
* {@link OperationListener} which keeps track of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-client">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-client">HTTP
* client metrics</a>.
*/
public final class HttpClientMetrics implements OperationListener {
@ -38,9 +39,10 @@ public final class HttpClientMetrics implements OperationListener {
private static final Logger logger = Logger.getLogger(HttpClientMetrics.class.getName());
/**
* Returns a {@link OperationMetrics} which can be used to enable recording of {@link
* HttpClientMetrics} on an {@link
* io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder}.
* Returns an {@link OperationMetrics} instance which can be used to enable recording of {@link
* HttpClientMetrics}.
*
* @see InstrumenterBuilder#addOperationMetrics(OperationMetrics)
*/
public static OperationMetrics get() {
return HttpClientMetrics::new;

View File

@ -28,7 +28,7 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes">HTTP
* attributes</a> that are common to client and server instrumentations.
*/
abstract class HttpCommonAttributesExtractor<

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
import java.util.List;
import javax.annotation.Nullable;
@ -61,13 +62,13 @@ public interface HttpCommonAttributesGetter<REQUEST, RESPONSE> {
* received.
*
* <p>If this method is not implemented, or if it returns {@code null}, the exception class name
* (if any was caught) or the value {@code _OTHER} will be used as error type.
* (if any was caught) or the value {@value HttpConstants#_OTHER} will be used as error type.
*
* <p>The cardinality of the error type should be low. The instrumentations implementing this
* method are recommended to document the custom values they support.
*
* <p>Examples: {@code Bad Request}, {@code java.net.UnknownHostException}, {@code request
* cancelled}, {@code _OTHER}.
* <p>Examples: {@code timeout}, {@code java.net.UnknownHostException}, {@code
* server_certificate_invalid}, {@code 500}, {@code _OTHER}.
*/
@Nullable
default String getErrorType(

View File

@ -151,7 +151,7 @@ final class HttpMetricsAdvice {
SemanticAttributes.HTTP_SCHEME,
SemanticAttributes.NET_HOST_NAME,
SemanticAttributes.NET_HOST_PORT,
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpserveractive_requests
// https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#metric-httpserveractive_requests
SemanticAttributes.HTTP_REQUEST_METHOD,
SemanticAttributes.URL_SCHEME));
}

View File

@ -10,6 +10,7 @@ import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorU
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.net.internal.InternalNetServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalNetworkAttributesExtractor;
@ -23,19 +24,19 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-server">HTTP
* server attributes</a>. Instrumentation of HTTP server frameworks should extend this class,
* defining {@link REQUEST} and {@link RESPONSE} with the actual request / response types of the
* instrumented library. If an attribute is not available in this library, it is appropriate to
* return {@code null} from the protected attribute methods, but implement as many as possible for
* best compliance with the OpenTelemetry specification.
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-server">HTTP
* server attributes</a>.
*/
public final class HttpServerAttributesExtractor<REQUEST, RESPONSE>
extends HttpCommonAttributesExtractor<
REQUEST, RESPONSE, HttpServerAttributesGetter<REQUEST, RESPONSE>>
implements SpanKeyProvider {
/** Creates the HTTP server attributes extractor with default configuration. */
/**
* Creates the HTTP server attributes extractor with default configuration.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> AttributesExtractor<REQUEST, RESPONSE> create(
HttpServerAttributesGetter<REQUEST, RESPONSE> httpAttributesGetter) {
return builder(httpAttributesGetter).build();

View File

@ -10,6 +10,7 @@ import static java.util.Collections.emptyList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.net.internal.InternalNetServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.AddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.ClientAddressAndPortExtractor;
@ -58,13 +59,13 @@ public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
}
/**
* Configures the HTTP request headers that will be captured as span attributes as described in <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes">HTTP
* Configures the HTTP response headers that will be captured as span attributes as described in
* <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#http-server-semantic-conventions">HTTP
* semantic conventions</a>.
*
* <p>The HTTP request header values will be captured under the {@code http.request.header.<name>}
* attribute key. The {@code <name>} part in the attribute key is the normalized header name:
* lowercase, with dashes replaced by underscores.
* <p>The HTTP request header values will be captured under the {@code http.request.header.<key>}
* attribute key. The {@code <key>} part in the attribute key is the lowercase header name.
*
* @param requestHeaders A list of HTTP header names.
*/
@ -78,12 +79,12 @@ public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
/**
* Configures the HTTP response headers that will be captured as span attributes as described in
* <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes">HTTP
* semantic conventions</a>.
*
* <p>The HTTP response header values will be captured under the {@code
* http.response.header.<name>} attribute key. The {@code <name>} part in the attribute key is the
* normalized header name: lowercase, with dashes replaced by underscores.
* http.response.header.<key>} attribute key. The {@code <key>} part in the attribute key is the
* lowercase header name.
*
* @param responseHeaders A list of HTTP header names.
*/
@ -127,6 +128,8 @@ public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
/**
* Returns a new {@link HttpServerAttributesExtractor} with the settings of this {@link
* HttpServerAttributesExtractorBuilder}.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public AttributesExtractor<REQUEST, RESPONSE> build() {
return new HttpServerAttributesExtractor<>(this);

View File

@ -47,8 +47,8 @@ public interface HttpServerAttributesGetter<REQUEST, RESPONSE>
String getUrlQuery(REQUEST request);
/**
* Returns the matched route (path template in the format used by the respective server
* framework).
* Returns the matched route, that is, the path template in the format used by the respective
* server framework.
*
* <p>Examples: {@code /users/:userID?}, {@code {controller}/{action}/{id?}}
*/

View File

@ -15,6 +15,7 @@ import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
@ -24,7 +25,7 @@ import javax.annotation.Nullable;
/**
* {@link OperationListener} which keeps track of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server">HTTP
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server">HTTP
* server metrics</a>.
*/
public final class HttpServerMetrics implements OperationListener {
@ -38,9 +39,10 @@ public final class HttpServerMetrics implements OperationListener {
private static final Logger logger = Logger.getLogger(HttpServerMetrics.class.getName());
/**
* Returns a {@link OperationMetrics} which can be used to enable recording of {@link
* HttpServerMetrics} on an {@link
* io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder}.
* Returns an {@link OperationMetrics} instance which can be used to enable recording of {@link
* HttpServerMetrics}.
*
* @see InstrumenterBuilder#addOperationMetrics(OperationMetrics)
*/
public static OperationMetrics get() {
return HttpServerMetrics::new;

View File

@ -9,9 +9,9 @@ import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.LocalRootSpan;
import io.opentelemetry.instrumentation.api.internal.HttpRouteState;
import io.opentelemetry.semconv.SemanticAttributes;
import javax.annotation.Nullable;
/**
@ -28,6 +28,8 @@ public final class HttpServerRoute {
/**
* Returns a {@link ContextCustomizer} that initializes an {@link HttpServerRoute} in the {@link
* Context} returned from {@link Instrumenter#start(Context, Object)}.
*
* @see InstrumenterBuilder#addContextCustomizer(ContextCustomizer)
*/
public static <REQUEST> ContextCustomizer<REQUEST> create(
HttpServerAttributesGetter<REQUEST, ?> getter) {
@ -53,10 +55,6 @@ public final class HttpServerRoute {
* if and only if the last {@link HttpServerRouteSource} to update the route using this method has
* strictly lower priority than the provided {@link HttpServerRouteSource}, and the passed value
* is non-null.
*
* <p>If there is a server span in the context, and the context has NOT been customized with a
* {@link HttpServerRoute}, then this method will update the route using the provided value if it
* is non-null.
*/
public static void update(
Context context, HttpServerRouteSource source, @Nullable String httpRoute) {
@ -72,10 +70,6 @@ public final class HttpServerRoute {
* route using this method has strictly lower priority than the provided {@link
* HttpServerRouteSource}, and the value returned from the {@link HttpServerRouteGetter} is
* non-null.
*
* <p>If there is a server span in the context, and the context has NOT been customized with a
* {@link HttpServerRoute}, then this method will update the route using the provided {@link
* HttpServerRouteGetter} if the value returned from it is non-null.
*/
public static <T> void update(
Context context,
@ -94,10 +88,6 @@ public final class HttpServerRoute {
* route using this method has strictly lower priority than the provided {@link
* HttpServerRouteSource}, and the value returned from the {@link HttpServerRouteBiGetter} is
* non-null.
*
* <p>If there is a server span in the context, and the context has NOT been customized with a
* {@code ServerSpanName}, then this method will update the route using the provided {@link
* HttpServerRouteBiGetter} if the value returned from it is non-null.
*/
public static <T, U> void update(
Context context,
@ -113,12 +103,6 @@ public final class HttpServerRoute {
}
HttpRouteState httpRouteState = HttpRouteState.fromContextOrNull(context);
if (httpRouteState == null) {
// TODO: remove this branch?
String httpRoute = httpRouteGetter.get(context, arg1, arg2);
if (httpRoute != null && !httpRoute.isEmpty()) {
// update just the attribute - without http.method we can't compute a proper span name here
serverSpan.setAttribute(SemanticAttributes.HTTP_ROUTE, httpRoute);
}
return;
}
// special case for servlet filters, even when we have a route from previous filter see whether

View File

@ -9,12 +9,13 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
import io.opentelemetry.instrumentation.api.internal.HttpRouteState;
import java.util.HashSet;
import java.util.Set;
/** A builder of {@link HttpSpanNameExtractor}. */
/** A builder of {@link HttpServerRoute}. */
public final class HttpServerRouteBuilder<REQUEST> {
final HttpServerAttributesGetter<REQUEST, ?> getter;
@ -48,6 +49,8 @@ public final class HttpServerRouteBuilder<REQUEST> {
* Returns a {@link ContextCustomizer} that initializes an {@link HttpServerRoute} in the {@link
* Context} returned from {@link Instrumenter#start(Context, Object)}. The returned customizer is
* configured with the settings of this {@link HttpServerRouteBuilder}.
*
* @see InstrumenterBuilder#addContextCustomizer(ContextCustomizer)
*/
public ContextCustomizer<REQUEST> build() {
Set<String> knownMethods = new HashSet<>(this.knownMethods);

View File

@ -25,7 +25,7 @@ public enum HttpServerRouteSource {
* annotated sub-resource method. Since multiple nested controllers may match the same request,
* the one with the longest (most detailed) route will be chosen.
*/
NESTED_CONTROLLER(4, false);
NESTED_CONTROLLER(4, /* useFirst= */ false);
final int order;
final boolean useFirst;

View File

@ -5,63 +5,99 @@
package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
/**
* Extractor of the <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#name">HTTP
* span name</a>. Instrumentation of HTTP server or client frameworks should use this class to
* comply with OpenTelemetry HTTP semantic conventions.
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#name">HTTP
* span name</a>.
*/
public final class HttpSpanNameExtractor<REQUEST> implements SpanNameExtractor<REQUEST> {
public final class HttpSpanNameExtractor {
/**
* Returns a {@link SpanNameExtractor} which should be used for HTTP requests with default
* configuration. HTTP attributes will be examined to determine the name of the span.
* Returns an HTTP client {@link SpanNameExtractor} with default configuration.
*
* @see Instrumenter#builder(OpenTelemetry, String, SpanNameExtractor)
*/
public static <REQUEST> SpanNameExtractor<REQUEST> create(
HttpCommonAttributesGetter<REQUEST, ?> getter) {
HttpClientAttributesGetter<REQUEST, ?> getter) {
return builder(getter).build();
}
/**
* Returns a new {@link HttpSpanNameExtractorBuilder} that can be used to configure the HTTP span
* name extractor.
* Returns an HTTP server {@link SpanNameExtractor} with default configuration.
*
* @see Instrumenter#builder(OpenTelemetry, String, SpanNameExtractor)
*/
public static <REQUEST> HttpSpanNameExtractorBuilder<REQUEST> builder(
HttpCommonAttributesGetter<REQUEST, ?> getter) {
return new HttpSpanNameExtractorBuilder<>(getter);
public static <REQUEST> SpanNameExtractor<REQUEST> create(
HttpServerAttributesGetter<REQUEST, ?> getter) {
return builder(getter).build();
}
private final HttpCommonAttributesGetter<REQUEST, ?> getter;
/**
* Returns a new {@link HttpSpanNameExtractorBuilder} that can be used to configure the HTTP
* client span name extractor.
*/
public static <REQUEST> HttpSpanNameExtractorBuilder<REQUEST> builder(
HttpClientAttributesGetter<REQUEST, ?> getter) {
return new HttpSpanNameExtractorBuilder<>(getter, null);
}
/**
* Returns a new {@link HttpSpanNameExtractorBuilder} that can be used to configure the HTTP
* server span name extractor.
*/
public static <REQUEST> HttpSpanNameExtractorBuilder<REQUEST> builder(
HttpServerAttributesGetter<REQUEST, ?> getter) {
return new HttpSpanNameExtractorBuilder<>(null, getter);
}
static final class Client<REQUEST> implements SpanNameExtractor<REQUEST> {
private final HttpClientAttributesGetter<REQUEST, ?> getter;
private final Set<String> knownMethods;
HttpSpanNameExtractor(HttpSpanNameExtractorBuilder<REQUEST> builder) {
this.getter = builder.httpAttributesGetter;
this.knownMethods = new HashSet<>(builder.knownMethods);
Client(HttpClientAttributesGetter<REQUEST, ?> getter, Set<String> knownMethods) {
this.getter = getter;
this.knownMethods = knownMethods;
}
@Override
public String extract(REQUEST request) {
String method = getter.getHttpRequestMethod(request);
String route = extractRoute(request);
if (method != null) {
if (method == null || !knownMethods.contains(method)) {
return "HTTP";
}
return method;
}
}
static final class Server<REQUEST> implements SpanNameExtractor<REQUEST> {
private final HttpServerAttributesGetter<REQUEST, ?> getter;
private final Set<String> knownMethods;
Server(HttpServerAttributesGetter<REQUEST, ?> getter, Set<String> knownMethods) {
this.getter = getter;
this.knownMethods = knownMethods;
}
@Override
public String extract(REQUEST request) {
String method = getter.getHttpRequestMethod(request);
String route = getter.getHttpRoute(request);
if (method == null) {
return "HTTP";
}
if (!knownMethods.contains(method)) {
method = "HTTP";
}
return route == null ? method : method + " " + route;
}
return "HTTP";
}
@Nullable
private String extractRoute(REQUEST request) {
if (getter instanceof HttpServerAttributesGetter) {
return ((HttpServerAttributesGetter<REQUEST, ?>) getter).getHttpRoute(request);
}
return null;
}
private HttpSpanNameExtractor() {}
}

View File

@ -5,20 +5,29 @@
package io.opentelemetry.instrumentation.api.instrumenter.http;
import static java.util.Objects.requireNonNull;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nullable;
/** A builder of {@link HttpSpanNameExtractor}. */
public final class HttpSpanNameExtractorBuilder<REQUEST> {
final HttpCommonAttributesGetter<REQUEST, ?> httpAttributesGetter;
@Nullable final HttpClientAttributesGetter<REQUEST, ?> clientGetter;
@Nullable final HttpServerAttributesGetter<REQUEST, ?> serverGetter;
Set<String> knownMethods = HttpConstants.KNOWN_METHODS;
HttpSpanNameExtractorBuilder(HttpCommonAttributesGetter<REQUEST, ?> httpAttributesGetter) {
this.httpAttributesGetter = httpAttributesGetter;
public HttpSpanNameExtractorBuilder(
@Nullable HttpClientAttributesGetter<REQUEST, ?> clientGetter,
@Nullable HttpServerAttributesGetter<REQUEST, ?> serverGetter) {
this.clientGetter = clientGetter;
this.serverGetter = serverGetter;
}
/**
@ -45,8 +54,13 @@ public final class HttpSpanNameExtractorBuilder<REQUEST> {
/**
* Returns a new {@link HttpSpanNameExtractor} with the settings of this {@link
* HttpSpanNameExtractorBuilder}.
*
* @see Instrumenter#builder(OpenTelemetry, String, SpanNameExtractor)
*/
public SpanNameExtractor<REQUEST> build() {
return new HttpSpanNameExtractor<>(this);
Set<String> knownMethods = new HashSet<>(this.knownMethods);
return clientGetter != null
? new HttpSpanNameExtractor.Client<>(clientGetter, knownMethods)
: new HttpSpanNameExtractor.Server<>(requireNonNull(serverGetter), knownMethods);
}
}

View File

@ -6,23 +6,25 @@
package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
import javax.annotation.Nullable;
/**
* Extractor of the <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#status">HTTP
* span status</a>. Instrumentation of HTTP server or client frameworks should use this class to
* comply with OpenTelemetry HTTP semantic conventions.
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#status">HTTP
* span status</a>.
*/
public final class HttpSpanStatusExtractor<REQUEST, RESPONSE>
implements SpanStatusExtractor<REQUEST, RESPONSE> {
/**
* Returns the {@link SpanStatusExtractor} for HTTP requests, which will use the HTTP status code
* to determine the {@link StatusCode} if available or fallback to {@linkplain #getDefault() the
* Returns the HTTP client {@link SpanStatusExtractor}, which will use the HTTP status code to
* determine the {@link StatusCode} if available or fallback to {@linkplain #getDefault() the
* default status} otherwise.
*
* @see InstrumenterBuilder#setSpanStatusExtractor(SpanStatusExtractor)
*/
public static <REQUEST, RESPONSE> SpanStatusExtractor<REQUEST, RESPONSE> create(
HttpClientAttributesGetter<? super REQUEST, ? super RESPONSE> getter) {
@ -30,9 +32,11 @@ public final class HttpSpanStatusExtractor<REQUEST, RESPONSE>
}
/**
* Returns the {@link SpanStatusExtractor} for HTTP requests, which will use the HTTP status code
* to determine the {@link StatusCode} if available or fallback to {@linkplain #getDefault() the
* Returns the HTTP server {@link SpanStatusExtractor}, which will use the HTTP status code to
* determine the {@link StatusCode} if available or fallback to {@linkplain #getDefault() the
* default status} otherwise.
*
* @see InstrumenterBuilder#setSpanStatusExtractor(SpanStatusExtractor)
*/
public static <REQUEST, RESPONSE> SpanStatusExtractor<REQUEST, RESPONSE> create(
HttpServerAttributesGetter<? super REQUEST, ? super RESPONSE> getter) {

View File

@ -0,0 +1,9 @@
/**
* This module contains the implementation of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/README.md">the
* OpenTelemetry HTTP semantic conventions</a>.
*/
@ParametersAreNonnullByDefault
package io.opentelemetry.instrumentation.api.instrumenter.http;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.network;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.AddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.ClientAddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalClientAttributesExtractor;
@ -16,15 +17,16 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/trace/semantic_conventions/span-general.md#client-attributes">client
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#client-attributes">client
* attributes</a>.
*/
public final class ClientAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<REQUEST, RESPONSE> {
/**
* Returns a new {@link ClientAttributesExtractor} that will use the passed {@link
* ClientAttributesGetter}.
* Creates the client attributes extractor.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> ClientAttributesExtractor<REQUEST, RESPONSE> create(
ClientAttributesGetter<REQUEST, RESPONSE> getter) {

View File

@ -19,9 +19,10 @@ import javax.annotation.Nullable;
public interface ClientAttributesGetter<REQUEST, RESPONSE> {
/**
* Returns the client address - unix domain socket name, IPv4 or IPv6 address.
* Returns the client address - domain name if available without reverse DNS lookup; otherwise, IP
* address or Unix domain socket name.
*
* <p>Examples: {@code /tmp/my.sock}, {@code 10.1.2.80}
* <p>Examples: {@code client.example.com}, {@code 10.1.2.80}, {@code /tmp/my.sock}
*/
@Nullable
default String getClientAddress(REQUEST request) {

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.network;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.AddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalNetworkAttributesExtractor;
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
@ -15,15 +16,16 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/trace/semantic_conventions/span-general.md#network-attributes">network
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#other-network-attributes">network
* attributes</a>.
*/
public final class NetworkAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<REQUEST, RESPONSE> {
/**
* Returns a new {@link NetworkAttributesExtractor} that will use the passed {@link
* NetworkAttributesGetter}.
* Creates the network attributes extractor.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> NetworkAttributesExtractor<REQUEST, RESPONSE> create(
NetworkAttributesGetter<REQUEST, RESPONSE> getter) {

View File

@ -19,19 +19,7 @@ import javax.annotation.Nullable;
public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
/**
* Returns the <a href="https://osi-model.com/transport-layer/">OSI Transport Layer</a> or <a
* href="https://en.wikipedia.org/wiki/Inter-process_communication">Inter-process Communication
* method</a>.
*
* <p>Examples: {@code tcp}, {@code udp}
*/
@Nullable
default String getNetworkTransport(REQUEST request, @Nullable RESPONSE response) {
return null;
}
/**
* Returns the <a href="https://osi-model.com/network-layer/">OSI Network Layer</a> or non-OSI
* Returns the <a href="https://osi-model.com/network-layer/">OSI network layer</a> or non-OSI
* equivalent.
*
* <p>Examples: {@code ipv4}, {@code ipv6}
@ -44,7 +32,19 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
}
/**
* Returns the <a href="https://osi-model.com/application-layer/">OSI Application Layer</a> or
* Returns the <a href="https://osi-model.com/transport-layer/">OSI transport layer</a> or <a
* href="https://en.wikipedia.org/wiki/Inter-process_communication">inter-process communication
* method</a>.
*
* <p>Examples: {@code tcp}, {@code udp}
*/
@Nullable
default String getNetworkTransport(REQUEST request, @Nullable RESPONSE response) {
return null;
}
/**
* Returns the <a href="https://osi-model.com/application-layer/">OSI application layer</a> or
* non-OSI equivalent.
*
* <p>Examples: {@code ampq}, {@code http}, {@code mqtt}
@ -55,7 +55,8 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
}
/**
* Returns the version of the application layer protocol used.
* Returns the version of the protocol returned by {@link #getNetworkProtocolName(Object,
* Object)}.
*
* <p>Examples: {@code 3.1.1}
*/
@ -82,7 +83,7 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
* <p>Examples: {@code 10.1.2.80}, {@code /tmp/my.sock}
*
* <p>By default, this method attempts to retrieve the local address using the {@link
* #getNetworkLocalInetSocketAddress(Object, Object)} method. If this method is not implemented,
* #getNetworkLocalInetSocketAddress(Object, Object)} method. If that method is not implemented,
* it will simply return {@code null}. If the instrumented library does not expose {@link
* InetSocketAddress} in its API, you might want to implement this method instead of {@link
* #getNetworkLocalInetSocketAddress(Object, Object)}.
@ -98,7 +99,7 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
* <p>Examples: {@code 65123}
*
* <p>By default, this method attempts to retrieve the local port using the {@link
* #getNetworkLocalInetSocketAddress(Object, Object)} method. If this method is not implemented,
* #getNetworkLocalInetSocketAddress(Object, Object)} method. If that method is not implemented,
* it will simply return {@code null}. If the instrumented library does not expose {@link
* InetSocketAddress} in its API, you might want to implement this method instead of {@link
* #getNetworkLocalInetSocketAddress(Object, Object)}.
@ -126,7 +127,7 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
* <p>Examples: {@code 10.1.2.80}, {@code /tmp/my.sock}
*
* <p>By default, this method attempts to retrieve the peer address using the {@link
* #getNetworkPeerInetSocketAddress(Object, Object)} method. If this method is not implemented, it
* #getNetworkPeerInetSocketAddress(Object, Object)} method. If that method is not implemented, it
* will simply return {@code null}. If the instrumented library does not expose {@link
* InetSocketAddress} in its API, you might want to implement this method instead of {@link
* #getNetworkPeerInetSocketAddress(Object, Object)}.
@ -142,7 +143,7 @@ public interface NetworkAttributesGetter<REQUEST, RESPONSE> {
* <p>Examples: {@code 65123}
*
* <p>By default, this method attempts to retrieve the peer port using the {@link
* #getNetworkPeerInetSocketAddress(Object, Object)} method. If this method is not implemented, it
* #getNetworkPeerInetSocketAddress(Object, Object)} method. If that method is not implemented, it
* will simply return {@code null}. If the instrumented library does not expose {@link
* InetSocketAddress} in its API, you might want to implement this method instead of {@link
* #getNetworkPeerInetSocketAddress(Object, Object)}.

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.instrumenter.network;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.AddressAndPortExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.InternalServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.network.internal.ServerAddressAndPortExtractor;
@ -16,15 +17,16 @@ import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/main/specification/trace/semantic_conventions/span-general.md#server-attributes">server
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#server-attributes">server
* attributes</a>.
*/
public final class ServerAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<REQUEST, RESPONSE> {
/**
* Returns a new {@link ServerAttributesExtractor} that will use the passed {@link
* ServerAttributesGetter}.
* Creates the server attributes extractor.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> ServerAttributesExtractor<REQUEST, RESPONSE> create(
ServerAttributesGetter<REQUEST, RESPONSE> getter) {

View File

@ -19,10 +19,10 @@ import javax.annotation.Nullable;
public interface ServerAttributesGetter<REQUEST, RESPONSE> {
/**
* Return the logical server hostname that matches server FQDN if available, and IP or socket
* address if FQDN is not known.
* Returns the server domain name if available without reverse DNS lookup; otherwise, IP address
* or Unix domain socket name.
*
* <p>Examples: {@code example.com}
* <p>Examples: {@code client.example.com}, {@code 10.1.2.80}, {@code /tmp/my.sock}
*/
@Nullable
default String getServerAddress(REQUEST request) {
@ -30,7 +30,7 @@ public interface ServerAttributesGetter<REQUEST, RESPONSE> {
}
/**
* Return the logical server port number.
* Return the server port number.
*
* <p>Examples: {@code 80}, {@code 8080}, {@code 443}
*/

View File

@ -0,0 +1,9 @@
/**
* This module contains the implementation of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#server-client-and-shared-network-attributes">the
* OpenTelemetry server, client and shared network attributes semantic conventions</a>.
*/
@ParametersAreNonnullByDefault
package io.opentelemetry.instrumentation.api.instrumenter.network;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -8,20 +8,22 @@ package io.opentelemetry.instrumentation.api.instrumenter.url;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.url.internal.InternalUrlAttributesExtractor;
import javax.annotation.Nullable;
/**
* Extractor of <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/url.md#attributes">URL
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/url/url.md">URL
* attributes</a>.
*/
public final class UrlAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<REQUEST, RESPONSE> {
/**
* Returns a new {@link UrlAttributesExtractor} that will use the passed {@link
* UrlAttributesGetter}.
* Creates the URL attributes extractor.
*
* @see InstrumenterBuilder#addAttributesExtractor(AttributesExtractor)
*/
public static <REQUEST, RESPONSE> UrlAttributesExtractor<REQUEST, RESPONSE> create(
UrlAttributesGetter<REQUEST> getter) {

View File

@ -0,0 +1,9 @@
/**
* This module contains the implementation of <a
* href="https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/url/url.md">the
* OpenTelemetry URL semantic conventions</a>.
*/
@ParametersAreNonnullByDefault
package io.opentelemetry.instrumentation.api.instrumenter.url;
import javax.annotation.ParametersAreNonnullByDefault;