Skip to content

Commit

Permalink
Remove reflection from builder (open-telemetry#11673)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitlinger committed Jun 27, 2024
1 parent 3037865 commit 0e218de
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.httpclient.JavaHttpClientTelemetry;
import io.opentelemetry.instrumentation.httpclient.internal.HttpHeadersSetter;
import io.opentelemetry.instrumentation.httpclient.internal.JavaHttpClientInstrumenterBuilderFactory;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
Expand All @@ -23,7 +23,7 @@ public class JavaHttpClientSingletons {

INSTRUMENTER =
JavaagentHttpClientInstrumenters.create(
JavaHttpClientTelemetry.builder(GlobalOpenTelemetry.get()));
JavaHttpClientInstrumenterBuilderFactory.create(GlobalOpenTelemetry.get()));
}

public static Instrumenter<HttpRequest, HttpResponse<?>> instrumenter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.httpclient.internal.HttpHeadersSetter;
import io.opentelemetry.instrumentation.httpclient.internal.JavaHttpClientAttributesGetter;
import io.opentelemetry.instrumentation.httpclient.internal.JavaHttpClientInstrumenterBuilderFactory;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
Expand All @@ -21,13 +21,10 @@

public final class JavaHttpClientTelemetryBuilder {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.java-http-client";
private final DefaultHttpClientInstrumenterBuilder<HttpRequest, HttpResponse<?>> builder;

JavaHttpClientTelemetryBuilder(OpenTelemetry openTelemetry) {
builder =
new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, JavaHttpClientAttributesGetter.INSTANCE);
builder = JavaHttpClientInstrumenterBuilderFactory.create(openTelemetry);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@
import java.util.List;
import javax.annotation.Nullable;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public enum JavaHttpClientAttributesGetter
enum JavaHttpClientAttributesGetter
implements HttpClientAttributesGetter<HttpRequest, HttpResponse<?>> {
INSTANCE;

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.httpclient.internal;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

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

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.java-http-client";

public static DefaultHttpClientInstrumenterBuilder<HttpRequest, HttpResponse<?>> create(
OpenTelemetry openTelemetry) {
return new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, JavaHttpClientAttributesGetter.INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.JettyClientTelemetry;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.JettyHttpClientInstrumenterBuilderFactory;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
Expand All @@ -16,7 +16,7 @@ public class JettyHttpClientSingletons {

private static final Instrumenter<Request, Response> INSTRUMENTER =
JavaagentHttpClientInstrumenters.create(
JettyClientTelemetry.builder(GlobalOpenTelemetry.get()));
JettyHttpClientInstrumenterBuilderFactory.create(GlobalOpenTelemetry.get()));

public static Instrumenter<Request, Response> instrumenter() {
return INSTRUMENTER;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.HttpHeaderSetter;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.JettyClientHttpAttributesGetter;
import io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal.JettyHttpClientInstrumenterBuilderFactory;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
Expand All @@ -24,16 +23,12 @@
/** A builder of {@link JettyClientTelemetry}. */
public final class JettyClientTelemetryBuilder {

private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jetty-httpclient-9.2";
private final DefaultHttpClientInstrumenterBuilder<Request, Response> builder;
private HttpClientTransport httpClientTransport;
private SslContextFactory sslContextFactory;

JettyClientTelemetryBuilder(OpenTelemetry openTelemetry) {
builder =
new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, JettyClientHttpAttributesGetter.INSTANCE)
.setHeaderSetter(HttpHeaderSetter.INSTANCE);
builder = JettyHttpClientInstrumenterBuilderFactory.create(openTelemetry);
}

@CanIgnoreReturnValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
import io.opentelemetry.context.propagation.TextMapSetter;
import org.eclipse.jetty.client.api.Request;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public enum HttpHeaderSetter implements TextMapSetter<Request> {
enum HttpHeaderSetter implements TextMapSetter<Request> {
INSTANCE;

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.jetty.httpclient.v9_2.internal;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public class JettyHttpClientInstrumenterBuilderFactory {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jetty-httpclient-9.2";

private JettyHttpClientInstrumenterBuilderFactory() {}

public static DefaultHttpClientInstrumenterBuilder<Request, Response> create(
OpenTelemetry openTelemetry) {
return new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, JettyClientHttpAttributesGetter.INSTANCE)
.setHeaderSetter(HttpHeaderSetter.INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientRequestResendCount;
import io.opentelemetry.instrumentation.okhttp.v3_0.OkHttpTelemetry;
import io.opentelemetry.instrumentation.okhttp.v3_0.internal.ConnectionErrorSpanInterceptor;
import io.opentelemetry.instrumentation.okhttp.v3_0.internal.OkHttpClientInstrumenterBuilderFactory;
import io.opentelemetry.instrumentation.okhttp.v3_0.internal.TracingInterceptor;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;
import okhttp3.Interceptor;
Expand All @@ -22,7 +22,8 @@
public final class OkHttp3Singletons {

private static final Instrumenter<Request, Response> INSTRUMENTER =
JavaagentHttpClientInstrumenters.create(OkHttpTelemetry.builder(GlobalOpenTelemetry.get()));
JavaagentHttpClientInstrumenters.create(
OkHttpClientInstrumenterBuilderFactory.create(GlobalOpenTelemetry.get()));

public static final Interceptor CONTEXT_INTERCEPTOR =
chain -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
import io.opentelemetry.instrumentation.okhttp.v3_0.internal.OkHttpAttributesGetter;
import io.opentelemetry.instrumentation.okhttp.v3_0.internal.OkHttpClientInstrumenterBuilderFactory;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
Expand All @@ -21,13 +21,10 @@
/** A builder of {@link OkHttpTelemetry}. */
public final class OkHttpTelemetryBuilder {

public static final String INSTRUMENTATION_NAME = "io.opentelemetry.okhttp-3.0";
private final DefaultHttpClientInstrumenterBuilder<Request, Response> builder;

OkHttpTelemetryBuilder(OpenTelemetry openTelemetry) {
builder =
new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, OkHttpAttributesGetter.INSTANCE);
builder = OkHttpClientInstrumenterBuilderFactory.create(openTelemetry);
}

/**
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.okhttp.v3_0.internal;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
import okhttp3.Request;
import okhttp3.Response;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public class OkHttpClientInstrumenterBuilderFactory {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.okhttp-3.0";

private OkHttpClientInstrumenterBuilderFactory() {}

public static DefaultHttpClientInstrumenterBuilder<Request, Response> create(
OpenTelemetry openTelemetry) {
return new DefaultHttpClientInstrumenterBuilder<>(
INSTRUMENTATION_NAME, openTelemetry, OkHttpAttributesGetter.INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter;
import java.lang.reflect.Field;
import java.util.function.Consumer;
import java.util.function.Supplier;

Expand All @@ -36,11 +35,9 @@ public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> create(
return create(instrumentationName, httpAttributesGetter, headerSetter, b -> {});
}

// this is where an HttpClientTelemetryBuilder interface would be nice
// instead of having to pass Object and using reflection to unwrap the underlying builder
public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> create(Object builder) {
DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> defaultBuilder = unwrapBuilder(builder);
return create(defaultBuilder, customizer -> {});
public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> create(
DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> builder) {
return create(builder, customizer -> {});
}

public static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> create(
Expand All @@ -64,34 +61,11 @@ private static <REQUEST, RESPONSE> Instrumenter<REQUEST, RESPONSE> create(
set(config::getKnownHttpRequestMethods, builder::setKnownMethods);
set(config::getClientRequestHeaders, builder::setCapturedRequestHeaders);
set(config::getClientResponseHeaders, builder::setCapturedResponseHeaders);
// is not exposed in the public API
set(config::getPeerServiceResolver, builder::setPeerServiceResolver);
set(
config::shouldEmitExperimentalHttpClientTelemetry,
builder::setEmitExperimentalHttpClientMetrics);
// is not exposed in the public API
builder.setBuilderCustomizer(builderCustomizer);
return builder.build();
}

/**
* This method is used to access the builder field of the builder object.
*
* <p>This approach allows us to re-use the existing builder classes from the library modules
*/
@SuppressWarnings("unchecked")
private static <REQUEST, RESPONSE>
DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE> unwrapBuilder(Object builder) {
if (builder instanceof DefaultHttpClientInstrumenterBuilder<?, ?>) {
return (DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE>) builder;
}
try {
Field field = builder.getClass().getDeclaredField("builder");
field.setAccessible(true);
return (DefaultHttpClientInstrumenterBuilder<REQUEST, RESPONSE>) field.get(builder);
} catch (Exception e) {
throw new IllegalStateException("Could not access builder field", e);
}
return builder.setBuilderCustomizer(builderCustomizer).build();
}

private static <T> void set(Supplier<T> supplier, Consumer<T> consumer) {
Expand Down

0 comments on commit 0e218de

Please sign in to comment.