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

http server and client builder for netty #12083

Merged
merged 14 commits into from
Sep 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,10 @@ public Instrumenter<REQUEST, RESPONSE> build() {
return builder.buildInstrumenter(SpanKindExtractor.alwaysClient());
}

public OpenTelemetry getOpenTelemetry() {
return openTelemetry;
public <BUILDERREQUEST, BUILDERRESPONSE>
InstrumenterBuilder<BUILDERREQUEST, BUILDERRESPONSE> instrumenterBuilder(
SpanNameExtractor<? super BUILDERREQUEST> spanNameExtractor) {
return Instrumenter.builder(openTelemetry, instrumentationName, spanNameExtractor);
Comment on lines +221 to +224
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method is confusing, I finally understood it, but wonder if there's anything we can do to make it clearer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe toInstrumenterBuilder?

}

@CanIgnoreReturnValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,26 @@ public final class DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> {
httpAttributesExtractorBuilder;
private final HttpSpanNameExtractorBuilder<REQUEST> httpSpanNameExtractorBuilder;

@Nullable private TextMapGetter<REQUEST> headerGetter;
@Nullable private final TextMapGetter<REQUEST> headerGetter;
private Function<SpanNameExtractor<? super REQUEST>, ? extends SpanNameExtractor<? super REQUEST>>
spanNameExtractorTransformer = Function.identity();
private final HttpServerRouteBuilder<REQUEST> httpServerRouteBuilder;
private final HttpServerAttributesGetter<REQUEST, RESPONSE> attributesGetter;
private boolean emitExperimentalHttpServerMetrics = false;
private Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> builderCustomizer = b -> {};

public DefaultHttpServerInstrumenterBuilder(
String instrumentationName,
OpenTelemetry openTelemetry,
HttpServerAttributesGetter<REQUEST, RESPONSE> attributesGetter) {
HttpServerAttributesGetter<REQUEST, RESPONSE> attributesGetter,
@Nullable TextMapGetter<REQUEST> headerGetter) {
this.instrumentationName = instrumentationName;
this.openTelemetry = openTelemetry;
httpAttributesExtractorBuilder = HttpServerAttributesExtractor.builder(attributesGetter);
httpSpanNameExtractorBuilder = HttpSpanNameExtractor.builder(attributesGetter);
httpServerRouteBuilder = HttpServerRoute.builder(attributesGetter);
this.attributesGetter = attributesGetter;
this.headerGetter = headerGetter;
}

/**
Expand Down Expand Up @@ -139,13 +142,6 @@ public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setKnownMethods(
return this;
}

@CanIgnoreReturnValue
public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setHeaderGetter(
@Nullable TextMapGetter<REQUEST> headerGetter) {
this.headerGetter = headerGetter;
return this;
}

/**
* Configures the instrumentation to emit experimental HTTP server metrics.
*
Expand All @@ -168,16 +164,14 @@ public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setSpanNameExtrac
return this;
}

public Instrumenter<REQUEST, RESPONSE> build() {
InstrumenterBuilder<REQUEST, RESPONSE> builder = builder();

if (headerGetter != null) {
return builder.buildServerInstrumenter(headerGetter);
}
return builder.buildInstrumenter(SpanKindExtractor.alwaysServer());
@CanIgnoreReturnValue
public DefaultHttpServerInstrumenterBuilder<REQUEST, RESPONSE> setBuilderCustomizer(
Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> builderCustomizer) {
this.builderCustomizer = builderCustomizer;
return this;
}

private InstrumenterBuilder<REQUEST, RESPONSE> builder() {
public Instrumenter<REQUEST, RESPONSE> build() {
SpanNameExtractor<? super REQUEST> spanNameExtractor =
spanNameExtractorTransformer.apply(httpSpanNameExtractorBuilder.build());

Expand All @@ -195,8 +189,12 @@ private InstrumenterBuilder<REQUEST, RESPONSE> builder() {
.addAttributesExtractor(HttpExperimentalAttributesExtractor.create(attributesGetter))
.addOperationMetrics(HttpServerExperimentalMetrics.get());
}
builderCustomizer.accept(builder);

return builder;
if (headerGetter != null) {
return builder.buildServerInstrumenter(headerGetter);
}
return builder.buildInstrumenter(SpanKindExtractor.alwaysServer());
Comment on lines +194 to +197
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any server instrumentations that don't provide a headerGetter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, they all do

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made it part of the ctor

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just found that ktor doesn't have the header getter - but this is an upcoming pr

}

@CanIgnoreReturnValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.instrumentation.api.internal;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapSetter;
Expand Down Expand Up @@ -67,10 +68,13 @@ public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> buildDownstrea
builder, setter, spanKindExtractor);
}

public static <REQUEST, RESPONSE> void propagateOperationListenersToOnEnd(
InstrumenterBuilder<REQUEST, RESPONSE> builder) {
@CanIgnoreReturnValue
public static <REQUEST, RESPONSE>
InstrumenterBuilder<REQUEST, RESPONSE> propagateOperationListenersToOnEnd(
InstrumenterBuilder<REQUEST, RESPONSE> builder) {
// instrumenterBuilderAccess is guaranteed to be non-null here
instrumenterBuilderAccess.propagateOperationListenersToOnEnd(builder);
return builder;
}

private InstrumenterUtil() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ public final class ApacheHttpClientTelemetryBuilder {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.apache-httpclient-4.3";
private final DefaultHttpClientInstrumenterBuilder<ApacheHttpClientRequest, HttpResponse> builder;
private final OpenTelemetry openTelemetry;

ApacheHttpClientTelemetryBuilder(OpenTelemetry openTelemetry) {
builder =
new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, ApacheHttpClientHttpAttributesGetter.INSTANCE);
this.openTelemetry = openTelemetry;
}

/**
Expand Down Expand Up @@ -110,7 +112,6 @@ public ApacheHttpClientTelemetryBuilder setSpanNameExtractor(
* ApacheHttpClientTelemetryBuilder}.
*/
public ApacheHttpClientTelemetry build() {
return new ApacheHttpClientTelemetry(
builder.build(), builder.getOpenTelemetry().getPropagators());
return new ApacheHttpClientTelemetry(builder.build(), openTelemetry.getPropagators());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ public final class ApacheHttpClient5TelemetryBuilder {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.apache-httpclient-5.2";
private final DefaultHttpClientInstrumenterBuilder<ApacheHttpClient5Request, HttpResponse>
builder;
private final OpenTelemetry openTelemetry;

ApacheHttpClient5TelemetryBuilder(OpenTelemetry openTelemetry) {
builder =
new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, ApacheHttpClient5HttpAttributesGetter.INSTANCE);
this.openTelemetry = openTelemetry;
}

/**
Expand Down Expand Up @@ -112,7 +114,6 @@ public ApacheHttpClient5TelemetryBuilder setSpanNameExtractor(
* ApacheHttpClient5TelemetryBuilder}.
*/
public ApacheHttpClient5Telemetry build() {
return new ApacheHttpClient5Telemetry(
builder.build(), builder.getOpenTelemetry().getPropagators());
return new ApacheHttpClient5Telemetry(builder.build(), openTelemetry.getPropagators());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ private ArmeriaInstrumenterBuilderFactory() {}
public static DefaultHttpServerInstrumenterBuilder<ServiceRequestContext, RequestLog>
getServerBuilder(OpenTelemetry openTelemetry) {
return new DefaultHttpServerInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, ArmeriaHttpServerAttributesGetter.INSTANCE)
.setHeaderGetter(RequestContextGetter.INSTANCE);
INSTRUMENTATION_NAME,
openTelemetry,
ArmeriaHttpServerAttributesGetter.INSTANCE,
RequestContextGetter.INSTANCE);
}

public static DefaultHttpClientInstrumenterBuilder<ClientRequestContext, RequestLog>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
public final class JavaHttpClientTelemetryBuilder {

private final DefaultHttpClientInstrumenterBuilder<HttpRequest, HttpResponse<?>> builder;
private final OpenTelemetry openTelemetry;

JavaHttpClientTelemetryBuilder(OpenTelemetry openTelemetry) {
builder = JavaHttpClientInstrumenterBuilderFactory.create(openTelemetry);
this.openTelemetry = openTelemetry;
}

/**
Expand Down Expand Up @@ -105,6 +107,6 @@ public JavaHttpClientTelemetryBuilder setSpanNameExtractor(

public JavaHttpClientTelemetry build() {
return new JavaHttpClientTelemetry(
builder.build(), new HttpHeadersSetter(builder.getOpenTelemetry().getPropagators()));
builder.build(), new HttpHeadersSetter(openTelemetry.getPropagators()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,9 @@

package io.opentelemetry.javaagent.instrumentation.netty.v3_8.server;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpExperimentalAttributesExtractor;
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpServerExperimentalMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerMetrics;
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute;
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanStatusExtractor;
import io.opentelemetry.instrumentation.netty.common.internal.NettyErrorHolder;
import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpServerInstrumenters;
import io.opentelemetry.javaagent.instrumentation.netty.v3_8.HttpRequestAndChannel;
import org.jboss.netty.handler.codec.http.HttpResponse;

Expand All @@ -25,37 +16,15 @@ final class NettyServerSingletons {
private static final Instrumenter<HttpRequestAndChannel, HttpResponse> INSTRUMENTER;

static {
NettyHttpServerAttributesGetter httpAttributesGetter = new NettyHttpServerAttributesGetter();

InstrumenterBuilder<HttpRequestAndChannel, HttpResponse> builder =
Instrumenter.<HttpRequestAndChannel, HttpResponse>builder(
GlobalOpenTelemetry.get(),
"io.opentelemetry.netty-3.8",
HttpSpanNameExtractor.builder(httpAttributesGetter)
.setKnownMethods(AgentCommonConfig.get().getKnownHttpRequestMethods())
.build())
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter))
.addAttributesExtractor(
HttpServerAttributesExtractor.builder(httpAttributesGetter)
.setCapturedRequestHeaders(AgentCommonConfig.get().getServerRequestHeaders())
.setCapturedResponseHeaders(AgentCommonConfig.get().getServerResponseHeaders())
.setKnownMethods(AgentCommonConfig.get().getKnownHttpRequestMethods())
.build())
.addOperationMetrics(HttpServerMetrics.get());
if (AgentCommonConfig.get().shouldEmitExperimentalHttpServerTelemetry()) {
builder
.addAttributesExtractor(HttpExperimentalAttributesExtractor.create(httpAttributesGetter))
.addOperationMetrics(HttpServerExperimentalMetrics.get());
}
INSTRUMENTER =
builder
.addContextCustomizer(
(context, requestAndChannel, startAttributes) -> NettyErrorHolder.init(context))
.addContextCustomizer(
HttpServerRoute.builder(httpAttributesGetter)
.setKnownMethods(AgentCommonConfig.get().getKnownHttpRequestMethods())
.build())
.buildServerInstrumenter(NettyHeadersGetter.INSTANCE);
JavaagentHttpServerInstrumenters.create(
"io.opentelemetry.netty-3.8",
new NettyHttpServerAttributesGetter(),
NettyHeadersGetter.INSTANCE,
builder ->
builder.addContextCustomizer(
(context, requestAndChannel, startAttributes) ->
NettyErrorHolder.init(context)));
}

public static Instrumenter<HttpRequestAndChannel, HttpResponse> instrumenter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.netty.v4.common.internal.client;

import io.netty.handler.codec.http.HttpResponse;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
import io.opentelemetry.instrumentation.netty.v4.common.HttpRequestAndChannel;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class NettyClientInstrumenterBuilderFactory {
private NettyClientInstrumenterBuilderFactory() {}

public static DefaultHttpClientInstrumenterBuilder<HttpRequestAndChannel, HttpResponse> create(
String instrumentationName, OpenTelemetry openTelemetry) {

return new DefaultHttpClientInstrumenterBuilder<>(
instrumentationName, openTelemetry, new NettyHttpClientAttributesGetter())
.setHeaderSetter(HttpRequestHeadersSetter.INSTANCE);
}
}
Loading
Loading