Make BaseTracer#startSpan() return Context (#2232)

* Make BaseTracer#startSpan() return Context

* Update instrumentation/apache-camel-2.20/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachecamel/CamelEventNotifier.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* spotless

* Add Javadocs to BaseTracer

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
Mateusz Rzeszutek 2021-02-12 12:12:40 +01:00 committed by GitHub
parent d3931912f2
commit 0fbdcad1dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 321 additions and 270 deletions

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.api.tracer;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
@ -21,6 +22,20 @@ import java.lang.reflect.Method;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* Base class for all instrumentation specific tracer implementations.
*
* <p>Tracers should not use {@link Span} directly in their public APIs: ideally all lifecycle
* methods (ex. start/end methods) should return/accept {@link Context}.
*
* <p>The {@link BaseTracer} offers several {@code startSpan()} utility methods for creating bare
* spans without any attributes. If you want to provide some additional attributes on span start
* please consider writing your own specific {@code startSpan()} method in the your tracer.
*
* <p>When constructing {@link Span}s tracers should set all attributes available during
* construction on a {@link SpanBuilder} instead of a {@link Span}. This way {@code SpanProcessor}s
* are able to see those attributes in the {@code onStart()} method and can freely read/modify them.
*/
public abstract class BaseTracer {
// Keeps track of the server span for the current trace.
// TODO(anuraaga): Should probably be renamed to local root key since it could be a consumer span
@ -61,18 +76,29 @@ public abstract class BaseTracer {
return propagators;
}
public Span startSpan(Class<?> clazz) {
String spanName = spanNameForClass(clazz);
public Context startSpan(Class<?> clazz) {
return startSpan(spanNameForClass(clazz));
}
public Context startSpan(Method method) {
return startSpan(spanNameForMethod(method));
}
public Context startSpan(String spanName) {
return startSpan(spanName, SpanKind.INTERNAL);
}
public Span startSpan(Method method) {
String spanName = spanNameForMethod(method);
return startSpan(spanName, SpanKind.INTERNAL);
public Context startSpan(String spanName, SpanKind kind) {
return startSpan(Context.current(), spanName, kind);
}
public Span startSpan(String spanName, SpanKind kind) {
return tracer.spanBuilder(spanName).setSpanKind(kind).startSpan();
public Context startSpan(Context parentContext, String spanName, SpanKind kind) {
Span span = spanBuilder(spanName, kind).setParent(parentContext).startSpan();
return parentContext.with(span);
}
protected SpanBuilder spanBuilder(String spanName, SpanKind kind) {
return tracer.spanBuilder(spanName).setSpanKind(kind);
}
protected final Context withClientSpan(Context parentContext, Span span) {
@ -157,10 +183,22 @@ public abstract class BaseTracer {
end(Span.fromContext(context), endTimeNanos);
}
/**
* End span.
*
* @deprecated Use {@link #end(Context)} instead.
*/
@Deprecated
public void end(Span span) {
end(span, -1);
}
/**
* End span.
*
* @deprecated Use {@link #end(Context, long)} instead.
*/
@Deprecated
public void end(Span span, long endTimeNanos) {
if (endTimeNanos > 0) {
span.end(endTimeNanos, TimeUnit.NANOSECONDS);
@ -177,10 +215,22 @@ public abstract class BaseTracer {
endExceptionally(Span.fromContext(context), throwable, endTimeNanos);
}
/**
* End span.
*
* @deprecated Use {@link #endExceptionally(Context, Throwable)} instead.
*/
@Deprecated
public void endExceptionally(Span span, Throwable throwable) {
endExceptionally(span, throwable, -1);
}
/**
* End span.
*
* @deprecated Use {@link #endExceptionally(Context, Throwable, long)} instead.
*/
@Deprecated
public void endExceptionally(Span span, Throwable throwable, long endTimeNanos) {
span.setStatus(StatusCode.ERROR);
onError(span, unwrapThrowable(throwable));

View File

@ -32,7 +32,11 @@ public final class NetPeerUtils {
if (remoteConnection != null) {
InetAddress remoteAddress = remoteConnection.getAddress();
if (remoteAddress != null) {
setNetPeer(span, remoteAddress, remoteConnection.getPort());
setNetPeer(
span::setAttribute,
remoteAddress.getHostName(),
remoteAddress.getHostAddress(),
remoteConnection.getPort());
} else {
// Failed DNS lookup, the host string is the name.
setNetPeer(
@ -41,7 +45,7 @@ public final class NetPeerUtils {
}
}
public void setNetPeer(Span span, InetAddress remoteAddress, int port) {
public void setNetPeer(SpanBuilder span, InetAddress remoteAddress, int port) {
setNetPeer(
span::setAttribute, remoteAddress.getHostName(), remoteAddress.getHostAddress(), port);
}

View File

@ -59,10 +59,11 @@ final class CamelEventNotifier extends EventNotifierSupport {
String name =
sd.getOperationName(ese.getExchange(), ese.getEndpoint(), CamelDirection.OUTBOUND);
Span span = CamelTracer.TRACER.startSpan(name, sd.getInitiatorSpanKind());
Context context = CamelTracer.TRACER.startSpan(name, sd.getInitiatorSpanKind());
Span span = Span.fromContext(context);
sd.pre(span, ese.getExchange(), ese.getEndpoint(), CamelDirection.OUTBOUND);
ActiveSpanManager.activate(ese.getExchange(), span, sd.getInitiatorSpanKind());
CamelPropagationUtil.injectParent(Context.current(), ese.getExchange().getIn().getHeaders());
CamelPropagationUtil.injectParent(context, ese.getExchange().getIn().getHeaders());
LOG.debug("[Exchange sending] Initiator span started: {}", span);
}

View File

@ -5,8 +5,6 @@
package io.opentelemetry.javaagent.instrumentation.dropwizardviews;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
public class DropwizardTracer extends BaseTracer {
@ -16,10 +14,6 @@ public class DropwizardTracer extends BaseTracer {
return TRACER;
}
public Span startSpan(String spanName) {
return super.startSpan(spanName, SpanKind.INTERNAL);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.javaagent.dropwizard-views";

View File

@ -17,7 +17,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.dropwizard.views.View;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
@ -67,27 +67,27 @@ public class DropwizardViewsInstrumentationModule extends InstrumentationModule
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) View view,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
span = tracer().startSpan("Render " + view.getTemplateName());
scope = span.makeCurrent();
context = tracer().startSpan("Render " + view.getTemplateName());
scope = context.makeCurrent();
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
return;
}
scope.close();
if (throwable == null) {
tracer().end(span);
tracer().end(context);
} else {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
}
}
}

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.extannotations;
import static io.opentelemetry.javaagent.instrumentation.extannotations.TraceAnnotationTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import java.lang.reflect.Method;
import net.bytebuddy.asm.Advice;
@ -17,22 +17,22 @@ public class TraceAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Origin Method method,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan(method);
scope = span.makeCurrent();
context = tracer().startSpan(method);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) {
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -22,6 +22,7 @@ import com.twitter.finatra.http.contexts.RouteInfo;
import com.twitter.util.Future;
import com.twitter.util.FutureEventListener;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
@ -74,7 +75,7 @@ public class FinatraInstrumentationModule extends InstrumentationModule {
public static void nameSpan(
@Advice.FieldValue("routeInfo") RouteInfo routeInfo,
@Advice.FieldValue("clazz") Class<?> clazz,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
Span serverSpan = BaseTracer.getCurrentServerSpan();
@ -82,15 +83,15 @@ public class FinatraInstrumentationModule extends InstrumentationModule {
serverSpan.updateName(routeInfo.path());
}
span = tracer().startSpan(clazz);
scope = span.makeCurrent();
context = tracer().startSpan(clazz);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void setupCallback(
@Advice.Thrown Throwable throwable,
@Advice.Return Some<Future<Response>> responseOption,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
@ -99,33 +100,33 @@ public class FinatraInstrumentationModule extends InstrumentationModule {
if (throwable != null) {
scope.close();
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
return;
}
responseOption.get().addEventListener(new Listener(span, scope));
responseOption.get().addEventListener(new Listener(context, scope));
}
}
public static class Listener implements FutureEventListener<Response> {
private final Span span;
private final Context context;
private final Scope scope;
public Listener(Span span, Scope scope) {
this.span = span;
public Listener(Context context, Scope scope) {
this.context = context;
this.scope = scope;
}
@Override
public void onSuccess(Response response) {
scope.close();
tracer().end(span);
tracer().end(context);
}
@Override
public void onFailure(Throwable cause) {
scope.close();
tracer().endExceptionally(span, cause);
tracer().endExceptionally(context, cause);
}
}
}

View File

@ -9,8 +9,8 @@ import static io.opentelemetry.api.trace.SpanKind.CLIENT;
import io.grpc.Status;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.RpcClientTracer;
import io.opentelemetry.instrumentation.grpc.v1_5.common.GrpcHelper;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
@ -28,15 +28,18 @@ public class GrpcClientTracer extends RpcClientTracer {
return "grpc";
}
public Span startSpan(String name) {
SpanBuilder spanBuilder = tracer.spanBuilder(name).setSpanKind(CLIENT);
spanBuilder.setAttribute(SemanticAttributes.RPC_SYSTEM, getRpcSystem());
return spanBuilder.startSpan();
public Context startSpan(String name) {
Span span =
spanBuilder(name, CLIENT)
.setAttribute(SemanticAttributes.RPC_SYSTEM, getRpcSystem())
.startSpan();
return Context.current().with(span);
}
public void endSpan(Span span, Status status) {
span.setStatus(GrpcHelper.statusFromGrpcStatus(status), status.getDescription());
end(span);
public void end(Context context, Status status) {
Span.fromContext(context)
.setStatus(GrpcHelper.statusFromGrpcStatus(status), status.getDescription());
end(context);
}
@Override

View File

@ -54,16 +54,16 @@ public class TracingClientInterceptor implements ClientInterceptor {
public <REQUEST, RESPONSE> ClientCall<REQUEST, RESPONSE> interceptCall(
MethodDescriptor<REQUEST, RESPONSE> method, CallOptions callOptions, Channel next) {
String methodName = method.getFullMethodName();
Span span = tracer.startSpan(methodName);
Context context = tracer.startSpan(methodName);
Span span = Span.fromContext(context);
GrpcHelper.prepareSpan(span, methodName);
Context context = Context.current().with(span);
final ClientCall<REQUEST, RESPONSE> result;
try (Scope ignored = context.makeCurrent()) {
try {
// call other interceptors
result = next.newCall(method, callOptions);
} catch (Throwable e) {
tracer.endExceptionally(span, e);
tracer.endExceptionally(context, e);
throw e;
}
}
@ -98,20 +98,20 @@ public class TracingClientInterceptor implements ClientInterceptor {
@Override
public void start(Listener<RESPONSE> responseListener, Metadata headers) {
GlobalOpenTelemetry.getPropagators().getTextMapPropagator().inject(context, headers, SETTER);
try (Scope ignored = span.makeCurrent()) {
super.start(new TracingClientCallListener<>(responseListener, span, tracer), headers);
try (Scope ignored = context.makeCurrent()) {
super.start(new TracingClientCallListener<>(responseListener, context, tracer), headers);
} catch (Throwable e) {
tracer.endExceptionally(span, e);
tracer.endExceptionally(context, e);
throw e;
}
}
@Override
public void sendMessage(REQUEST message) {
try (Scope ignored = span.makeCurrent()) {
try (Scope ignored = context.makeCurrent()) {
super.sendMessage(message);
} catch (Throwable e) {
tracer.endExceptionally(span, e);
tracer.endExceptionally(context, e);
throw e;
}
}
@ -119,24 +119,26 @@ public class TracingClientInterceptor implements ClientInterceptor {
static final class TracingClientCallListener<RESPONSE>
extends ForwardingClientCallListener.SimpleForwardingClientCallListener<RESPONSE> {
private final Span span;
private final Context context;
private final GrpcClientTracer tracer;
private final AtomicLong messageId = new AtomicLong();
TracingClientCallListener(Listener<RESPONSE> delegate, Span span, GrpcClientTracer tracer) {
TracingClientCallListener(
Listener<RESPONSE> delegate, Context context, GrpcClientTracer tracer) {
super(delegate);
this.span = span;
this.context = context;
this.tracer = tracer;
}
@Override
public void onMessage(RESPONSE message) {
Span span = Span.fromContext(context);
Attributes attributes =
Attributes.of(
GrpcHelper.MESSAGE_TYPE, "SENT", GrpcHelper.MESSAGE_ID, messageId.incrementAndGet());
span.addEvent("message", attributes);
try (Scope ignored = span.makeCurrent()) {
try (Scope ignored = context.makeCurrent()) {
delegate().onMessage(message);
} catch (Throwable e) {
tracer.addThrowable(span, e);
@ -145,21 +147,21 @@ public class TracingClientInterceptor implements ClientInterceptor {
@Override
public void onClose(Status status, Metadata trailers) {
try (Scope ignored = span.makeCurrent()) {
try (Scope ignored = context.makeCurrent()) {
delegate().onClose(status, trailers);
} catch (Throwable e) {
tracer.endExceptionally(span, e);
tracer.endExceptionally(context, e);
throw e;
}
tracer.endSpan(span, status);
tracer.end(context, status);
}
@Override
public void onReady() {
try (Scope ignored = span.makeCurrent()) {
try (Scope ignored = context.makeCurrent()) {
delegate().onReady();
} catch (Throwable e) {
tracer.endExceptionally(span, e);
tracer.endExceptionally(context, e);
throw e;
}
}

View File

@ -13,7 +13,7 @@ import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
@ -59,7 +59,7 @@ public class JdbcDataSourceInstrumentationModule extends InstrumentationModule {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void start(
@Advice.This DataSource ds,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
// TODO this is very strange condition
if (!Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
@ -67,13 +67,13 @@ public class JdbcDataSourceInstrumentationModule extends InstrumentationModule {
return;
}
span = tracer().startSpan(ds.getClass().getSimpleName() + ".getConnection", CLIENT);
scope = span.makeCurrent();
context = tracer().startSpan(ds.getClass().getSimpleName() + ".getConnection", CLIENT);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) {
if (scope == null) {
@ -82,9 +82,9 @@ public class JdbcDataSourceInstrumentationModule extends InstrumentationModule {
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -13,8 +13,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map;
@ -51,24 +51,24 @@ public class HttpJspPageInstrumentation implements TypeInstrumentation {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) HttpServletRequest req,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan(tracer().spanNameOnRender(req), SpanKind.INTERNAL);
tracer().onRender(span, req);
scope = span.makeCurrent();
context = tracer().startSpan(tracer().spanNameOnRender(req), SpanKind.INTERNAL);
tracer().onRender(context, req);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -11,8 +11,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map;
@ -41,28 +41,28 @@ public class JspCompilationContextInstrumentation implements TypeInstrumentation
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.This JspCompilationContext jspCompilationContext,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span =
context =
tracer().startSpan(tracer().spanNameOnCompile(jspCompilationContext), SpanKind.INTERNAL);
scope = span.makeCurrent();
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.This JspCompilationContext jspCompilationContext,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
// Decorate on return because additional properties are available
tracer().onCompile(span, jspCompilationContext);
tracer().onCompile(context, jspCompilationContext);
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -6,6 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.jsp;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import java.net.URI;
import java.net.URISyntaxException;
@ -29,8 +30,9 @@ public class JspTracer extends BaseTracer {
: "Compile " + jspCompilationContext.getJspFile();
}
public void onCompile(Span span, JspCompilationContext jspCompilationContext) {
public void onCompile(Context context, JspCompilationContext jspCompilationContext) {
if (jspCompilationContext != null) {
Span span = Span.fromContext(context);
Compiler compiler = jspCompilationContext.getCompiler();
if (compiler != null) {
span.setAttribute("jsp.compiler", compiler.getClass().getName());
@ -49,7 +51,9 @@ public class JspTracer extends BaseTracer {
return "Render " + spanName;
}
public void onRender(Span span, HttpServletRequest req) {
public void onRender(Context context, HttpServletRequest req) {
Span span = Span.fromContext(context);
Object forwardOrigin = req.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
if (forwardOrigin instanceof String) {
span.setAttribute("jsp.forwardOrigin", forwardOrigin.toString());

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.kafkaclients;
import static io.opentelemetry.api.trace.SpanKind.PRODUCER;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.apache.kafka.clients.ApiVersions;
@ -22,9 +23,9 @@ public class KafkaProducerTracer extends BaseTracer {
}
public Span startProducerSpan(ProducerRecord<?, ?> record) {
Span span = startSpan(spanNameOnProduce(record), PRODUCER);
SpanBuilder span = spanBuilder(spanNameOnProduce(record), PRODUCER);
onProduce(span, record);
return span;
return span.startSpan();
}
// Do not inject headers for batch versions below 2
@ -43,14 +44,14 @@ public class KafkaProducerTracer extends BaseTracer {
return record.topic() + " send";
}
public void onProduce(Span span, ProducerRecord<?, ?> record) {
public void onProduce(SpanBuilder span, ProducerRecord<?, ?> record) {
span.setAttribute(SemanticAttributes.MESSAGING_SYSTEM, "kafka");
span.setAttribute(SemanticAttributes.MESSAGING_DESTINATION_KIND, "topic");
span.setAttribute(SemanticAttributes.MESSAGING_DESTINATION, record.topic());
Integer partition = record.partition();
if (partition != null) {
span.setAttribute(SemanticAttributes.MESSAGING_KAFKA_PARTITION, partition);
span.setAttribute(SemanticAttributes.MESSAGING_KAFKA_PARTITION, partition.longValue());
}
if (record.value() == null) {
span.setAttribute(SemanticAttributes.MESSAGING_KAFKA_TOMBSTONE, true);

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.methods;
import static io.opentelemetry.javaagent.instrumentation.methods.MethodTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import java.lang.reflect.Method;
import net.bytebuddy.asm.Advice;
@ -17,22 +17,22 @@ public class MethodAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Origin Method method,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan(method);
scope = span.makeCurrent();
context = tracer().startSpan(method);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) {
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -5,6 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.netty.v3_8;
import static io.opentelemetry.javaagent.instrumentation.netty.v3_8.client.NettyHttpClientTracer.tracer;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonMap;
@ -12,13 +13,11 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.instrumentation.netty.v3_8.client.NettyHttpClientTracer;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map;
import net.bytebuddy.asm.Advice;
@ -75,8 +74,8 @@ public class ChannelFutureListenerInstrumentation implements TypeInstrumentation
}
// TODO pass Context into Tracer.startSpan() and then don't need this scoping
Scope parentScope = parentContext.makeCurrent();
Span errorSpan = NettyHttpClientTracer.tracer().startSpan("CONNECT", SpanKind.CLIENT);
NettyHttpClientTracer.tracer().endExceptionally(errorSpan, cause);
Context errorContext = tracer().startSpan("CONNECT", SpanKind.CLIENT);
tracer().endExceptionally(errorContext, cause);
return parentScope;
}

View File

@ -5,6 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.netty.v4_0;
import static io.opentelemetry.javaagent.instrumentation.netty.v4_0.client.NettyHttpClientTracer.tracer;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonMap;
@ -13,11 +14,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.netty.channel.ChannelFuture;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.client.NettyHttpClientTracer;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map;
import net.bytebuddy.asm.Advice;
@ -63,8 +62,8 @@ public class ChannelFutureListenerInstrumentation implements TypeInstrumentation
return null;
}
Scope parentScope = parentContext.makeCurrent();
Span span = NettyHttpClientTracer.tracer().startSpan("CONNECT", SpanKind.CLIENT);
NettyHttpClientTracer.tracer().endExceptionally(span, cause);
Context errorContext = tracer().startSpan("CONNECT", SpanKind.CLIENT);
tracer().endExceptionally(errorContext, cause);
return parentScope;
}

View File

@ -5,6 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.netty.v4_1;
import static io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyHttpClientTracer.tracer;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed;
import static java.util.Collections.singletonMap;
@ -13,12 +14,10 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.netty.channel.ChannelFuture;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.netty.v4_1.AttributeKeys;
import io.opentelemetry.javaagent.instrumentation.netty.v4_1.client.NettyHttpClientTracer;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
import java.util.Map;
import net.bytebuddy.asm.Advice;
@ -64,8 +63,8 @@ public class ChannelFutureListenerInstrumentation implements TypeInstrumentation
return null;
}
Scope parentScope = parentContext.makeCurrent();
Span errorSpan = NettyHttpClientTracer.tracer().startSpan("CONNECT", SpanKind.CLIENT);
NettyHttpClientTracer.tracer().endExceptionally(errorSpan, cause);
Context errorContext = tracer().startSpan("CONNECT", SpanKind.CLIENT);
tracer().endExceptionally(errorContext, cause);
return parentScope;
}

View File

@ -35,7 +35,8 @@ public class WithSpanTracer extends BaseTracer {
Method method,
io.opentelemetry.api.trace.SpanKind kind) {
io.opentelemetry.api.trace.Span span =
startSpan(spanNameForMethodWithAnnotation(applicationAnnotation, method), kind);
spanBuilder(spanNameForMethodWithAnnotation(applicationAnnotation, method), kind)
.startSpan();
if (kind == io.opentelemetry.api.trace.SpanKind.SERVER) {
return withServerSpan(context, span);
}

View File

@ -7,8 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_3;
import static io.opentelemetry.javaagent.instrumentation.play.v2_3.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import net.bytebuddy.asm.Advice;
@ -22,10 +22,10 @@ public class PlayAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) final Request<?> req,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = span.makeCurrent();
context = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
@ -34,16 +34,16 @@ public class PlayAdvice {
@Advice.Thrown Throwable throwable,
@Advice.Argument(0) Request<?> req,
@Advice.Return(readOnly = false) Future<Result> responseFuture,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
scope.close();
// span finished in RequestCompleteCallback
if (throwable == null) {
responseFuture.onComplete(
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
new RequestCompleteCallback(context), ((Action<?>) thisAction).executionContext());
} else {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
}
// set the span name on the upstream akka/netty span

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_3;
import static io.opentelemetry.javaagent.instrumentation.play.v2_3.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.api.mvc.Result;
@ -17,19 +17,19 @@ public class RequestCompleteCallback extends scala.runtime.AbstractFunction1<Try
private static final Logger log = LoggerFactory.getLogger(RequestCompleteCallback.class);
private final Span span;
private final Context context;
public RequestCompleteCallback(Span span) {
this.span = span;
public RequestCompleteCallback(Context context) {
this.context = context;
}
@Override
public Object apply(Try<Result> result) {
try {
if (result.isFailure()) {
tracer().endExceptionally(span, result.failed().get());
tracer().endExceptionally(context, result.failed().get());
} else {
tracer().end(span);
tracer().end(context);
}
} catch (Throwable t) {
log.debug("error in play instrumentation", t);

View File

@ -7,10 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_4;
import static io.opentelemetry.javaagent.instrumentation.play.v2_4.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import net.bytebuddy.asm.Advice;
import play.api.mvc.Action;
import play.api.mvc.Headers;
@ -22,10 +23,10 @@ public class PlayAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) Request<?> req,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = span.makeCurrent();
context = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
@ -34,18 +35,18 @@ public class PlayAdvice {
@Advice.Thrown Throwable throwable,
@Advice.Argument(0) Request<?> req,
@Advice.Return(readOnly = false) Future<Result> responseFuture,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
// Call onRequest on return after tags are populated.
tracer().updateSpanName(span, req);
tracer().updateSpanName(Java8BytecodeBridge.spanFromContext(context), req);
scope.close();
// span finished in RequestCompleteCallback
if (throwable == null) {
responseFuture.onComplete(
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
new RequestCompleteCallback(context), ((Action<?>) thisAction).executionContext());
} else {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
}
// set the span name on the upstream akka/netty span

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_4;
import static io.opentelemetry.javaagent.instrumentation.play.v2_4.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.api.mvc.Result;
@ -17,19 +17,19 @@ public class RequestCompleteCallback extends scala.runtime.AbstractFunction1<Try
private static final Logger log = LoggerFactory.getLogger(RequestCompleteCallback.class);
private final Span span;
private final Context context;
public RequestCompleteCallback(Span span) {
this.span = span;
public RequestCompleteCallback(Context context) {
this.context = context;
}
@Override
public Object apply(Try<Result> result) {
try {
if (result.isFailure()) {
tracer().endExceptionally(span, result.failed().get());
tracer().endExceptionally(context, result.failed().get());
} else {
tracer().end(span);
tracer().end(context);
}
} catch (Throwable t) {
log.debug("error in play instrumentation", t);

View File

@ -7,10 +7,11 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_6;
import static io.opentelemetry.javaagent.instrumentation.play.v2_6.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import net.bytebuddy.asm.Advice;
import play.api.mvc.Action;
import play.api.mvc.Request;
@ -21,10 +22,10 @@ public class PlayAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) Request<?> req,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
span = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = span.makeCurrent();
context = tracer().startSpan("play.request", SpanKind.INTERNAL);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
@ -33,18 +34,18 @@ public class PlayAdvice {
@Advice.Thrown Throwable throwable,
@Advice.Argument(0) Request<?> req,
@Advice.Return(readOnly = false) Future<Result> responseFuture,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
// Call onRequest on return after tags are populated.
tracer().updateSpanName(span, req);
tracer().updateSpanName(Java8BytecodeBridge.spanFromContext(context), req);
scope.close();
// span finished in RequestCompleteCallback
if (throwable == null) {
responseFuture.onComplete(
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
new RequestCompleteCallback(context), ((Action<?>) thisAction).executionContext());
} else {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
}
// set the span name on the upstream akka/netty span

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_6;
import static io.opentelemetry.javaagent.instrumentation.play.v2_6.PlayTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.api.mvc.Result;
@ -17,19 +17,19 @@ public class RequestCompleteCallback extends scala.runtime.AbstractFunction1<Try
private static final Logger log = LoggerFactory.getLogger(RequestCompleteCallback.class);
private final Span span;
private final Context context;
public RequestCompleteCallback(Span span) {
this.span = span;
public RequestCompleteCallback(Context context) {
this.context = context;
}
@Override
public Object apply(Try<Result> result) {
try {
if (result.isFailure()) {
tracer().endExceptionally(span, result.failed().get());
tracer().endExceptionally(context, result.failed().get());
} else {
tracer().end(span);
tracer().end(context);
}
} catch (Throwable t) {
log.debug("error in play instrumentation", t);

View File

@ -35,13 +35,14 @@ public class RabbitTracer extends BaseTracer {
public Span startSpan(String method, Connection connection) {
SpanKind kind = method.equals("Channel.basicPublish") ? PRODUCER : CLIENT;
Span span = startSpan(method, kind);
span.setAttribute(SemanticAttributes.MESSAGING_SYSTEM, "rabbitmq");
span.setAttribute(SemanticAttributes.MESSAGING_DESTINATION_KIND, "queue");
SpanBuilder span =
spanBuilder(method, kind)
.setAttribute(SemanticAttributes.MESSAGING_SYSTEM, "rabbitmq")
.setAttribute(SemanticAttributes.MESSAGING_DESTINATION_KIND, "queue");
NetPeerUtils.INSTANCE.setNetPeer(span, connection.getAddress(), connection.getPort());
return span;
return span.startSpan();
}
public Span startGetSpan(
@ -55,20 +56,20 @@ public class RabbitTracer extends BaseTracer {
.setAttribute(SemanticAttributes.MESSAGING_OPERATION, "receive")
.setStartTimestamp(startTime, TimeUnit.MILLISECONDS);
Span span = spanBuilder.startSpan();
if (response != null) {
span.setAttribute(
spanBuilder.setAttribute(
SemanticAttributes.MESSAGING_DESTINATION,
normalizeExchangeName(response.getEnvelope().getExchange()));
span.setAttribute("messaging.rabbitmq.routing_key", response.getEnvelope().getRoutingKey());
span.setAttribute(
spanBuilder.setAttribute(
"messaging.rabbitmq.routing_key", response.getEnvelope().getRoutingKey());
spanBuilder.setAttribute(
SemanticAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES,
(long) response.getBody().length);
}
NetPeerUtils.INSTANCE.setNetPeer(span, connection.getAddress(), connection.getPort());
onGet(span, queue);
NetPeerUtils.INSTANCE.setNetPeer(spanBuilder, connection.getAddress(), connection.getPort());
onGet(spanBuilder, queue);
return span;
return spanBuilder.startSpan();
}
public Span startDeliverySpan(
@ -120,7 +121,7 @@ public class RabbitTracer extends BaseTracer {
return (queue.startsWith("amq.gen-") ? "<generated>" : queue) + " receive";
}
public void onGet(Span span, String queue) {
public void onGet(SpanBuilder span, String queue) {
span.setAttribute("rabbitmq.command", "basic.get");
span.setAttribute("rabbitmq.queue", queue);
}

View File

@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.instrumentation.ratpack.RatpackTracer.t
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import java.util.Optional;
import net.bytebuddy.asm.Advice;
import ratpack.handling.Context;
@ -17,11 +18,13 @@ public class ErrorHandlerAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void captureThrowable(
@Advice.Argument(0) Context ctx, @Advice.Argument(1) Throwable throwable) {
Optional<Span> span = ctx.maybeGet(Span.class);
if (span.isPresent()) {
Optional<io.opentelemetry.context.Context> otelContext =
ctx.maybeGet(io.opentelemetry.context.Context.class);
if (otelContext.isPresent()) {
// TODO this emulates old behaviour of BaseDecorator. Has to review
span.get().setStatus(StatusCode.ERROR);
tracer().addThrowable(span.get(), throwable);
Span span = Java8BytecodeBridge.spanFromContext(otelContext.get());
span.setStatus(StatusCode.ERROR);
tracer().addThrowable(span, throwable);
}
}
}

View File

@ -16,7 +16,7 @@ public class RatpackTracer extends BaseTracer {
return TRACER;
}
public Span onContext(Span span, Context ctx) {
public void onContext(io.opentelemetry.context.Context otelContext, Context ctx) {
String description = ctx.getPathBinding().getDescription();
if (description == null || description.isEmpty()) {
description = "/";
@ -24,9 +24,7 @@ public class RatpackTracer extends BaseTracer {
description = "/" + description;
}
span.updateName(description);
return span;
Span.fromContext(otelContext).updateName(description);
}
@Override

View File

@ -8,7 +8,6 @@ package io.opentelemetry.javaagent.instrumentation.ratpack;
import static io.opentelemetry.javaagent.instrumentation.ratpack.RatpackTracer.tracer;
import io.netty.util.Attribute;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.netty.v4_1.AttributeKeys;
@ -25,21 +24,22 @@ public final class TracingHandler implements Handler {
io.opentelemetry.context.Context serverSpanContext = spanAttribute.get();
// Relying on executor instrumentation to assume the netty span is in context as the parent.
Span ratpackSpan = tracer().startSpan("ratpack.handler", SpanKind.INTERNAL);
ctx.getExecution().add(ratpackSpan);
io.opentelemetry.context.Context ratpackContext =
tracer().startSpan("ratpack.handler", SpanKind.INTERNAL);
ctx.getExecution().add(ratpackContext);
ctx.getResponse()
.beforeSend(
response -> {
if (serverSpanContext != null) {
// Rename the netty span name with the ratpack route.
tracer().onContext(Span.fromContext(serverSpanContext), ctx);
tracer().onContext(serverSpanContext, ctx);
}
tracer().onContext(ratpackSpan, ctx);
tracer().end(ratpackSpan);
tracer().onContext(ratpackContext, ctx);
tracer().end(ratpackContext);
});
try (Scope ignored = ratpackSpan.makeCurrent()) {
try (Scope ignored = ratpackContext.makeCurrent()) {
ctx.next();
// exceptions are captured by ServerErrorHandlerInstrumentation
}

View File

@ -14,7 +14,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
@ -60,30 +60,30 @@ public class RmiClientInstrumentationModule extends InstrumentationModule {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(value = 1) Method method,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
// TODO replace with client span check
if (!Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
return;
}
span = tracer().startSpan(method);
scope = span.makeCurrent();
context = tracer().startSpan(method);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
return;
}
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.rmi.client;
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.RpcClientTracer;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.lang.reflect.Method;
@ -21,17 +21,18 @@ public class RmiClientTracer extends RpcClientTracer {
}
@Override
public Span startSpan(Method method) {
public Context startSpan(Method method) {
String serviceName = method.getDeclaringClass().getName();
String methodName = method.getName();
SpanBuilder spanBuilder =
tracer.spanBuilder(serviceName + "/" + methodName).setSpanKind(CLIENT);
spanBuilder.setAttribute(SemanticAttributes.RPC_SYSTEM, getRpcSystem());
spanBuilder.setAttribute(SemanticAttributes.RPC_SERVICE, serviceName);
spanBuilder.setAttribute(SemanticAttributes.RPC_METHOD, methodName);
Span span =
spanBuilder(serviceName + "/" + methodName, CLIENT)
.setAttribute(SemanticAttributes.RPC_SYSTEM, getRpcSystem())
.setAttribute(SemanticAttributes.RPC_SERVICE, serviceName)
.setAttribute(SemanticAttributes.RPC_METHOD, methodName)
.startSpan();
return spanBuilder.startSpan();
return Context.current().with(span);
}
@Override

View File

@ -36,13 +36,10 @@ public class TracedOnSubscribe<T> implements Observable.OnSubscribe<T> {
@Override
public void call(Subscriber<? super T> subscriber) {
// TODO pass Context into Tracer.startSpan() and then don't need this outer scoping
try (Scope ignored = parentContext.makeCurrent()) {
Span span = tracer.startSpan(operationName, spanKind);
decorateSpan(span);
try (Scope ignored1 = span.makeCurrent()) {
delegate.call(new TracedSubscriber<>(Context.current(), subscriber, tracer));
}
Context context = tracer.startSpan(parentContext, operationName, spanKind);
decorateSpan(Span.fromContext(context));
try (Scope ignored = context.makeCurrent()) {
delegate.call(new TracedSubscriber<>(context, subscriber, tracer));
}
}

View File

@ -81,7 +81,7 @@ public class RequestDispatcherInstrumentationModule extends InstrumentationModul
@Advice.Origin Method method,
@Advice.This RequestDispatcher dispatcher,
@Advice.Local("_originalContext") Object originalContext,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Argument(0) ServletRequest request) {
@ -116,7 +116,7 @@ public class RequestDispatcherInstrumentationModule extends InstrumentationModul
}
try (Scope ignored = parent.makeCurrent()) {
span = tracer().startSpan(method);
context = tracer().startSpan(method);
// save the original servlet span before overwriting the request attribute, so that it can
// be
@ -124,17 +124,16 @@ public class RequestDispatcherInstrumentationModule extends InstrumentationModul
originalContext = request.getAttribute(CONTEXT_ATTRIBUTE);
// this tells the dispatched servlet to use the current span as the parent for its work
Context newContext = Java8BytecodeBridge.currentContext().with(span);
request.setAttribute(CONTEXT_ATTRIBUTE, newContext);
request.setAttribute(CONTEXT_ATTRIBUTE, context);
}
scope = span.makeCurrent();
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stop(
@Advice.Local("_originalContext") Object originalContext,
@Advice.Argument(0) ServletRequest request,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) {
if (scope == null) {
@ -151,9 +150,9 @@ public class RequestDispatcherInstrumentationModule extends InstrumentationModul
request.setAttribute(CONTEXT_ATTRIBUTE, originalContext);
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -14,7 +14,7 @@ import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
@ -63,33 +63,33 @@ public class HttpServletResponseInstrumentationModule extends InstrumentationMod
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void start(
@Advice.Origin Method method,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") CallDepth callDepth) {
callDepth = CallDepthThreadLocalMap.getCallDepth(HttpServletResponse.class);
// Don't want to generate a new top-level span
if (callDepth.getAndIncrement() == 0
&& Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
span = tracer().startSpan(method);
scope = span.makeCurrent();
context = tracer().startSpan(method);
scope = context.makeCurrent();
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") CallDepth callDepth) {
if (callDepth.decrementAndGet() == 0 && span != null) {
if (callDepth.decrementAndGet() == 0 && context != null) {
CallDepthThreadLocalMap.reset(HttpServletResponse.class);
scope.close();
if (throwable != null) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
} else {
tracer().end(span);
tracer().end(context);
}
}
}

View File

@ -7,7 +7,6 @@ package io.opentelemetry.javaagent.instrumentation.spring.batch.item;
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
@ -59,13 +58,9 @@ public class ItemTracer extends BaseTracer {
String jobName = chunkContext.getStepContext().getJobName();
String stepName = chunkContext.getStepContext().getStepName();
Span span =
tracer
.spanBuilder("BatchJob " + jobName + "." + stepName + "." + itemOperationName)
.setSpanKind(INTERNAL)
.startSpan();
return currentContext.with(span);
return startSpan(
currentContext, "BatchJob " + jobName + "." + stepName + "." + itemOperationName, INTERNAL);
}
@Override

View File

@ -7,7 +7,6 @@ package io.opentelemetry.javaagent.instrumentation.spring.batch.job;
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import org.springframework.batch.core.JobExecution;
@ -21,8 +20,7 @@ public class JobExecutionTracer extends BaseTracer {
public Context startSpan(JobExecution jobExecution) {
String jobName = jobExecution.getJobInstance().getJobName();
Span span = startSpan("BatchJob " + jobName, INTERNAL);
return Context.current().with(span);
return startSpan("BatchJob " + jobName, INTERNAL);
}
@Override

View File

@ -7,7 +7,6 @@ package io.opentelemetry.javaagent.instrumentation.spring.batch.step;
import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import org.springframework.batch.core.StepExecution;
@ -22,8 +21,7 @@ public class StepExecutionTracer extends BaseTracer {
public Context startSpan(StepExecution stepExecution) {
String jobName = stepExecution.getJobExecution().getJobInstance().getJobName();
String stepName = stepExecution.getStepName();
Span span = startSpan("BatchJob " + jobName + "." + stepName, INTERNAL);
return Context.current().with(span);
return startSpan("BatchJob " + jobName + "." + stepName, INTERNAL);
}
@Override

View File

@ -12,7 +12,7 @@ import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
@ -102,17 +102,15 @@ public class SpringDataInstrumentationModule extends InstrumentationModule {
return methodInvocation.proceed();
}
Span span = tracer().startSpan(invokedMethod);
Object result;
try (Scope ignored = span.makeCurrent()) {
result = methodInvocation.proceed();
tracer().end(span);
Context context = tracer().startSpan(invokedMethod);
try (Scope ignored = context.makeCurrent()) {
Object result = methodInvocation.proceed();
tracer().end(context);
return result;
} catch (Throwable t) {
tracer().endExceptionally(span, t);
tracer().endExceptionally(context, t);
throw t;
}
return result;
}
}
}

View File

@ -7,8 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.scheduling;
import static io.opentelemetry.javaagent.instrumentation.spring.scheduling.SpringSchedulingTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
public class SpringSchedulingRunnableWrapper implements Runnable {
@ -23,13 +22,13 @@ public class SpringSchedulingRunnableWrapper implements Runnable {
if (runnable == null) {
return;
}
Span span = tracer().startSpan(tracer().spanNameOnRun(runnable), SpanKind.INTERNAL);
try (Scope ignored = span.makeCurrent()) {
Context context = tracer().startSpan(runnable);
try (Scope ignored = context.makeCurrent()) {
runnable.run();
tracer().end(span);
tracer().end(context);
} catch (Throwable throwable) {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
throw throwable;
}
}

View File

@ -5,6 +5,8 @@
package io.opentelemetry.javaagent.instrumentation.spring.scheduling;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
@ -20,7 +22,11 @@ public class SpringSchedulingTracer extends BaseTracer {
return "io.opentelemetry.javaagent.spring-scheduling";
}
public String spanNameOnRun(Runnable runnable) {
public Context startSpan(Runnable runnable) {
return startSpan(spanNameOnRun(runnable), SpanKind.INTERNAL);
}
private String spanNameOnRun(Runnable runnable) {
if (runnable instanceof ScheduledMethodRunnable) {
ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable) runnable;
return spanNameForMethod(scheduledMethodRunnable.getMethod());

View File

@ -7,11 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.spring.webflux.server;
import static io.opentelemetry.javaagent.instrumentation.spring.webflux.server.SpringWebfluxHttpServerTracer.tracer;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import net.bytebuddy.asm.Advice;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@ -28,9 +26,7 @@ public class DispatcherHandlerAdvice {
@Advice.Local("otelScope") Scope otelScope,
@Advice.Local("otelContext") Context otelContext) {
Span span = tracer().startSpan("DispatcherHandler.handle", SpanKind.INTERNAL);
otelContext = Java8BytecodeBridge.currentContext().with(span);
otelContext = tracer().startSpan("DispatcherHandler.handle", SpanKind.INTERNAL);
// Unfortunately Netty EventLoop is not instrumented well enough to attribute all work to the
// right things so we have to store the context in request itself.
exchange.getAttributes().put(AdviceUtils.CONTEXT_ATTRIBUTE, otelContext);

View File

@ -13,7 +13,7 @@ import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
@ -55,19 +55,19 @@ public class AnnotatedMethodInstrumentation implements TypeInstrumentation {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void startSpan(
@Advice.Origin Method method,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (CallDepthThreadLocalMap.incrementCallDepth(PayloadRoot.class) > 0) {
return;
}
span = tracer().startSpan(method);
scope = span.makeCurrent();
context = tracer().startSpan(method);
scope = context.makeCurrent();
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Thrown Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
if (scope == null) {
return;
@ -76,9 +76,9 @@ public class AnnotatedMethodInstrumentation implements TypeInstrumentation {
scope.close();
if (throwable == null) {
tracer().end(span);
tracer().end(context);
} else {
tracer().endExceptionally(span, throwable);
tracer().endExceptionally(context, throwable);
}
}
}

View File

@ -6,6 +6,8 @@
package io.opentelemetry.javaagent.instrumentation.spring.ws;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.lang.reflect.Method;
@ -18,13 +20,13 @@ public class SpringWsTracer extends BaseTracer {
return TRACER;
}
public Span startSpan(Method method) {
Span springWsSpan = super.startSpan(method);
springWsSpan.setAttribute(
SemanticAttributes.CODE_NAMESPACE, method.getDeclaringClass().getName());
springWsSpan.setAttribute(SemanticAttributes.CODE_FUNCTION, method.getName());
return springWsSpan;
public Context startSpan(Method method) {
Span span =
spanBuilder(spanNameForMethod(method), SpanKind.INTERNAL)
.setAttribute(SemanticAttributes.CODE_NAMESPACE, method.getDeclaringClass().getName())
.setAttribute(SemanticAttributes.CODE_FUNCTION, method.getName())
.startSpan();
return Context.current().with(span);
}
@Override