Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use DefaultHttpClientInstrumenterBuilder and DefaultHttpServerInstrumenterBuilder for armeria #11797

Merged
merged 11 commits into from
Aug 15, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig;
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientExperimentalMetrics;
Expand All @@ -18,6 +19,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter;
Expand All @@ -39,18 +41,25 @@
*/
public final class DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> {

// copied from PeerIncubatingAttributes
private static final AttributeKey<String> PEER_SERVICE = AttributeKey.stringKey("peer.service");

private final String instrumentationName;
private final OpenTelemetry openTelemetry;

private final List<AttributesExtractor<? super REQUEST, ? super RESPONSE>> additionalExtractors =
new ArrayList<>();
private Function<
SpanStatusExtractor<? super REQUEST, ? super RESPONSE>,
? extends SpanStatusExtractor<? super REQUEST, ? super RESPONSE>>
trask marked this conversation as resolved.
Show resolved Hide resolved
statusExtractorTransformer = Function.identity();
private final HttpClientAttributesExtractorBuilder<REQUEST, RESPONSE>
httpAttributesExtractorBuilder;
private final HttpClientAttributesGetter<REQUEST, RESPONSE> attributesGetter;
private final HttpSpanNameExtractorBuilder<REQUEST> httpSpanNameExtractorBuilder;

@Nullable private TextMapSetter<REQUEST> headerSetter;
private Function<SpanNameExtractor<REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
private Function<SpanNameExtractor<? super REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
spanNameExtractorTransformer = Function.identity();
private boolean emitExperimentalHttpClientMetrics = false;
private Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> builderCustomizer = b -> {};
Expand All @@ -77,6 +86,16 @@ public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> addAttributeExtra
return this;
}

@CanIgnoreReturnValue
public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setStatusExtractor(
Function<
SpanStatusExtractor<? super REQUEST, ? super RESPONSE>,
? extends SpanStatusExtractor<? super REQUEST, ? super RESPONSE>>
statusExtractor) {
this.statusExtractorTransformer = statusExtractor;
return this;
}

/**
* Configures the HTTP request headers that will be captured as span attributes.
*
Expand Down Expand Up @@ -145,7 +164,7 @@ public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setHeaderSetter(
/** Sets custom {@link SpanNameExtractor} via transform function. */
@CanIgnoreReturnValue
public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setSpanNameExtractor(
Function<SpanNameExtractor<REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
Function<SpanNameExtractor<? super REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
spanNameExtractorTransformer) {
this.spanNameExtractorTransformer = spanNameExtractorTransformer;
return this;
Expand All @@ -159,6 +178,13 @@ public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setPeerServiceRes
HttpClientPeerServiceAttributesExtractor.create(attributesGetter, peerServiceResolver));
}

/** Sets the {@code peer.service} attribute for http client spans. */
@CanIgnoreReturnValue
public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setPeerService(
String peerService) {
return addAttributeExtractor(AttributesExtractor.constant(PEER_SERVICE, peerService));
}

@CanIgnoreReturnValue
public DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> setBuilderCustomizer(
Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> builderCustomizer) {
Expand All @@ -174,7 +200,8 @@ public Instrumenter<REQUEST, RESPONSE> build() {
InstrumenterBuilder<REQUEST, RESPONSE> builder =
Instrumenter.<REQUEST, RESPONSE>builder(
openTelemetry, instrumentationName, spanNameExtractor)
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(attributesGetter))
.setSpanStatusExtractor(
statusExtractorTransformer.apply(HttpSpanStatusExtractor.create(attributesGetter)))
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
.addAttributesExtractors(additionalExtractors)
.addOperationMetrics(HttpClientMetrics.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public final class DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> {
private final HttpSpanNameExtractorBuilder<REQUEST> httpSpanNameExtractorBuilder;

@Nullable private TextMapGetter<REQUEST> headerGetter;
private Function<SpanNameExtractor<REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
private Function<SpanNameExtractor<? super REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
spanNameExtractorTransformer = Function.identity();
private final HttpServerRouteBuilder<REQUEST> httpServerRouteBuilder;
private final HttpServerAttributesGetter<REQUEST, RESPONSE> attributesGetter;
Expand Down Expand Up @@ -162,7 +162,7 @@ public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setHeaderGetter(
/** Sets custom {@link SpanNameExtractor} via transform function. */
@CanIgnoreReturnValue
public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setSpanNameExtractor(
Function<SpanNameExtractor<REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
Function<SpanNameExtractor<? super REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
spanNameExtractorTransformer) {
this.spanNameExtractorTransformer = spanNameExtractorTransformer;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public ApacheHttpClientTelemetryBuilder setEmitExperimentalHttpClientMetrics(
@CanIgnoreReturnValue
public ApacheHttpClientTelemetryBuilder setSpanNameExtractor(
Function<
SpanNameExtractor<ApacheHttpClientRequest>,
SpanNameExtractor<? super ApacheHttpClientRequest>,
? extends SpanNameExtractor<? super ApacheHttpClientRequest>>
spanNameExtractorTransformer) {
builder.setSpanNameExtractor(spanNameExtractorTransformer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public ApacheHttpClient5TelemetryBuilder setEmitExperimentalHttpClientMetrics(
@CanIgnoreReturnValue
public ApacheHttpClient5TelemetryBuilder setSpanNameExtractor(
Function<
SpanNameExtractor<ApacheHttpClient5Request>,
SpanNameExtractor<? super ApacheHttpClient5Request>,
? extends SpanNameExtractor<? super ApacheHttpClient5Request>>
spanNameExtractorTransformer) {
builder.setSpanNameExtractor(spanNameExtractorTransformer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import com.linecorp.armeria.client.HttpClient;
import com.linecorp.armeria.server.HttpService;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientPeerServiceAttributesExtractor;
import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig;
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaTelemetry;
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaHttpClientAttributesGetter;
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaTelemetryBuilder;
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderUtil;
import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig;
import java.util.function.Function;

Expand All @@ -22,28 +23,15 @@ public final class ArmeriaSingletons {
public static final Function<? super HttpService, ? extends HttpService> SERVER_DECORATOR;

static {
ArmeriaTelemetry telemetry =
ArmeriaTelemetry.builder(GlobalOpenTelemetry.get())
.setCapturedClientRequestHeaders(AgentCommonConfig.get().getClientRequestHeaders())
.setCapturedClientResponseHeaders(AgentCommonConfig.get().getClientResponseHeaders())
.setCapturedServerRequestHeaders(AgentCommonConfig.get().getServerRequestHeaders())
.setCapturedServerResponseHeaders(AgentCommonConfig.get().getServerResponseHeaders())
.setKnownMethods(AgentCommonConfig.get().getKnownHttpRequestMethods())
.addClientAttributeExtractor(
HttpClientPeerServiceAttributesExtractor.create(
ArmeriaHttpClientAttributesGetter.INSTANCE,
AgentCommonConfig.get().getPeerServiceResolver()))
.setEmitExperimentalHttpClientMetrics(
AgentCommonConfig.get().shouldEmitExperimentalHttpClientTelemetry())
.setEmitExperimentalHttpServerMetrics(
AgentCommonConfig.get().shouldEmitExperimentalHttpServerTelemetry())
.build();
ArmeriaTelemetryBuilder builder = ArmeriaTelemetry.builder(GlobalOpenTelemetry.get());
CommonConfig config = AgentCommonConfig.get();
ArmeriaInstrumenterBuilderUtil.getClientBuilderExtractor().apply(builder).configure(config);
ArmeriaInstrumenterBuilderUtil.getServerBuilderExtractor().apply(builder).configure(config);
ArmeriaTelemetry telemetry = builder.build();

CLIENT_DECORATOR = telemetry.newClientDecorator();
Function<? super HttpService, ? extends HttpService> libraryDecorator =
telemetry
.newServiceDecorator()
.compose(service -> new ResponseCustomizingDecorator(service));
telemetry.newServiceDecorator().compose(ResponseCustomizingDecorator::new);
SERVER_DECORATOR = service -> new ServerDecorator(service, libraryDecorator.apply(service));
}

Expand Down
Loading
Loading