Convert play instrumentation to instrumenter api
MODIFY
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/ActionInstrumentation.java
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/ActionInstrumentation.java
@@ -7,18 +7,17 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_4;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
-import static io.opentelemetry.javaagent.instrumentation.play.v2_4.PlayTracer.tracer;
+import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_4.Play24Singletons.instrumenter;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_4.Play24Singletons.updateSpanNames;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
-import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
-import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
-import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@@ -55,7 +54,12 @@ public class ActionInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) Request<?> req,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- context = tracer().startSpan("play.request", SpanKind.INTERNAL);
+ Context parentContext = currentContext();
+ if (!instrumenter().shouldStart(parentContext, null)) {
+ return;
+ }
+
+ context = instrumenter().start(parentContext, null);
scope = context.makeCurrent();
}
@@ -67,18 +71,15 @@ public class ActionInstrumentation implements TypeInstrumentation {
@Advice.Return(readOnly = false) Future<Result> responseFuture,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- // Call onRequest on return after tags are populated.
- tracer().updateSpanName(Java8BytecodeBridge.spanFromContext(context), req);
- // set the span name on the upstream akka/netty span
- tracer().updateSpanName(ServerSpan.fromContextOrNull(context), req);
-
scope.close();
+
+ updateSpanNames(context, req);
// span finished in RequestCompleteCallback
if (throwable == null) {
responseFuture.onComplete(
new RequestCompleteCallback(context), ((Action<?>) thisAction).executionContext());
} else {
- tracer().endExceptionally(context, throwable);
+ instrumenter().end(context, null, null, throwable);
}
}
}

ADD
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/Play24Singletons.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.play.v2_4;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
+import play.api.mvc.Request;
+import scala.Option;
+
+public final class Play24Singletons {
+
+ private static final String SPAN_NAME = "play.request";
+ private static final Instrumenter<Void, Void> INSTRUMENTER =
+ Instrumenter.<Void, Void>builder(
+ GlobalOpenTelemetry.get(), "io.opentelemetry.play-2.4", s -> SPAN_NAME)
+ .newInstrumenter();
+
+ public static Instrumenter<Void, Void> instrumenter() {
+ return INSTRUMENTER;
+ }
+
+ public static void updateSpanNames(Context context, Request<?> request) {
+ String route = getRoute(request);
+ if (route == null) {
+ return;
+ }
+
+ Span.fromContext(context).updateName(route);
+ // set the span name on the upstream akka/netty span
+ Span serverSpan = ServerSpan.fromContextOrNull(context);
+ if (serverSpan != null) {
+ serverSpan.updateName(route);
+ }
+ }
+
+ private static String getRoute(Request<?> request) {
+ if (request != null) {
+ Option<String> pathOption = request.tags().get("ROUTE_PATTERN");
+ if (!pathOption.isEmpty()) {
+ return pathOption.get();
+ }
+ }
+ return null;
+ }
+
+ private Play24Singletons() {}
+}

DELETE
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayTracer.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.play.v2_4;
-
-import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
-import play.api.mvc.Request;
-import scala.Option;
-
-public class PlayTracer extends BaseTracer {
- private static final PlayTracer TRACER = new PlayTracer();
-
- public static PlayTracer tracer() {
- return TRACER;
- }
-
- public void updateSpanName(Span span, Request<?> request) {
- if (request != null) {
- Option<String> pathOption = request.tags().get("ROUTE_PATTERN");
- if (!pathOption.isEmpty()) {
- String path = pathOption.get();
- span.updateName(path);
- }
- }
- }
-
- @Override
- protected String getInstrumentationName() {
- return "io.opentelemetry.play-2.4";
- }
-}

MODIFY
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/RequestCompleteCallback.java
instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/RequestCompleteCallback.java
package io.opentelemetry.javaagent.instrumentation.play.v2_4;
-import static io.opentelemetry.javaagent.instrumentation.play.v2_4.PlayTracer.tracer;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_4.Play24Singletons.instrumenter;
import io.opentelemetry.context.Context;
import org.slf4j.Logger;
@@ -27,11 +27,7 @@ public class RequestCompleteCallback extends AbstractFunction1<Try<Result>, Obje
@Override
public Object apply(Try<Result> result) {
try {
- if (result.isFailure()) {
- tracer().endExceptionally(context, result.failed().get());
- } else {
- tracer().end(context);
- }
+ instrumenter().end(context, null, null, result.isFailure() ? result.failed().get() : null);
} catch (Throwable t) {
logger.debug("error in play instrumentation", t);
}

MODIFY
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/ActionInstrumentation.java
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/ActionInstrumentation.java
@@ -7,18 +7,17 @@ package io.opentelemetry.javaagent.instrumentation.play.v2_6;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
-import static io.opentelemetry.javaagent.instrumentation.play.v2_6.PlayTracer.tracer;
+import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_6.Play26Singletons.instrumenter;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_6.Play26Singletons.updateSpanNames;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
-import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
-import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
-import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@@ -55,7 +54,12 @@ public class ActionInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) Request<?> req,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- context = tracer().startSpan("play.request", SpanKind.INTERNAL);
+ Context parentContext = currentContext();
+ if (!instrumenter().shouldStart(parentContext, null)) {
+ return;
+ }
+
+ context = instrumenter().start(parentContext, null);
scope = context.makeCurrent();
}
@@ -67,12 +71,9 @@ public class ActionInstrumentation implements TypeInstrumentation {
@Advice.Return(readOnly = false) Future<Result> responseFuture,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
- // Call onRequest on return after tags are populated.
- tracer().updateSpanName(Java8BytecodeBridge.spanFromContext(context), req);
- // set the span name on the upstream akka/netty span
- tracer().updateSpanName(ServerSpan.fromContextOrNull(context), req);
-
scope.close();
+
+ updateSpanNames(context, req);
if (throwable == null) {
// span is finished when future completes
// not using responseFuture.onComplete() because that doesn't guarantee this handler span
@@ -81,7 +82,7 @@ public class ActionInstrumentation implements TypeInstrumentation {
ResponseFutureWrapper.wrap(
responseFuture, context, ((Action<?>) thisAction).executionContext());
} else {
- tracer().endExceptionally(context, throwable);
+ instrumenter().end(context, null, null, throwable);
}
}
}

RENAME
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayTracer.java
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/Play26Singletons.java
package io.opentelemetry.javaagent.instrumentation.play.v2_6;
+import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
-import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
+import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.Nullable;
@@ -16,12 +19,13 @@ import play.libs.typedmap.TypedKey;
import play.routing.Router;
import scala.Option;
-public class PlayTracer extends BaseTracer {
- private static final PlayTracer TRACER = new PlayTracer();
+public final class Play26Singletons {
- public static PlayTracer tracer() {
- return TRACER;
- }
+ private static final String SPAN_NAME = "play.request";
+ private static final Instrumenter<Void, Void> INSTRUMENTER =
+ Instrumenter.<Void, Void>builder(
+ GlobalOpenTelemetry.get(), "io.opentelemetry.play-2.6", s -> SPAN_NAME)
+ .newInstrumenter();
@Nullable private static final Method typedKeyGetUnderlying;
@@ -44,7 +48,25 @@ public class PlayTracer extends BaseTracer {
typedKeyGetUnderlying = typedKeyGetUnderlyingCheck;
}
- public void updateSpanName(Span span, Request request) {
+ public static Instrumenter<Void, Void> instrumenter() {
+ return INSTRUMENTER;
+ }
+
+ public static void updateSpanNames(Context context, Request<?> request) {
+ String route = getRoute(request);
+ if (route == null) {
+ return;
+ }
+
+ Span.fromContext(context).updateName(route);
+ // set the span name on the upstream akka/netty span
+ Span serverSpan = ServerSpan.fromContextOrNull(context);
+ if (serverSpan != null) {
+ serverSpan.updateName(route);
+ }
+ }
+
+ private static String getRoute(Request<?> request) {
if (request != null) {
// more about routes here:
// https://github.com/playframework/playframework/blob/master/documentation/manual/releases/release26/migration26/Migration26.md
@@ -62,14 +84,11 @@ public class PlayTracer extends BaseTracer {
}
}
if (defOption != null && !defOption.isEmpty()) {
- String path = defOption.get().path();
- span.updateName(path);
+ return defOption.get().path();
}
}
+ return null;
}
- @Override
- protected String getInstrumentationName() {
- return "io.opentelemetry.play-2.6";
- }
+ private Play26Singletons() {}
}

MODIFY
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/ResponseFutureWrapper.java
instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/ResponseFutureWrapper.java
package io.opentelemetry.javaagent.instrumentation.play.v2_6;
-import static io.opentelemetry.javaagent.instrumentation.play.v2_6.PlayTracer.tracer;
+import static io.opentelemetry.javaagent.instrumentation.play.v2_6.Play26Singletons.instrumenter;
import io.opentelemetry.context.Context;
import play.api.mvc.Result;
@@ -22,14 +22,14 @@ public class ResponseFutureWrapper {
new AbstractFunction1<Result, Result>() {
@Override
public Result apply(Result result) {
- tracer().end(context);
+ instrumenter().end(context, null, null, null);
return result;
}
},
new AbstractFunction1<Throwable, Throwable>() {
@Override
public Throwable apply(Throwable throwable) {
- tracer().endExceptionally(context, throwable);
+ instrumenter().end(context, null, null, throwable);
return throwable;
}
},

Convert play instrumentation to instrumenter api (#4853)