Add constructors/methods to the base tracers to enable injecting an OpenTelemetry instance (#2197)

* Add constructors/methods to the base tracers to enable injecting propagators.

* formatting

* deprecate old things. convert to non-deprecated where easily possible.

* formatting, always more formatting
This commit is contained in:
John Watson 2021-02-05 05:50:47 -08:00 committed by GitHub
parent e9a4b952dd
commit 644ee18666
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 18 deletions

View File

@ -6,6 +6,7 @@
package io.opentelemetry.instrumentation.api.tracer; package io.opentelemetry.instrumentation.api.tracer;
import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind; import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.api.trace.StatusCode;
@ -13,6 +14,7 @@ import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey; import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.instrumentation.api.InstrumentationVersion; import io.opentelemetry.instrumentation.api.InstrumentationVersion;
import io.opentelemetry.instrumentation.api.context.ContextPropagationDebug; import io.opentelemetry.instrumentation.api.context.ContextPropagationDebug;
@ -36,13 +38,32 @@ public abstract class BaseTracer {
ContextKey.named("opentelemetry-trace-auto-client-span-key"); ContextKey.named("opentelemetry-trace-auto-client-span-key");
protected final Tracer tracer; protected final Tracer tracer;
protected final ContextPropagators propagators;
public BaseTracer() { public BaseTracer() {
tracer = GlobalOpenTelemetry.getTracer(getInstrumentationName(), getVersion()); tracer = GlobalOpenTelemetry.getTracer(getInstrumentationName(), getVersion());
propagators = GlobalOpenTelemetry.getPropagators();
} }
/**
* Prefer to pass in an OpenTelemetry instance, rather than just a Tracer, so you don't have to
* use the GlobalOpenTelemetry Propagator instance.
*
* @deprecated prefer to pass in an OpenTelemetry instance, instead.
*/
@Deprecated
public BaseTracer(Tracer tracer) { public BaseTracer(Tracer tracer) {
this.tracer = tracer; this.tracer = tracer;
this.propagators = GlobalOpenTelemetry.getPropagators();
}
public BaseTracer(OpenTelemetry openTelemetry) {
this.tracer = openTelemetry.getTracer(getInstrumentationName(), getVersion());
this.propagators = openTelemetry.getPropagators();
}
public ContextPropagators getPropagators() {
return propagators;
} }
public Span startSpan(Class<?> clazz) { public Span startSpan(Class<?> clazz) {
@ -187,15 +208,29 @@ public abstract class BaseTracer {
span.recordException(throwable); span.recordException(throwable);
} }
public static <C> Context extract(C carrier, TextMapPropagator.Getter<C> getter) { /**
* Do extraction with the propagators from the GlobalOpenTelemetry instance. Not recommended.
*
* @deprecated We should eliminate all static usages so we can use the non-global propagators.
*/
@Deprecated
public static <C> Context extractWithGlobalPropagators(
C carrier, TextMapPropagator.Getter<C> getter) {
return extract(GlobalOpenTelemetry.getPropagators(), carrier, getter);
}
public <C> Context extract(C carrier, TextMapPropagator.Getter<C> getter) {
return extract(propagators, carrier, getter);
}
private static <C> Context extract(
ContextPropagators propagators, C carrier, TextMapPropagator.Getter<C> getter) {
ContextPropagationDebug.debugContextLeakIfEnabled(); ContextPropagationDebug.debugContextLeakIfEnabled();
// Using Context.ROOT here may be quite unexpected, but the reason is simple. // Using Context.ROOT here may be quite unexpected, but the reason is simple.
// We want either span context extracted from the carrier or invalid one. // We want either span context extracted from the carrier or invalid one.
// We DO NOT want any span context potentially lingering in the current context. // We DO NOT want any span context potentially lingering in the current context.
return GlobalOpenTelemetry.getPropagators() return propagators.getTextMapPropagator().extract(Context.root(), carrier, getter);
.getTextMapPropagator()
.extract(Context.root(), carrier, getter);
} }
/** Returns span of type SERVER from the current context or <code>null</code> if not found. */ /** Returns span of type SERVER from the current context or <code>null</code> if not found. */

View File

@ -7,7 +7,7 @@ package io.opentelemetry.instrumentation.api.tracer;
import static io.opentelemetry.api.trace.Span.Kind.CLIENT; import static io.opentelemetry.api.trace.Span.Kind.CLIENT;
import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Span.Kind; import io.opentelemetry.api.trace.Span.Kind;
import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanBuilder;
@ -32,6 +32,25 @@ public abstract class HttpClientTracer<REQUEST, CARRIER, RESPONSE> extends BaseT
protected static final String USER_AGENT = "User-Agent"; protected static final String USER_AGENT = "User-Agent";
protected HttpClientTracer() {
super();
}
/**
* Prefer to pass in an OpenTelemetry instance, rather than just a Tracer, so you don't have to
* use the GlobalOpenTelemetry Propagator instance.
*
* @deprecated prefer to pass in an OpenTelemetry instance, instead.
*/
@Deprecated
protected HttpClientTracer(Tracer tracer) {
super(tracer);
}
protected HttpClientTracer(OpenTelemetry openTelemetry) {
super(openTelemetry);
}
protected abstract String method(REQUEST request); protected abstract String method(REQUEST request);
@Nullable @Nullable
@ -53,14 +72,6 @@ public abstract class HttpClientTracer<REQUEST, CARRIER, RESPONSE> extends BaseT
protected abstract TextMapPropagator.Setter<CARRIER> getSetter(); protected abstract TextMapPropagator.Setter<CARRIER> getSetter();
protected HttpClientTracer() {
super();
}
protected HttpClientTracer(Tracer tracer) {
super(tracer);
}
public boolean shouldStartSpan(Context parentContext) { public boolean shouldStartSpan(Context parentContext) {
return shouldStartSpan(CLIENT, parentContext); return shouldStartSpan(CLIENT, parentContext);
} }
@ -90,7 +101,7 @@ public abstract class HttpClientTracer<REQUEST, CARRIER, RESPONSE> extends BaseT
throw new IllegalStateException( throw new IllegalStateException(
"getSetter() not defined but calling startScope(), either getSetter must be implemented or the scope should be setup manually"); "getSetter() not defined but calling startScope(), either getSetter must be implemented or the scope should be setup manually");
} }
GlobalOpenTelemetry.getPropagators().getTextMapPropagator().inject(context, carrier, setter); propagators.getTextMapPropagator().inject(context, carrier, setter);
} }
public void end(Context context, RESPONSE response) { public void end(Context context, RESPONSE response) {

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.tracer;
import static io.opentelemetry.api.trace.Span.Kind.SERVER; import static io.opentelemetry.api.trace.Span.Kind.SERVER;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.api.trace.Tracer;
@ -42,10 +43,21 @@ public abstract class HttpServerTracer<REQUEST, RESPONSE, CONNECTION, STORAGE> e
super(); super();
} }
/**
* Prefer to pass in an OpenTelemetry instance, rather than just a Tracer, so you don't have to
* use the GlobalOpenTelemetry Propagator instance.
*
* @deprecated prefer to pass in an OpenTelemetry instance, instead.
*/
@Deprecated
public HttpServerTracer(Tracer tracer) { public HttpServerTracer(Tracer tracer) {
super(tracer); super(tracer);
} }
public HttpServerTracer(OpenTelemetry openTelemetry) {
super(openTelemetry);
}
public Context startSpan(REQUEST request, CONNECTION connection, STORAGE storage, Method origin) { public Context startSpan(REQUEST request, CONNECTION connection, STORAGE storage, Method origin) {
String spanName = spanNameForMethod(origin); String spanName = spanNameForMethod(origin);
return startSpan(request, connection, storage, spanName); return startSpan(request, connection, storage, spanName);

View File

@ -15,7 +15,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope; import io.opentelemetry.context.Scope;
@ -111,7 +110,8 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation
@Override @Override
public HttpRequest generateRequest() throws IOException, HttpException { public HttpRequest generateRequest() throws IOException, HttpException {
HttpRequest request = delegate.generateRequest(); HttpRequest request = delegate.generateRequest();
GlobalOpenTelemetry.getPropagators() tracer()
.getPropagators()
.getTextMapPropagator() .getTextMapPropagator()
.inject(context, request, tracer().getSetter()); .inject(context, request, tracer().getSetter());
Span span = Span.fromContext(context); Span span = Span.fromContext(context);

View File

@ -5,7 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.rmi.context.server; package io.opentelemetry.javaagent.instrumentation.rmi.context.server;
import static io.opentelemetry.instrumentation.api.tracer.BaseTracer.extract; import static io.opentelemetry.instrumentation.api.tracer.BaseTracer.extractWithGlobalPropagators;
import static io.opentelemetry.javaagent.instrumentation.api.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT; import static io.opentelemetry.javaagent.instrumentation.api.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT;
import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload.GETTER; import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload.GETTER;
import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator.CONTEXT_CALL_ID; import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator.CONTEXT_CALL_ID;
@ -50,7 +50,7 @@ public class ContextDispatcher implements Dispatcher {
if (PROPAGATOR.isOperationWithPayload(operationId)) { if (PROPAGATOR.isOperationWithPayload(operationId)) {
ContextPayload payload = ContextPayload.read(in); ContextPayload payload = ContextPayload.read(in);
if (payload != null) { if (payload != null) {
Context context = extract(payload, GETTER); Context context = extractWithGlobalPropagators(payload, GETTER);
SpanContext spanContext = Span.fromContext(context).getSpanContext(); SpanContext spanContext = Span.fromContext(context).getSpanContext();
if (spanContext.isValid()) { if (spanContext.isValid()) {
THREAD_LOCAL_CONTEXT.set(context); THREAD_LOCAL_CONTEXT.set(context);