Deprecate CapturedHttpHeaders and replace it with builder methods (#5533)

This commit is contained in:
Mateusz Rzeszutek 2022-03-09 21:21:32 +01:00 committed by GitHub
parent c461d22d83
commit f6cca58f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 623 additions and 227 deletions

View File

@ -7,7 +7,6 @@ package io.opentelemetry.instrumentation.api.instrumenter;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesGetter; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesGetter;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
@ -43,9 +42,7 @@ public class InstrumenterBenchmark {
"benchmark", "benchmark",
HttpSpanNameExtractor.create(ConstantHttpAttributesGetter.INSTANCE)) HttpSpanNameExtractor.create(ConstantHttpAttributesGetter.INSTANCE))
.addAttributesExtractor( .addAttributesExtractor(
HttpClientAttributesExtractor.builder(ConstantHttpAttributesGetter.INSTANCE) HttpClientAttributesExtractor.create(ConstantHttpAttributesGetter.INSTANCE))
.captureHttpHeaders(CapturedHttpHeaders.empty())
.build())
.addAttributesExtractor( .addAttributesExtractor(
NetServerAttributesExtractor.create(new ConstantNetAttributesGetter())) NetServerAttributesExtractor.create(new ConstantNetAttributesGetter()))
.newInstrumenter(); .newInstrumenter();

View File

@ -23,8 +23,16 @@ import java.util.stream.Collectors;
* attribute key. The HTTP response header values will be captured under the {@code * attribute key. 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 * 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. * normalized header name: lowercase, with dashes replaced by underscores.
*
* @deprecated This class should no longer be used directly. Use the {@link
* HttpClientAttributesExtractorBuilder#setCapturedRequestHeaders(List)}, {@link
* HttpClientAttributesExtractorBuilder#setCapturedResponseHeaders(List)}, {@link
* HttpServerAttributesExtractorBuilder#setCapturedRequestHeaders(List)} and {@link
* HttpServerAttributesExtractorBuilder#setCapturedResponseHeaders(List)} methods instead.
*/ */
@Deprecated
@AutoValue @AutoValue
@AutoValue.CopyAnnotations
public abstract class CapturedHttpHeaders { public abstract class CapturedHttpHeaders {
private static final CapturedHttpHeaders EMPTY = create(emptyList(), emptyList()); private static final CapturedHttpHeaders EMPTY = create(emptyList(), emptyList());

View File

@ -19,6 +19,7 @@ import javax.annotation.Nullable;
* return {@code null} from the protected attribute methods, but implement as many as possible for * return {@code null} from the protected attribute methods, but implement as many as possible for
* best compliance with the OpenTelemetry specification. * best compliance with the OpenTelemetry specification.
*/ */
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
public final class HttpClientAttributesExtractor<REQUEST, RESPONSE> public final class HttpClientAttributesExtractor<REQUEST, RESPONSE>
extends HttpCommonAttributesExtractor< extends HttpCommonAttributesExtractor<
REQUEST, RESPONSE, HttpClientAttributesGetter<REQUEST, RESPONSE>> { REQUEST, RESPONSE, HttpClientAttributesGetter<REQUEST, RESPONSE>> {

View File

@ -6,8 +6,10 @@
package io.opentelemetry.instrumentation.api.instrumenter.http; package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.instrumentation.api.config.Config; import io.opentelemetry.instrumentation.api.config.Config;
import java.util.List;
/** A builder of {@link HttpClientAttributesExtractor}. */ /** A builder of {@link HttpClientAttributesExtractor}. */
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> { public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> {
final HttpClientAttributesGetter<REQUEST, RESPONSE> getter; final HttpClientAttributesGetter<REQUEST, RESPONSE> getter;
@ -22,13 +24,40 @@ public final class HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> {
* *
* @param capturedHttpHeaders A configuration object specifying which HTTP request and response * @param capturedHttpHeaders A configuration object specifying which HTTP request and response
* headers should be captured as span attributes. * headers should be captured as span attributes.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
@Deprecated
public HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> captureHttpHeaders( public HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> captureHttpHeaders(
CapturedHttpHeaders capturedHttpHeaders) { CapturedHttpHeaders capturedHttpHeaders) {
this.capturedHttpHeaders = capturedHttpHeaders; this.capturedHttpHeaders = capturedHttpHeaders;
return this; return this;
} }
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> setCapturedRequestHeaders(
List<String> requestHeaders) {
this.capturedHttpHeaders =
CapturedHttpHeaders.create(requestHeaders, capturedHttpHeaders.responseHeaders());
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE> setCapturedResponseHeaders(
List<String> responseHeaders) {
this.capturedHttpHeaders =
CapturedHttpHeaders.create(capturedHttpHeaders.requestHeaders(), responseHeaders);
return this;
}
/** /**
* Returns a new {@link HttpClientAttributesExtractor} with the settings of this {@link * Returns a new {@link HttpClientAttributesExtractor} with the settings of this {@link
* HttpClientAttributesExtractorBuilder}. * HttpClientAttributesExtractorBuilder}.

View File

@ -20,6 +20,7 @@ import javax.annotation.Nullable;
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#common-attributes">HTTP * href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#common-attributes">HTTP
* attributes</a> that are common to client and server instrumentations. * attributes</a> that are common to client and server instrumentations.
*/ */
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
abstract class HttpCommonAttributesExtractor< abstract class HttpCommonAttributesExtractor<
REQUEST, RESPONSE, GETTER extends HttpCommonAttributesGetter<REQUEST, RESPONSE>> REQUEST, RESPONSE, GETTER extends HttpCommonAttributesGetter<REQUEST, RESPONSE>>
implements AttributesExtractor<REQUEST, RESPONSE> { implements AttributesExtractor<REQUEST, RESPONSE> {

View File

@ -25,6 +25,7 @@ import javax.annotation.Nullable;
* return {@code null} from the protected attribute methods, but implement as many as possible for * return {@code null} from the protected attribute methods, but implement as many as possible for
* best compliance with the OpenTelemetry specification. * best compliance with the OpenTelemetry specification.
*/ */
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
public final class HttpServerAttributesExtractor<REQUEST, RESPONSE> public final class HttpServerAttributesExtractor<REQUEST, RESPONSE>
extends HttpCommonAttributesExtractor< extends HttpCommonAttributesExtractor<
REQUEST, RESPONSE, HttpServerAttributesGetter<REQUEST, RESPONSE>> { REQUEST, RESPONSE, HttpServerAttributesGetter<REQUEST, RESPONSE>> {

View File

@ -6,8 +6,10 @@
package io.opentelemetry.instrumentation.api.instrumenter.http; package io.opentelemetry.instrumentation.api.instrumenter.http;
import io.opentelemetry.instrumentation.api.config.Config; import io.opentelemetry.instrumentation.api.config.Config;
import java.util.List;
/** A builder of {@link HttpServerAttributesExtractor}. */ /** A builder of {@link HttpServerAttributesExtractor}. */
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> { public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
final HttpServerAttributesGetter<REQUEST, RESPONSE> getter; final HttpServerAttributesGetter<REQUEST, RESPONSE> getter;
@ -22,13 +24,40 @@ public final class HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> {
* *
* @param capturedHttpHeaders A configuration object specifying which HTTP request and response * @param capturedHttpHeaders A configuration object specifying which HTTP request and response
* headers should be captured as span attributes. * headers should be captured as span attributes.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
@Deprecated
public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> captureHttpHeaders( public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> captureHttpHeaders(
CapturedHttpHeaders capturedHttpHeaders) { CapturedHttpHeaders capturedHttpHeaders) {
this.capturedHttpHeaders = capturedHttpHeaders; this.capturedHttpHeaders = capturedHttpHeaders;
return this; return this;
} }
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> setCapturedRequestHeaders(
List<String> requestHeaders) {
this.capturedHttpHeaders =
CapturedHttpHeaders.create(requestHeaders, capturedHttpHeaders.responseHeaders());
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public HttpServerAttributesExtractorBuilder<REQUEST, RESPONSE> setCapturedResponseHeaders(
List<String> responseHeaders) {
this.capturedHttpHeaders =
CapturedHttpHeaders.create(capturedHttpHeaders.requestHeaders(), responseHeaders);
return this;
}
/** /**
* Returns a new {@link HttpServerAttributesExtractor} with the settings of this {@link * Returns a new {@link HttpServerAttributesExtractor} with the settings of this {@link
* HttpServerAttributesExtractorBuilder}. * HttpServerAttributesExtractorBuilder}.

View File

@ -105,10 +105,8 @@ class HttpClientAttributesExtractorTest {
HttpClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor = HttpClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
HttpClientAttributesExtractor.builder(new TestHttpClientAttributesGetter()) HttpClientAttributesExtractor.builder(new TestHttpClientAttributesGetter())
.captureHttpHeaders( .setCapturedRequestHeaders(singletonList("Custom-Request-Header"))
CapturedHttpHeaders.create( .setCapturedResponseHeaders(singletonList("Custom-Response-Header"))
singletonList("Custom-Request-Header"),
singletonList("Custom-Response-Header")))
.build(); .build();
AttributesBuilder attributes = Attributes.builder(); AttributesBuilder attributes = Attributes.builder();
@ -151,7 +149,8 @@ class HttpClientAttributesExtractorTest {
HttpClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor = HttpClientAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
HttpClientAttributesExtractor.builder(new TestHttpClientAttributesGetter()) HttpClientAttributesExtractor.builder(new TestHttpClientAttributesGetter())
.captureHttpHeaders(CapturedHttpHeaders.empty()) .setCapturedRequestHeaders(emptyList())
.setCapturedResponseHeaders(emptyList())
.build(); .build();
AttributesBuilder attributes = Attributes.builder(); AttributesBuilder attributes = Attributes.builder();

View File

@ -22,6 +22,7 @@ import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation") // suppress CapturedHttpHeaders deprecation
class HttpServerAttributesExtractorTest { class HttpServerAttributesExtractorTest {
static class TestHttpServerAttributesExtractor static class TestHttpServerAttributesExtractor
@ -185,7 +186,8 @@ class HttpServerAttributesExtractorTest {
HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor = HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
HttpServerAttributesExtractor.builder(new TestHttpServerAttributesExtractor()) HttpServerAttributesExtractor.builder(new TestHttpServerAttributesExtractor())
.captureHttpHeaders(CapturedHttpHeaders.empty()) .setCapturedRequestHeaders(emptyList())
.setCapturedResponseHeaders(emptyList())
.build(); .build();
AttributesBuilder attributes = Attributes.builder(); AttributesBuilder attributes = Attributes.builder();
@ -205,7 +207,8 @@ class HttpServerAttributesExtractorTest {
HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor = HttpServerAttributesExtractor<Map<String, String>, Map<String, String>> extractor =
HttpServerAttributesExtractor.builder(new TestHttpServerAttributesExtractor()) HttpServerAttributesExtractor.builder(new TestHttpServerAttributesExtractor())
.captureHttpHeaders(CapturedHttpHeaders.empty()) .setCapturedRequestHeaders(emptyList())
.setCapturedResponseHeaders(emptyList())
.build(); .build();
AttributesBuilder attributes = Attributes.builder(); AttributesBuilder attributes = Attributes.builder();

View File

@ -12,8 +12,9 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
final class ApacheHttpClientHttpAttributesGetter enum ApacheHttpClientHttpAttributesGetter
implements HttpClientAttributesGetter<ApacheHttpClientRequest, HttpResponse> { implements HttpClientAttributesGetter<ApacheHttpClientRequest, HttpResponse> {
INSTANCE;
@Override @Override
public String method(ApacheHttpClientRequest request) { public String method(ApacheHttpClientRequest request) {

View File

@ -6,12 +6,11 @@
package io.opentelemetry.instrumentation.apachehttpclient.v4_3; package io.opentelemetry.instrumentation.apachehttpclient.v4_3;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
@ -28,7 +27,9 @@ public final class ApacheHttpClientTracingBuilder {
private final List<AttributesExtractor<? super ApacheHttpClientRequest, ? super HttpResponse>> private final List<AttributesExtractor<? super ApacheHttpClientRequest, ? super HttpResponse>>
additionalExtractors = new ArrayList<>(); additionalExtractors = new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<ApacheHttpClientRequest, HttpResponse>
httpAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(ApacheHttpClientHttpAttributesGetter.INSTANCE);
ApacheHttpClientTracingBuilder(OpenTelemetry openTelemetry) { ApacheHttpClientTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -49,12 +50,37 @@ public final class ApacheHttpClientTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
@Deprecated
public ApacheHttpClientTracingBuilder captureHttpHeaders( public ApacheHttpClientTracingBuilder captureHttpHeaders(
CapturedHttpHeaders capturedHttpHeaders) { io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
this.capturedHttpHeaders = capturedHttpHeaders; capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public ApacheHttpClientTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public ApacheHttpClientTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -64,7 +90,7 @@ public final class ApacheHttpClientTracingBuilder {
*/ */
public ApacheHttpClientTracing build() { public ApacheHttpClientTracing build() {
ApacheHttpClientHttpAttributesGetter httpAttributesGetter = ApacheHttpClientHttpAttributesGetter httpAttributesGetter =
new ApacheHttpClientHttpAttributesGetter(); ApacheHttpClientHttpAttributesGetter.INSTANCE;
ApacheHttpClientNetAttributesGetter netAttributesGetter = ApacheHttpClientNetAttributesGetter netAttributesGetter =
new ApacheHttpClientNetAttributesGetter(); new ApacheHttpClientNetAttributesGetter();
@ -74,10 +100,7 @@ public final class ApacheHttpClientTracingBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
// We manually inject because we need to inject internal requests for redirects. // We manually inject because we need to inject internal requests for redirects.

View File

@ -15,8 +15,9 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
final class ArmeriaHttpClientAttributesGetter enum ArmeriaHttpClientAttributesGetter
implements HttpClientAttributesGetter<RequestContext, RequestLog> { implements HttpClientAttributesGetter<RequestContext, RequestLog> {
INSTANCE;
@Override @Override
public String method(RequestContext ctx) { public String method(RequestContext ctx) {

View File

@ -16,8 +16,9 @@ import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
final class ArmeriaHttpServerAttributesGetter enum ArmeriaHttpServerAttributesGetter
implements HttpServerAttributesGetter<RequestContext, RequestLog> { implements HttpServerAttributesGetter<RequestContext, RequestLog> {
INSTANCE;
@Override @Override
public String method(RequestContext ctx) { public String method(RequestContext ctx) {

View File

@ -10,17 +10,17 @@ import com.linecorp.armeria.common.RequestContext;
import com.linecorp.armeria.common.logging.RequestLog; import com.linecorp.armeria.common.logging.RequestLog;
import com.linecorp.armeria.server.ServiceRequestContext; import com.linecorp.armeria.server.ServiceRequestContext;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -39,12 +39,17 @@ public final class ArmeriaTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
@Nullable private String peerService; @Nullable private String peerService;
private CapturedHttpHeaders capturedHttpClientHeaders = CapturedHttpHeaders.client(Config.get());
private CapturedHttpHeaders capturedHttpServerHeaders = CapturedHttpHeaders.server(Config.get());
private final List<AttributesExtractor<? super RequestContext, ? super RequestLog>> private final List<AttributesExtractor<? super RequestContext, ? super RequestLog>>
additionalExtractors = new ArrayList<>(); additionalExtractors = new ArrayList<>();
private final HttpClientAttributesExtractorBuilder<RequestContext, RequestLog>
httpClientAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(ArmeriaHttpClientAttributesGetter.INSTANCE);
private final HttpServerAttributesExtractorBuilder<RequestContext, RequestLog>
httpServerAttributesExtractorBuilder =
HttpServerAttributesExtractor.builder(ArmeriaHttpServerAttributesGetter.INSTANCE);
private Function< private Function<
SpanStatusExtractor<RequestContext, RequestLog>, SpanStatusExtractor<RequestContext, RequestLog>,
? extends SpanStatusExtractor<? super RequestContext, ? super RequestLog>> ? extends SpanStatusExtractor<? super RequestContext, ? super RequestLog>>
@ -74,20 +79,46 @@ public final class ArmeriaTracingBuilder {
} }
/** Sets the {@code peer.service} attribute for http client spans. */ /** Sets the {@code peer.service} attribute for http client spans. */
public void setPeerService(String peerService) { public ArmeriaTracingBuilder setPeerService(String peerService) {
this.peerService = peerService; this.peerService = peerService;
return this;
} }
/** /**
* Configure the HTTP client instrumentation to capture chosen HTTP request and response headers * Configure the HTTP client instrumentation to capture chosen HTTP request and response headers
* as span attributes. * as span attributes.
* *
* @param capturedHttpClientHeaders An instance of {@link CapturedHttpHeaders} containing the * @param capturedHttpClientHeaders An instance of {@link
* io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names. * configured HTTP request and response names.
* @deprecated Use {@link #setCapturedClientRequestHeaders(List)} and {@link
* #setCapturedClientResponseHeaders(List)} instead.
*/ */
@Deprecated
public ArmeriaTracingBuilder captureHttpClientHeaders( public ArmeriaTracingBuilder captureHttpClientHeaders(
CapturedHttpHeaders capturedHttpClientHeaders) { io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
this.capturedHttpClientHeaders = capturedHttpClientHeaders; capturedHttpClientHeaders) {
httpClientAttributesExtractorBuilder.captureHttpHeaders(capturedHttpClientHeaders);
return this;
}
/**
* Configures the HTTP client request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public ArmeriaTracingBuilder setCapturedClientRequestHeaders(List<String> requestHeaders) {
httpClientAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP client response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public ArmeriaTracingBuilder setCapturedClientResponseHeaders(List<String> responseHeaders) {
httpClientAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -95,20 +126,45 @@ public final class ArmeriaTracingBuilder {
* Configure the HTTP server instrumentation to capture chosen HTTP request and response headers * Configure the HTTP server instrumentation to capture chosen HTTP request and response headers
* as span attributes. * as span attributes.
* *
* @param capturedHttpServerHeaders An instance of {@link CapturedHttpHeaders} containing the * @param capturedHttpServerHeaders An instance of {@link
* io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names. * configured HTTP request and response names.
* @deprecated Use {@link #setCapturedServerRequestHeaders(List)} and {@link
* #setCapturedServerResponseHeaders(List)} instead.
*/ */
@Deprecated
public ArmeriaTracingBuilder captureHttpServerHeaders( public ArmeriaTracingBuilder captureHttpServerHeaders(
CapturedHttpHeaders capturedHttpServerHeaders) { io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
this.capturedHttpServerHeaders = capturedHttpServerHeaders; capturedHttpServerHeaders) {
httpServerAttributesExtractorBuilder.captureHttpHeaders(capturedHttpServerHeaders);
return this;
}
/**
* Configures the HTTP server request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public ArmeriaTracingBuilder setCapturedServerRequestHeaders(List<String> requestHeaders) {
httpServerAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP server response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public ArmeriaTracingBuilder setCapturedServerResponseHeaders(List<String> responseHeaders) {
httpServerAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
public ArmeriaTracing build() { public ArmeriaTracing build() {
ArmeriaHttpClientAttributesGetter clientAttributesGetter = ArmeriaHttpClientAttributesGetter clientAttributesGetter =
new ArmeriaHttpClientAttributesGetter(); ArmeriaHttpClientAttributesGetter.INSTANCE;
ArmeriaHttpServerAttributesGetter serverAttributesGetter = ArmeriaHttpServerAttributesGetter serverAttributesGetter =
new ArmeriaHttpServerAttributesGetter(); ArmeriaHttpServerAttributesGetter.INSTANCE;
InstrumenterBuilder<ClientRequestContext, RequestLog> clientInstrumenterBuilder = InstrumenterBuilder<ClientRequestContext, RequestLog> clientInstrumenterBuilder =
Instrumenter.builder( Instrumenter.builder(
@ -134,10 +190,7 @@ public final class ArmeriaTracingBuilder {
statusExtractorTransformer.apply( statusExtractorTransformer.apply(
HttpSpanStatusExtractor.create(clientAttributesGetter))) HttpSpanStatusExtractor.create(clientAttributesGetter)))
.addAttributesExtractor(netClientAttributesExtractor) .addAttributesExtractor(netClientAttributesExtractor)
.addAttributesExtractor( .addAttributesExtractor(httpClientAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(clientAttributesGetter)
.captureHttpHeaders(capturedHttpClientHeaders)
.build())
.addRequestMetrics(HttpClientMetrics.get()); .addRequestMetrics(HttpClientMetrics.get());
serverInstrumenterBuilder serverInstrumenterBuilder
.setSpanStatusExtractor( .setSpanStatusExtractor(
@ -145,10 +198,7 @@ public final class ArmeriaTracingBuilder {
HttpSpanStatusExtractor.create(serverAttributesGetter))) HttpSpanStatusExtractor.create(serverAttributesGetter)))
.addAttributesExtractor( .addAttributesExtractor(
NetServerAttributesExtractor.create(new ArmeriaNetServerAttributesGetter())) NetServerAttributesExtractor.create(new ArmeriaNetServerAttributesGetter()))
.addAttributesExtractor( .addAttributesExtractor(httpServerAttributesExtractorBuilder.build())
HttpServerAttributesExtractor.builder(serverAttributesGetter)
.captureHttpHeaders(capturedHttpServerHeaders)
.build())
.addRequestMetrics(HttpServerMetrics.get()) .addRequestMetrics(HttpServerMetrics.get())
.addContextCustomizer(HttpRouteHolder.get()); .addContextCustomizer(HttpRouteHolder.get());

View File

@ -7,12 +7,14 @@ package io.opentelemetry.instrumentation.armeria.v1_3
import com.linecorp.armeria.server.ServerBuilder import com.linecorp.armeria.server.ServerBuilder
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
class ArmeriaHttpServerTest extends AbstractArmeriaHttpServerTest implements LibraryTestTrait { class ArmeriaHttpServerTest extends AbstractArmeriaHttpServerTest implements LibraryTestTrait {
@Override @Override
ServerBuilder configureServer(ServerBuilder sb) { ServerBuilder configureServer(ServerBuilder sb) {
return sb.decorator(ArmeriaTracing.builder(getOpenTelemetry()) return sb.decorator(ArmeriaTracing.builder(getOpenTelemetry())
.captureHttpServerHeaders(capturedHttpHeadersForTesting()) .setCapturedServerRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedServerResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
.newServiceDecorator()) .newServiceDecorator())
} }

View File

@ -7,8 +7,8 @@ package io.opentelemetry.instrumentation.jetty.httpclient.v9_2;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.JettyClientInstrumenterBuilder; import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.JettyClientInstrumenterBuilder;
import java.util.List;
import org.eclipse.jetty.client.HttpClientTransport; import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Response;
@ -49,11 +49,39 @@ public final class JettyClientTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public JettyClientTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
instrumenterBuilder.captureHttpHeaders(capturedHttpHeaders); public JettyClientTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
instrumenterBuilder
.setCapturedRequestHeaders(capturedHttpHeaders.requestHeaders())
.setCapturedResponseHeaders(capturedHttpHeaders.responseHeaders());
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public JettyClientTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
instrumenterBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public JettyClientTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
instrumenterBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }

View File

@ -20,8 +20,8 @@ import org.eclipse.jetty.http.HttpVersion;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
final class JettyClientHttpAttributesGetter enum JettyClientHttpAttributesGetter implements HttpClientAttributesGetter<Request, Response> {
implements HttpClientAttributesGetter<Request, Response> { INSTANCE;
private static final Logger logger = private static final Logger logger =
LoggerFactory.getLogger(JettyClientHttpAttributesGetter.class); LoggerFactory.getLogger(JettyClientHttpAttributesGetter.class);

View File

@ -6,11 +6,10 @@
package io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal; package io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -32,7 +31,9 @@ public final class JettyClientInstrumenterBuilder {
private final List<AttributesExtractor<? super Request, ? super Response>> additionalExtractors = private final List<AttributesExtractor<? super Request, ? super Response>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<Request, Response>
httpAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(JettyClientHttpAttributesGetter.INSTANCE);
public JettyClientInstrumenterBuilder(OpenTelemetry openTelemetry) { public JettyClientInstrumenterBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -44,14 +45,18 @@ public final class JettyClientInstrumenterBuilder {
return this; return this;
} }
public JettyClientInstrumenterBuilder captureHttpHeaders( public JettyClientInstrumenterBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
CapturedHttpHeaders capturedHttpHeaders) { httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
this.capturedHttpHeaders = capturedHttpHeaders; return this;
}
public JettyClientInstrumenterBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
public Instrumenter<Request, Response> build() { public Instrumenter<Request, Response> build() {
JettyClientHttpAttributesGetter httpAttributesGetter = new JettyClientHttpAttributesGetter(); JettyClientHttpAttributesGetter httpAttributesGetter = JettyClientHttpAttributesGetter.INSTANCE;
JettyHttpClientNetAttributesGetter netAttributesGetter = JettyHttpClientNetAttributesGetter netAttributesGetter =
new JettyHttpClientNetAttributesGetter(); new JettyHttpClientNetAttributesGetter();
@ -60,10 +65,7 @@ public final class JettyClientInstrumenterBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpClientMetrics.get()) .addRequestMetrics(HttpClientMetrics.get())

View File

@ -11,8 +11,9 @@ import io.ktor.response.*
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesGetter import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesGetter
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
internal class KtorHttpServerAttributesGetter : internal enum class KtorHttpServerAttributesGetter :
HttpServerAttributesGetter<ApplicationRequest, ApplicationResponse> { HttpServerAttributesGetter<ApplicationRequest, ApplicationResponse> {
INSTANCE;
override fun method(request: ApplicationRequest): String { override fun method(request: ApplicationRequest): String {
return request.httpMethod.value return request.httpMethod.value

View File

@ -14,11 +14,9 @@ import io.ktor.util.pipeline.*
import io.opentelemetry.api.OpenTelemetry import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.context.Context import io.opentelemetry.context.Context
import io.opentelemetry.extension.kotlin.asContextElement import io.opentelemetry.extension.kotlin.asContextElement
import io.opentelemetry.instrumentation.api.config.Config
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteSource import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteSource
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor
@ -35,10 +33,10 @@ class KtorServerTracing private constructor(
class Configuration { class Configuration {
internal lateinit var openTelemetry: OpenTelemetry internal lateinit var openTelemetry: OpenTelemetry
internal var capturedHttpHeaders = CapturedHttpHeaders.server(Config.get())
internal val additionalExtractors = mutableListOf<AttributesExtractor<in ApplicationRequest, in ApplicationResponse>>() internal val additionalExtractors = mutableListOf<AttributesExtractor<in ApplicationRequest, in ApplicationResponse>>()
internal val httpAttributesExtractorBuilder = HttpServerAttributesExtractor.builder(KtorHttpServerAttributesGetter.INSTANCE)
internal var statusExtractor: internal var statusExtractor:
(SpanStatusExtractor<ApplicationRequest, ApplicationResponse>) -> SpanStatusExtractor<in ApplicationRequest, in ApplicationResponse> = { a -> a } (SpanStatusExtractor<ApplicationRequest, ApplicationResponse>) -> SpanStatusExtractor<in ApplicationRequest, in ApplicationResponse> = { a -> a }
@ -54,8 +52,17 @@ class KtorServerTracing private constructor(
additionalExtractors.add(extractor) additionalExtractors.add(extractor)
} }
fun captureHttpHeaders(capturedHttpHeaders: CapturedHttpHeaders) { @Deprecated("Use the new setCapturedRequestHeaders() and setCapturedResponseHeaders() methods instead")
this.capturedHttpHeaders = capturedHttpHeaders fun captureHttpHeaders(capturedHttpHeaders: io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders)
}
fun setCapturedRequestHeaders(requestHeaders: List<String>) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders)
}
fun setCapturedResponseHeaders(responseHeaders: List<String>) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders)
} }
internal fun isOpenTelemetryInitialized(): Boolean = this::openTelemetry.isInitialized internal fun isOpenTelemetryInitialized(): Boolean = this::openTelemetry.isInitialized
@ -89,7 +96,7 @@ class KtorServerTracing private constructor(
throw IllegalArgumentException("OpenTelemetry must be set") throw IllegalArgumentException("OpenTelemetry must be set")
} }
val httpAttributesGetter = KtorHttpServerAttributesGetter() val httpAttributesGetter = KtorHttpServerAttributesGetter.INSTANCE
val instrumenterBuilder = Instrumenter.builder<ApplicationRequest, ApplicationResponse>( val instrumenterBuilder = Instrumenter.builder<ApplicationRequest, ApplicationResponse>(
configuration.openTelemetry, configuration.openTelemetry,
@ -102,7 +109,7 @@ class KtorServerTracing private constructor(
with(instrumenterBuilder) { with(instrumenterBuilder) {
setSpanStatusExtractor(configuration.statusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))) setSpanStatusExtractor(configuration.statusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)))
addAttributesExtractor(NetServerAttributesExtractor.create(KtorNetServerAttributesGetter())) addAttributesExtractor(NetServerAttributesExtractor.create(KtorNetServerAttributesGetter()))
addAttributesExtractor(HttpServerAttributesExtractor.builder(httpAttributesGetter).captureHttpHeaders(configuration.capturedHttpHeaders).build()) addAttributesExtractor(configuration.httpAttributesExtractorBuilder.build())
addRequestMetrics(HttpServerMetrics.get()) addRequestMetrics(HttpServerMetrics.get())
addContextCustomizer(HttpRouteHolder.get()) addContextCustomizer(HttpRouteHolder.get())
} }

View File

@ -7,14 +7,15 @@ package io.opentelemetry.instrumentation.ktor.v1_0
import io.ktor.application.* import io.ktor.application.*
import io.opentelemetry.api.OpenTelemetry import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.instrumentation.test.base.HttpServerTest import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
class KtorTestUtil { class KtorTestUtil {
companion object { companion object {
fun installOpenTelemetry(application: Application, openTelemetry: OpenTelemetry) { fun installOpenTelemetry(application: Application, openTelemetry: OpenTelemetry) {
application.install(KtorServerTracing) { application.install(KtorServerTracing) {
setOpenTelemetry(openTelemetry) setOpenTelemetry(openTelemetry)
captureHttpHeaders(HttpServerTest.capturedHttpHeadersForTesting()) setCapturedRequestHeaders(listOf(AbstractHttpServerTest.TEST_REQUEST_HEADER))
setCapturedResponseHeaders(listOf(AbstractHttpServerTest.TEST_RESPONSE_HEADER))
} }
} }
} }

View File

@ -12,7 +12,8 @@ import javax.annotation.Nullable;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
final class OkHttpAttributesGetter implements HttpClientAttributesGetter<Request, Response> { enum OkHttpAttributesGetter implements HttpClientAttributesGetter<Request, Response> {
INSTANCE;
@Override @Override
public String method(Request request) { public String method(Request request) {

View File

@ -8,11 +8,10 @@ package io.opentelemetry.instrumentation.okhttp.v3_0;
import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient; import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -30,7 +29,9 @@ public final class OkHttpTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<Request, Response>> additionalExtractors = private final List<AttributesExtractor<Request, Response>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<Request, Response>
httpAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(OkHttpAttributesGetter.INSTANCE);
OkHttpTracingBuilder(OpenTelemetry openTelemetry) { OkHttpTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -50,17 +51,43 @@ public final class OkHttpTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public OkHttpTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public OkHttpTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public OkHttpTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public OkHttpTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
/** Returns a new {@link OkHttpTracing} with the settings of this {@link OkHttpTracingBuilder}. */ /** Returns a new {@link OkHttpTracing} with the settings of this {@link OkHttpTracingBuilder}. */
public OkHttpTracing build() { public OkHttpTracing build() {
OkHttpAttributesGetter httpAttributesGetter = new OkHttpAttributesGetter(); OkHttpAttributesGetter httpAttributesGetter = OkHttpAttributesGetter.INSTANCE;
OkHttpNetAttributesGetter attributesGetter = new OkHttpNetAttributesGetter(); OkHttpNetAttributesGetter attributesGetter = new OkHttpNetAttributesGetter();
Instrumenter<Request, Response> instrumenter = Instrumenter<Request, Response> instrumenter =
@ -69,10 +96,7 @@ public final class OkHttpTracingBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetClientAttributesExtractor.create(attributesGetter)) .addAttributesExtractor(NetClientAttributesExtractor.create(attributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpClientMetrics.get()) .addRequestMetrics(HttpClientMetrics.get())

View File

@ -14,7 +14,8 @@ import ratpack.http.Request;
import ratpack.http.Response; import ratpack.http.Response;
import ratpack.server.PublicAddress; import ratpack.server.PublicAddress;
final class RatpackHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> { enum RatpackHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> {
INSTANCE;
@Override @Override
public String method(Request request) { public String method(Request request) {

View File

@ -12,8 +12,9 @@ import javax.annotation.Nullable;
import ratpack.http.client.HttpResponse; import ratpack.http.client.HttpResponse;
import ratpack.http.client.RequestSpec; import ratpack.http.client.RequestSpec;
final class RatpackHttpClientAttributesGetter enum RatpackHttpClientAttributesGetter
implements HttpClientAttributesGetter<RequestSpec, HttpResponse> { implements HttpClientAttributesGetter<RequestSpec, HttpResponse> {
INSTANCE;
@Nullable @Nullable
@Override @Override
@ -21,7 +22,6 @@ final class RatpackHttpClientAttributesGetter
return requestSpec.getUri().toString(); return requestSpec.getUri().toString();
} }
@Nullable
@Override @Override
public String flavor(RequestSpec requestSpec, @Nullable HttpResponse httpResponse) { public String flavor(RequestSpec requestSpec, @Nullable HttpResponse httpResponse) {
return SemanticAttributes.HttpFlavorValues.HTTP_1_1; return SemanticAttributes.HttpFlavorValues.HTTP_1_1;

View File

@ -6,12 +6,12 @@
package io.opentelemetry.instrumentation.ratpack; package io.opentelemetry.instrumentation.ratpack;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -35,8 +35,12 @@ public final class RatpackTracingBuilder {
private final List<AttributesExtractor<? super Request, ? super Response>> additionalExtractors = private final List<AttributesExtractor<? super Request, ? super Response>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpClientHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<RequestSpec, HttpResponse>
private CapturedHttpHeaders capturedHttpServerHeaders = CapturedHttpHeaders.server(Config.get()); httpClientAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(RatpackHttpClientAttributesGetter.INSTANCE);
private final HttpServerAttributesExtractorBuilder<Request, Response>
httpServerAttributesExtractorBuilder =
HttpServerAttributesExtractor.builder(RatpackHttpAttributesGetter.INSTANCE);
private final List<AttributesExtractor<? super RequestSpec, ? super HttpResponse>> private final List<AttributesExtractor<? super RequestSpec, ? super HttpResponse>>
additionalHttpClientExtractors = new ArrayList<>(); additionalHttpClientExtractors = new ArrayList<>();
@ -65,55 +69,106 @@ public final class RatpackTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* @deprecated Use {@link #captureHttpServerHeaders(CapturedHttpHeaders)} instead. * configured HTTP request and response names.
* @deprecated Use {@link #setCapturedServerRequestHeaders(List)} and {@link
* #setCapturedServerResponseHeaders(List)} instead.
*/ */
@Deprecated @Deprecated
public RatpackTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { public RatpackTracingBuilder captureHttpHeaders(
return captureHttpServerHeaders(capturedHttpServerHeaders); io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
} capturedHttpHeaders) {
return captureHttpServerHeaders(capturedHttpHeaders);
/**
* Configure the HTTP client instrumentation to capture chosen HTTP request and response headers
* as span attributes.
*
* @param capturedHttpClientHeaders An instance of {@link CapturedHttpHeaders} containing the
* configured HTTP request and response names.
*/
public RatpackTracingBuilder captureHttpClientHeaders(
CapturedHttpHeaders capturedHttpClientHeaders) {
this.capturedHttpClientHeaders = capturedHttpClientHeaders;
return this;
} }
/** /**
* Configure the HTTP server instrumentation to capture chosen HTTP request and response headers * Configure the HTTP server instrumentation to capture chosen HTTP request and response headers
* as span attributes. * as span attributes.
* *
* @param capturedHttpServerHeaders An instance of {@link CapturedHttpHeaders} containing the * @param capturedHttpServerHeaders An instance of {@link
* io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names. * configured HTTP request and response names.
* @deprecated Use {@link #setCapturedServerRequestHeaders(List)} and {@link
* #setCapturedServerResponseHeaders(List)} instead.
*/ */
@Deprecated
public RatpackTracingBuilder captureHttpServerHeaders( public RatpackTracingBuilder captureHttpServerHeaders(
CapturedHttpHeaders capturedHttpServerHeaders) { io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
this.capturedHttpServerHeaders = capturedHttpServerHeaders; capturedHttpServerHeaders) {
httpServerAttributesExtractorBuilder.captureHttpHeaders(capturedHttpServerHeaders);
return this;
}
/**
* Configures the HTTP server request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public RatpackTracingBuilder setCapturedServerRequestHeaders(List<String> requestHeaders) {
httpServerAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP server response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public RatpackTracingBuilder setCapturedServerResponseHeaders(List<String> responseHeaders) {
httpServerAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this;
}
/**
* Configure the HTTP client instrumentation to capture chosen HTTP request and response headers
* as span attributes.
*
* @param capturedHttpClientHeaders An instance of {@link
* io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedClientRequestHeaders(List)} and {@link
* #setCapturedClientResponseHeaders(List)} instead.
*/
@Deprecated
public RatpackTracingBuilder captureHttpClientHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpClientHeaders) {
httpClientAttributesExtractorBuilder.captureHttpHeaders(capturedHttpClientHeaders);
return this;
}
/**
* Configures the HTTP client request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public RatpackTracingBuilder setCapturedClientRequestHeaders(List<String> requestHeaders) {
httpClientAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP client response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public RatpackTracingBuilder setCapturedClientResponseHeaders(List<String> responseHeaders) {
httpClientAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
/** Returns a new {@link RatpackTracing} with the configuration of this builder. */ /** Returns a new {@link RatpackTracing} with the configuration of this builder. */
public RatpackTracing build() { public RatpackTracing build() {
RatpackNetAttributesGetter netAttributes = new RatpackNetAttributesGetter(); RatpackNetAttributesGetter netAttributes = new RatpackNetAttributesGetter();
RatpackHttpAttributesGetter httpAttributes = new RatpackHttpAttributesGetter(); RatpackHttpAttributesGetter httpAttributes = RatpackHttpAttributesGetter.INSTANCE;
Instrumenter<Request, Response> instrumenter = Instrumenter<Request, Response> instrumenter =
Instrumenter.<Request, Response>builder( Instrumenter.<Request, Response>builder(
openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributes)) openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributes))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributes)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributes))
.addAttributesExtractor(NetServerAttributesExtractor.create(netAttributes)) .addAttributesExtractor(NetServerAttributesExtractor.create(netAttributes))
.addAttributesExtractor( .addAttributesExtractor(httpServerAttributesExtractorBuilder.build())
HttpServerAttributesExtractor.builder(httpAttributes)
.captureHttpHeaders(capturedHttpServerHeaders)
.build())
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpServerMetrics.get()) .addRequestMetrics(HttpServerMetrics.get())
.newServerInstrumenter(RatpackGetter.INSTANCE); .newServerInstrumenter(RatpackGetter.INSTANCE);
@ -123,16 +178,13 @@ public final class RatpackTracingBuilder {
private Instrumenter<RequestSpec, HttpResponse> httpClientInstrumenter() { private Instrumenter<RequestSpec, HttpResponse> httpClientInstrumenter() {
RatpackHttpNetAttributesGetter netAttributes = new RatpackHttpNetAttributesGetter(); RatpackHttpNetAttributesGetter netAttributes = new RatpackHttpNetAttributesGetter();
RatpackHttpClientAttributesGetter httpAttributes = new RatpackHttpClientAttributesGetter(); RatpackHttpClientAttributesGetter httpAttributes = RatpackHttpClientAttributesGetter.INSTANCE;
return Instrumenter.<RequestSpec, HttpResponse>builder( return Instrumenter.<RequestSpec, HttpResponse>builder(
openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributes)) openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributes))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributes)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributes))
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributes)) .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributes))
.addAttributesExtractor( .addAttributesExtractor(httpClientAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributes)
.captureHttpHeaders(capturedHttpClientHeaders)
.build())
.addAttributesExtractors(additionalHttpClientExtractors) .addAttributesExtractors(additionalHttpClientExtractors)
.addRequestMetrics(HttpServerMetrics.get()) .addRequestMetrics(HttpServerMetrics.get())
.newClientInstrumenter(RequestHeaderSetter.INSTANCE); .newClientInstrumenter(RequestHeaderSetter.INSTANCE);

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.ratpack.server
import io.opentelemetry.instrumentation.ratpack.RatpackTracing import io.opentelemetry.instrumentation.ratpack.RatpackTracing
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import ratpack.server.RatpackServerSpec import ratpack.server.RatpackServerSpec
@ -14,7 +15,8 @@ class RatpackAsyncHttpServerTest extends AbstractRatpackAsyncHttpServerTest impl
@Override @Override
void configure(RatpackServerSpec serverSpec) { void configure(RatpackServerSpec serverSpec) {
RatpackTracing tracing = RatpackTracing.builder(openTelemetry) RatpackTracing tracing = RatpackTracing.builder(openTelemetry)
.captureHttpServerHeaders(capturedHttpHeadersForTesting()) .setCapturedServerRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedServerResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
serverSpec.registryOf { serverSpec.registryOf {
tracing.configureServerRegistry(it) tracing.configureServerRegistry(it)

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.ratpack.server
import io.opentelemetry.instrumentation.ratpack.RatpackTracing import io.opentelemetry.instrumentation.ratpack.RatpackTracing
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import ratpack.server.RatpackServerSpec import ratpack.server.RatpackServerSpec
@ -14,7 +15,8 @@ class RatpackForkedHttpServerTest extends AbstractRatpackForkedHttpServerTest im
@Override @Override
void configure(RatpackServerSpec serverSpec) { void configure(RatpackServerSpec serverSpec) {
RatpackTracing tracing = RatpackTracing.builder(openTelemetry) RatpackTracing tracing = RatpackTracing.builder(openTelemetry)
.captureHttpServerHeaders(capturedHttpHeadersForTesting()) .setCapturedServerRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedServerResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
serverSpec.registryOf { serverSpec.registryOf {
tracing.configureServerRegistry(it) tracing.configureServerRegistry(it)

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.ratpack.server
import io.opentelemetry.instrumentation.ratpack.RatpackTracing import io.opentelemetry.instrumentation.ratpack.RatpackTracing
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import ratpack.server.RatpackServerSpec import ratpack.server.RatpackServerSpec
@ -14,7 +15,8 @@ class RatpackHttpServerTest extends AbstractRatpackHttpServerTest implements Lib
@Override @Override
void configure(RatpackServerSpec serverSpec) { void configure(RatpackServerSpec serverSpec) {
RatpackTracing tracing = RatpackTracing.builder(openTelemetry) RatpackTracing tracing = RatpackTracing.builder(openTelemetry)
.captureHttpServerHeaders(capturedHttpHeadersForTesting()) .setCapturedServerRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedServerResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
serverSpec.registryOf { serverSpec.registryOf {
tracing.configureServerRegistry(it) tracing.configureServerRegistry(it)

View File

@ -20,7 +20,8 @@ import org.restlet.data.Request;
import org.restlet.data.Response; import org.restlet.data.Response;
import org.restlet.util.Series; import org.restlet.util.Series;
final class RestletHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> { enum RestletHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> {
INSTANCE;
@Override @Override
public String method(Request request) { public String method(Request request) {

View File

@ -6,11 +6,10 @@
package io.opentelemetry.instrumentation.restlet.v1_0; package io.opentelemetry.instrumentation.restlet.v1_0;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -28,7 +27,9 @@ public final class RestletTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<Request, Response>> additionalExtractors = private final List<AttributesExtractor<Request, Response>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.server(Config.get()); private final HttpServerAttributesExtractorBuilder<Request, Response>
httpAttributesExtractorBuilder =
HttpServerAttributesExtractor.builder(RestletHttpAttributesGetter.INSTANCE);
RestletTracingBuilder(OpenTelemetry openTelemetry) { RestletTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -48,11 +49,37 @@ public final class RestletTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public RestletTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public RestletTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public RestletTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public RestletTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -60,7 +87,7 @@ public final class RestletTracingBuilder {
* Returns a new {@link RestletTracing} with the settings of this {@link RestletTracingBuilder}. * Returns a new {@link RestletTracing} with the settings of this {@link RestletTracingBuilder}.
*/ */
public RestletTracing build() { public RestletTracing build() {
RestletHttpAttributesGetter httpAttributesGetter = new RestletHttpAttributesGetter(); RestletHttpAttributesGetter httpAttributesGetter = RestletHttpAttributesGetter.INSTANCE;
RestletNetAttributesGetter netAttributesGetter = new RestletNetAttributesGetter(); RestletNetAttributesGetter netAttributesGetter = new RestletNetAttributesGetter();
Instrumenter<Request, Response> instrumenter = Instrumenter<Request, Response> instrumenter =
@ -69,10 +96,7 @@ public final class RestletTracingBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpServerAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetServerAttributesExtractor.create(netAttributesGetter)) .addAttributesExtractor(NetServerAttributesExtractor.create(netAttributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpServerMetrics.get()) .addRequestMetrics(HttpServerMetrics.get())

View File

@ -9,6 +9,7 @@ import com.noelios.restlet.StatusFilter
import io.opentelemetry.instrumentation.restlet.v1_0.AbstractRestletServerTest import io.opentelemetry.instrumentation.restlet.v1_0.AbstractRestletServerTest
import io.opentelemetry.instrumentation.restlet.v1_0.RestletTracing import io.opentelemetry.instrumentation.restlet.v1_0.RestletTracing
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Restlet import org.restlet.Restlet
class RestletServerTest extends AbstractRestletServerTest implements LibraryTestTrait { class RestletServerTest extends AbstractRestletServerTest implements LibraryTestTrait {
@ -16,7 +17,8 @@ class RestletServerTest extends AbstractRestletServerTest implements LibraryTest
@Override @Override
Restlet wrapRestlet(Restlet restlet, String path) { Restlet wrapRestlet(Restlet restlet, String path) {
RestletTracing tracing = RestletTracing.builder(openTelemetry) RestletTracing tracing = RestletTracing.builder(openTelemetry)
.captureHttpHeaders(capturedHttpHeadersForTesting()) .setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
def tracingFilter = tracing.newFilter(path) def tracingFilter = tracing.newFilter(path)

View File

@ -9,6 +9,7 @@ import com.noelios.restlet.StatusFilter
import io.opentelemetry.instrumentation.restlet.v1_0.RestletTracing import io.opentelemetry.instrumentation.restlet.v1_0.RestletTracing
import io.opentelemetry.instrumentation.restlet.v1_0.spring.AbstractSpringServerTest import io.opentelemetry.instrumentation.restlet.v1_0.spring.AbstractSpringServerTest
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Restlet import org.restlet.Restlet
import org.restlet.Route import org.restlet.Route
import org.restlet.Router import org.restlet.Router
@ -19,7 +20,8 @@ abstract class AbstractSpringServerLibraryTest extends AbstractSpringServerTest
Restlet wrapRestlet(Restlet restlet, String path) { Restlet wrapRestlet(Restlet restlet, String path) {
RestletTracing tracing = RestletTracing.builder(openTelemetry) RestletTracing tracing = RestletTracing.builder(openTelemetry)
.captureHttpHeaders(capturedHttpHeadersForTesting()) .setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
def tracingFilter = tracing.newFilter(path) def tracingFilter = tracing.newFilter(path)

View File

@ -6,10 +6,11 @@
package io.opentelemetry.instrumentation.restlet.v2_0; package io.opentelemetry.instrumentation.restlet.v2_0;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.restlet.v2_0.internal.RestletHttpAttributesGetter;
import io.opentelemetry.instrumentation.restlet.v2_0.internal.RestletInstrumenterFactory; import io.opentelemetry.instrumentation.restlet.v2_0.internal.RestletInstrumenterFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -22,7 +23,9 @@ public final class RestletTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<Request, Response>> additionalExtractors = private final List<AttributesExtractor<Request, Response>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.server(Config.get()); private final HttpServerAttributesExtractorBuilder<Request, Response>
httpAttributesExtractorBuilder =
HttpServerAttributesExtractor.builder(RestletHttpAttributesGetter.INSTANCE);
RestletTracingBuilder(OpenTelemetry openTelemetry) { RestletTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -42,11 +45,37 @@ public final class RestletTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public RestletTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public RestletTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public RestletTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public RestletTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -54,10 +83,9 @@ public final class RestletTracingBuilder {
* Returns a new {@link RestletTracing} with the settings of this {@link RestletTracingBuilder}. * Returns a new {@link RestletTracing} with the settings of this {@link RestletTracingBuilder}.
*/ */
public RestletTracing build() { public RestletTracing build() {
Instrumenter<Request, Response> serverInstrumenter = Instrumenter<Request, Response> serverInstrumenter =
RestletInstrumenterFactory.newServerInstrumenter( RestletInstrumenterFactory.newServerInstrumenter(
openTelemetry, capturedHttpHeaders, additionalExtractors); openTelemetry, httpAttributesExtractorBuilder.build(), additionalExtractors);
return new RestletTracing(serverInstrumenter); return new RestletTracing(serverInstrumenter);
} }

View File

@ -18,7 +18,12 @@ import org.restlet.Response;
import org.restlet.data.Reference; import org.restlet.data.Reference;
import org.restlet.util.Series; import org.restlet.util.Series;
final class RestletHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> { /**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public enum RestletHttpAttributesGetter implements HttpServerAttributesGetter<Request, Response> {
INSTANCE;
@Override @Override
public String method(Request request) { public String method(Request request) {

View File

@ -6,10 +6,8 @@
package io.opentelemetry.instrumentation.restlet.v2_0.internal; package io.opentelemetry.instrumentation.restlet.v2_0.internal;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
@ -30,24 +28,23 @@ public class RestletInstrumenterFactory {
public static Instrumenter<Request, Response> newServerInstrumenter(OpenTelemetry openTelemetry) { public static Instrumenter<Request, Response> newServerInstrumenter(OpenTelemetry openTelemetry) {
return newServerInstrumenter( return newServerInstrumenter(
openTelemetry, CapturedHttpHeaders.server(Config.get()), Collections.emptyList()); openTelemetry,
HttpServerAttributesExtractor.create(RestletHttpAttributesGetter.INSTANCE),
Collections.emptyList());
} }
public static Instrumenter<Request, Response> newServerInstrumenter( public static Instrumenter<Request, Response> newServerInstrumenter(
OpenTelemetry openTelemetry, OpenTelemetry openTelemetry,
CapturedHttpHeaders capturedHttpHeaders, HttpServerAttributesExtractor<Request, Response> httpServerAttributesExtractor,
List<AttributesExtractor<Request, Response>> additionalExtractors) { List<AttributesExtractor<Request, Response>> additionalExtractors) {
RestletHttpAttributesGetter httpAttributesGetter = new RestletHttpAttributesGetter(); RestletHttpAttributesGetter httpAttributesGetter = RestletHttpAttributesGetter.INSTANCE;
RestletNetAttributesGetter netAttributesGetter = new RestletNetAttributesGetter(); RestletNetAttributesGetter netAttributesGetter = new RestletNetAttributesGetter();
return Instrumenter.<Request, Response>builder( return Instrumenter.<Request, Response>builder(
openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributesGetter)) openTelemetry, INSTRUMENTATION_NAME, HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpServerAttributesExtractor)
HttpServerAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetServerAttributesExtractor.create(netAttributesGetter)) .addAttributesExtractor(NetServerAttributesExtractor.create(netAttributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpServerMetrics.get()) .addRequestMetrics(HttpServerMetrics.get())

View File

@ -6,6 +6,7 @@
package io.opentelemetry.instrumentation.restlet.v2_0 package io.opentelemetry.instrumentation.restlet.v2_0
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Restlet import org.restlet.Restlet
import org.restlet.engine.application.StatusFilter import org.restlet.engine.application.StatusFilter
import org.restlet.service.StatusService import org.restlet.service.StatusService
@ -16,7 +17,8 @@ class RestletServerTest extends AbstractRestletServerTest implements LibraryTest
Restlet wrapRestlet(Restlet restlet, String path) { Restlet wrapRestlet(Restlet restlet, String path) {
RestletTracing tracing = RestletTracing.builder(openTelemetry) RestletTracing tracing = RestletTracing.builder(openTelemetry)
.captureHttpHeaders(capturedHttpHeadersForTesting()) .setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
def tracingFilter = tracing.newFilter(path) def tracingFilter = tracing.newFilter(path)

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.restlet.v2_0.spring
import io.opentelemetry.instrumentation.restlet.v2_0.RestletTracing import io.opentelemetry.instrumentation.restlet.v2_0.RestletTracing
import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.instrumentation.test.LibraryTestTrait
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerTest
import org.restlet.Request import org.restlet.Request
import org.restlet.Response import org.restlet.Response
import org.restlet.Restlet import org.restlet.Restlet
@ -25,7 +26,8 @@ abstract class AbstractSpringServerLibraryTest extends AbstractSpringServerTest
Restlet wrapRestlet(Restlet restlet, String path) { Restlet wrapRestlet(Restlet restlet, String path) {
RestletTracing tracing = RestletTracing.builder(openTelemetry) RestletTracing tracing = RestletTracing.builder(openTelemetry)
.captureHttpHeaders(capturedHttpHeadersForTesting()) .setCapturedRequestHeaders([AbstractHttpServerTest.TEST_REQUEST_HEADER])
.setCapturedResponseHeaders([AbstractHttpServerTest.TEST_RESPONSE_HEADER])
.build() .build()
def tracingFilter = tracing.newFilter(path) def tracingFilter = tracing.newFilter(path)

View File

@ -15,8 +15,9 @@ import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
final class SpringWebHttpAttributesGetter enum SpringWebHttpAttributesGetter
implements HttpClientAttributesGetter<HttpRequest, ClientHttpResponse> { implements HttpClientAttributesGetter<HttpRequest, ClientHttpResponse> {
INSTANCE;
@Override @Override
public String method(HttpRequest httpRequest) { public String method(HttpRequest httpRequest) {

View File

@ -6,11 +6,10 @@
package io.opentelemetry.instrumentation.spring.web; package io.opentelemetry.instrumentation.spring.web;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -27,7 +26,9 @@ public final class SpringWebTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<HttpRequest, ClientHttpResponse>> additionalExtractors = private final List<AttributesExtractor<HttpRequest, ClientHttpResponse>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<HttpRequest, ClientHttpResponse>
httpAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(SpringWebHttpAttributesGetter.INSTANCE);
SpringWebTracingBuilder(OpenTelemetry openTelemetry) { SpringWebTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -47,11 +48,37 @@ public final class SpringWebTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public SpringWebTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public SpringWebTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public SpringWebTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public SpringWebTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -60,7 +87,7 @@ public final class SpringWebTracingBuilder {
* SpringWebTracingBuilder}. * SpringWebTracingBuilder}.
*/ */
public SpringWebTracing build() { public SpringWebTracing build() {
SpringWebHttpAttributesGetter httpAttributeGetter = new SpringWebHttpAttributesGetter(); SpringWebHttpAttributesGetter httpAttributeGetter = SpringWebHttpAttributesGetter.INSTANCE;
SpringWebNetAttributesGetter netAttributesGetter = new SpringWebNetAttributesGetter(); SpringWebNetAttributesGetter netAttributesGetter = new SpringWebNetAttributesGetter();
Instrumenter<HttpRequest, ClientHttpResponse> instrumenter = Instrumenter<HttpRequest, ClientHttpResponse> instrumenter =
@ -69,10 +96,7 @@ public final class SpringWebTracingBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributeGetter)) HttpSpanNameExtractor.create(httpAttributeGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributeGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributeGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributeGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)
.addRequestMetrics(HttpClientMetrics.get()) .addRequestMetrics(HttpClientMetrics.get())

View File

@ -16,8 +16,9 @@ import javax.annotation.Nullable;
import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ClientResponse;
final class SpringWebfluxHttpAttributesGetter enum SpringWebfluxHttpAttributesGetter
implements HttpClientAttributesGetter<ClientRequest, ClientResponse> { implements HttpClientAttributesGetter<ClientRequest, ClientResponse> {
INSTANCE;
private static final MethodHandle RAW_STATUS_CODE = findRawStatusCode(); private static final MethodHandle RAW_STATUS_CODE = findRawStatusCode();

View File

@ -8,13 +8,12 @@ package io.opentelemetry.instrumentation.spring.webflux.client;
import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient; import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -30,7 +29,9 @@ public final class SpringWebfluxTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<ClientRequest, ClientResponse>> additionalExtractors = private final List<AttributesExtractor<ClientRequest, ClientResponse>> additionalExtractors =
new ArrayList<>(); new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.client(Config.get()); private final HttpClientAttributesExtractorBuilder<ClientRequest, ClientResponse>
httpAttributesExtractorBuilder =
HttpClientAttributesExtractor.builder(SpringWebfluxHttpAttributesGetter.INSTANCE);
SpringWebfluxTracingBuilder(OpenTelemetry openTelemetry) { SpringWebfluxTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -50,11 +51,37 @@ public final class SpringWebfluxTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public SpringWebfluxTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public SpringWebfluxTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public SpringWebfluxTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public SpringWebfluxTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -64,7 +91,7 @@ public final class SpringWebfluxTracingBuilder {
*/ */
public SpringWebfluxTracing build() { public SpringWebfluxTracing build() {
SpringWebfluxHttpAttributesGetter httpAttributesGetter = SpringWebfluxHttpAttributesGetter httpAttributesGetter =
new SpringWebfluxHttpAttributesGetter(); SpringWebfluxHttpAttributesGetter.INSTANCE;
SpringWebfluxNetAttributesGetter attributesGetter = new SpringWebfluxNetAttributesGetter(); SpringWebfluxNetAttributesGetter attributesGetter = new SpringWebfluxNetAttributesGetter();
NetClientAttributesExtractor<ClientRequest, ClientResponse> attributesExtractor = NetClientAttributesExtractor<ClientRequest, ClientResponse> attributesExtractor =
NetClientAttributesExtractor.create(attributesGetter); NetClientAttributesExtractor.create(attributesGetter);
@ -75,10 +102,7 @@ public final class SpringWebfluxTracingBuilder {
"io.opentelemetry.spring-webflux-5.0", "io.opentelemetry.spring-webflux-5.0",
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpClientAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(attributesExtractor) .addAttributesExtractor(attributesExtractor)
.addAttributesExtractor(PeerServiceAttributesExtractor.create(attributesGetter)) .addAttributesExtractor(PeerServiceAttributesExtractor.create(attributesGetter))
.addAttributesExtractors(additionalExtractors) .addAttributesExtractors(additionalExtractors)

View File

@ -15,8 +15,9 @@ import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
final class SpringWebMvcHttpAttributesGetter enum SpringWebMvcHttpAttributesGetter
implements HttpServerAttributesGetter<HttpServletRequest, HttpServletResponse> { implements HttpServerAttributesGetter<HttpServletRequest, HttpServletResponse> {
INSTANCE;
@Override @Override
@Nullable @Nullable

View File

@ -6,12 +6,11 @@
package io.opentelemetry.instrumentation.spring.webmvc; package io.opentelemetry.instrumentation.spring.webmvc;
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpRouteHolder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor; import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
@ -29,7 +28,9 @@ public final class SpringWebMvcTracingBuilder {
private final OpenTelemetry openTelemetry; private final OpenTelemetry openTelemetry;
private final List<AttributesExtractor<HttpServletRequest, HttpServletResponse>> private final List<AttributesExtractor<HttpServletRequest, HttpServletResponse>>
additionalExtractors = new ArrayList<>(); additionalExtractors = new ArrayList<>();
private CapturedHttpHeaders capturedHttpHeaders = CapturedHttpHeaders.server(Config.get()); private final HttpServerAttributesExtractorBuilder<HttpServletRequest, HttpServletResponse>
httpAttributesExtractorBuilder =
HttpServerAttributesExtractor.builder(SpringWebMvcHttpAttributesGetter.INSTANCE);
SpringWebMvcTracingBuilder(OpenTelemetry openTelemetry) { SpringWebMvcTracingBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry; this.openTelemetry = openTelemetry;
@ -49,11 +50,37 @@ public final class SpringWebMvcTracingBuilder {
* Configure the instrumentation to capture chosen HTTP request and response headers as span * Configure the instrumentation to capture chosen HTTP request and response headers as span
* attributes. * attributes.
* *
* @param capturedHttpHeaders An instance of {@link CapturedHttpHeaders} containing the configured * @param capturedHttpHeaders An instance of {@link
* HTTP request and response names. * io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders} containing the
* configured HTTP request and response names.
* @deprecated Use {@link #setCapturedRequestHeaders(List)} and {@link
* #setCapturedResponseHeaders(List)} instead.
*/ */
public SpringWebMvcTracingBuilder captureHttpHeaders(CapturedHttpHeaders capturedHttpHeaders) { @Deprecated
this.capturedHttpHeaders = capturedHttpHeaders; public SpringWebMvcTracingBuilder captureHttpHeaders(
io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
capturedHttpHeaders) {
this.httpAttributesExtractorBuilder.captureHttpHeaders(capturedHttpHeaders);
return this;
}
/**
* Configures the HTTP request headers that will be captured as span attributes.
*
* @param requestHeaders A list of HTTP header names.
*/
public SpringWebMvcTracingBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders);
return this;
}
/**
* Configures the HTTP response headers that will be captured as span attributes.
*
* @param responseHeaders A list of HTTP header names.
*/
public SpringWebMvcTracingBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders);
return this; return this;
} }
@ -62,7 +89,8 @@ public final class SpringWebMvcTracingBuilder {
* SpringWebMvcTracingBuilder}. * SpringWebMvcTracingBuilder}.
*/ */
public SpringWebMvcTracing build() { public SpringWebMvcTracing build() {
SpringWebMvcHttpAttributesGetter httpAttributesGetter = new SpringWebMvcHttpAttributesGetter(); SpringWebMvcHttpAttributesGetter httpAttributesGetter =
SpringWebMvcHttpAttributesGetter.INSTANCE;
Instrumenter<HttpServletRequest, HttpServletResponse> instrumenter = Instrumenter<HttpServletRequest, HttpServletResponse> instrumenter =
Instrumenter.<HttpServletRequest, HttpServletResponse>builder( Instrumenter.<HttpServletRequest, HttpServletResponse>builder(
@ -70,10 +98,7 @@ public final class SpringWebMvcTracingBuilder {
INSTRUMENTATION_NAME, INSTRUMENTATION_NAME,
HttpSpanNameExtractor.create(httpAttributesGetter)) HttpSpanNameExtractor.create(httpAttributesGetter))
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)) .setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor( .addAttributesExtractor(httpAttributesExtractorBuilder.build())
HttpServerAttributesExtractor.builder(httpAttributesGetter)
.captureHttpHeaders(capturedHttpHeaders)
.build())
.addAttributesExtractor(new StatusCodeExtractor()) .addAttributesExtractor(new StatusCodeExtractor())
.addAttributesExtractor( .addAttributesExtractor(
NetServerAttributesExtractor.create(new SpringWebMvcNetAttributesGetter())) NetServerAttributesExtractor.create(new SpringWebMvcNetAttributesGetter()))

View File

@ -9,7 +9,6 @@ import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.api.trace.Span import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.SpanId import io.opentelemetry.api.trace.SpanId
import io.opentelemetry.api.trace.SpanKind import io.opentelemetry.api.trace.SpanKind
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders
import io.opentelemetry.instrumentation.test.InstrumentationSpecification import io.opentelemetry.instrumentation.test.InstrumentationSpecification
import io.opentelemetry.instrumentation.test.asserts.TraceAssert import io.opentelemetry.instrumentation.test.asserts.TraceAssert
import io.opentelemetry.instrumentation.testing.GlobalTraceUtil import io.opentelemetry.instrumentation.testing.GlobalTraceUtil
@ -47,10 +46,6 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
cleanupServer() cleanupServer()
} }
static CapturedHttpHeaders capturedHttpHeadersForTesting() {
return AbstractHttpServerTest.capturedHttpHeadersForTesting()
}
String expectedServerSpanName(ServerEndpoint endpoint, String method) { String expectedServerSpanName(ServerEndpoint endpoint, String method) {
def route = expectedHttpRoute(endpoint) def route = expectedHttpRoute(endpoint)
return route == null ? "HTTP $method" : route return route == null ? "HTTP $method" : route

View File

@ -16,7 +16,6 @@ import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT;
import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue;
import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.GlobalOpenTelemetry;
@ -26,7 +25,6 @@ import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.instrumentation.api.instrumenter.http.CapturedHttpHeaders;
import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner; import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner;
import io.opentelemetry.sdk.testing.assertj.SpanDataAssert; import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
import io.opentelemetry.sdk.testing.assertj.TraceAssert; import io.opentelemetry.sdk.testing.assertj.TraceAssert;
@ -68,8 +66,8 @@ import org.slf4j.LoggerFactory;
public abstract class AbstractHttpServerTest<SERVER> { public abstract class AbstractHttpServerTest<SERVER> {
private static final Logger logger = LoggerFactory.getLogger(AbstractHttpServerTest.class); private static final Logger logger = LoggerFactory.getLogger(AbstractHttpServerTest.class);
private static final String TEST_REQUEST_HEADER = "X-Test-Request"; public static final String TEST_REQUEST_HEADER = "X-Test-Request";
private static final String TEST_RESPONSE_HEADER = "X-Test-Response"; public static final String TEST_RESPONSE_HEADER = "X-Test-Response";
public static final String TEST_CLIENT_IP = "1.1.1.1"; public static final String TEST_CLIENT_IP = "1.1.1.1";
public static final String TEST_USER_AGENT = "test-user-agent"; public static final String TEST_USER_AGENT = "test-user-agent";
@ -135,11 +133,6 @@ public abstract class AbstractHttpServerTest<SERVER> {
} }
} }
public static CapturedHttpHeaders capturedHttpHeadersForTesting() {
return CapturedHttpHeaders.create(
singletonList(TEST_REQUEST_HEADER), singletonList(TEST_RESPONSE_HEADER));
}
String resolveAddress(ServerEndpoint uri) { String resolveAddress(ServerEndpoint uri) {
String url = uri.resolvePath(address).toString(); String url = uri.resolvePath(address).toString();
// Force HTTP/1 via h1c so upgrade requests don't show up as traces // Force HTTP/1 via h1c so upgrade requests don't show up as traces