Skip to content

Commit 8e0b613

Browse files
authored
make play-ws and play-mvc indy-ready (open-telemetry#14782)
1 parent e7d67c4 commit 8e0b613

File tree

6 files changed

+128
-49
lines changed

6 files changed

+128
-49
lines changed

instrumentation/play/play-mvc/play-mvc-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
import com.google.auto.service.AutoService;
1212
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1313
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
14+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1415
import java.util.List;
1516
import net.bytebuddy.matcher.ElementMatcher;
1617

1718
@AutoService(InstrumentationModule.class)
18-
public class PlayInstrumentationModule extends InstrumentationModule {
19+
public class PlayInstrumentationModule extends InstrumentationModule
20+
implements ExperimentalInstrumentationModule {
1921

2022
public PlayInstrumentationModule() {
2123
super("play-mvc", "play-mvc-2.4", "play");
@@ -31,4 +33,9 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
3133
public List<TypeInstrumentation> typeInstrumentations() {
3234
return singletonList(new ActionInstrumentation());
3335
}
36+
37+
@Override
38+
public boolean isIndyReady() {
39+
return true;
40+
}
3441
}

instrumentation/play/play-mvc/play-mvc-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import java.util.List;
1415

1516
@AutoService(InstrumentationModule.class)
16-
public class PlayInstrumentationModule extends InstrumentationModule {
17+
public class PlayInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719

1820
public PlayInstrumentationModule() {
1921
super("play-mvc", "play-mvc-2.6", "play");
@@ -23,4 +25,9 @@ public PlayInstrumentationModule() {
2325
public List<TypeInstrumentation> typeInstrumentations() {
2426
return singletonList(new ActionInstrumentation());
2527
}
28+
29+
@Override
30+
public boolean isIndyReady() {
31+
return true;
32+
}
2633
}

instrumentation/play/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/PlayWsInstrumentationModule.java

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@
1414
import io.opentelemetry.context.Scope;
1515
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1616
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
17+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1718
import io.opentelemetry.javaagent.instrumentation.playws.AsyncHttpClientInstrumentation;
1819
import io.opentelemetry.javaagent.instrumentation.playws.HandlerPublisherInstrumentation;
1920
import java.util.List;
21+
import javax.annotation.Nullable;
2022
import net.bytebuddy.asm.Advice;
23+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2124
import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
2225
import play.shaded.ahc.org.asynchttpclient.Request;
2326
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
2427
import play.shaded.ahc.org.asynchttpclient.ws.WebSocketUpgradeHandler;
2528

2629
@AutoService(InstrumentationModule.class)
27-
public class PlayWsInstrumentationModule extends InstrumentationModule {
30+
public class PlayWsInstrumentationModule extends InstrumentationModule
31+
implements ExperimentalInstrumentationModule {
2832
public PlayWsInstrumentationModule() {
2933
super("play-ws", "play-ws-1.0");
3034
}
@@ -37,46 +41,79 @@ public List<TypeInstrumentation> typeInstrumentations() {
3741
new HandlerPublisherInstrumentation());
3842
}
3943

44+
@Override
45+
public boolean isIndyReady() {
46+
return true;
47+
}
48+
4049
@SuppressWarnings("unused")
4150
public static class ClientAdvice {
4251

43-
@Advice.OnMethodEnter(suppress = Throwable.class)
44-
public static void methodEnter(
45-
@Advice.Argument(0) Request request,
46-
@Advice.Argument(value = 1, readOnly = false) AsyncHandler<?> asyncHandler,
47-
@Advice.Local("otelContext") Context context,
48-
@Advice.Local("otelScope") Scope scope) {
49-
Context parentContext = currentContext();
50-
if (!instrumenter().shouldStart(parentContext, request)) {
51-
return;
52+
public static class AdviceScope {
53+
private final Context parentContext;
54+
private final Context context;
55+
private final Request request;
56+
private final Scope scope;
57+
58+
private AdviceScope(Context parentContext, Request request, Context context, Scope scope) {
59+
this.parentContext = parentContext;
60+
this.request = request;
61+
this.context = context;
62+
this.scope = scope;
5263
}
5364

54-
context = instrumenter().start(parentContext, request);
55-
scope = context.makeCurrent();
65+
@Nullable
66+
public static AdviceScope start(Request request) {
67+
Context parentContext = currentContext();
68+
if (!instrumenter().shouldStart(parentContext, request)) {
69+
return null;
70+
}
71+
Context context = instrumenter().start(parentContext, request);
72+
return new AdviceScope(parentContext, request, context, context.makeCurrent());
73+
}
5674

57-
if (asyncHandler instanceof StreamedAsyncHandler) {
58-
asyncHandler =
59-
new StreamedAsyncHandlerWrapper<>(
60-
(StreamedAsyncHandler<?>) asyncHandler, request, context, parentContext);
61-
} else if (!(asyncHandler instanceof WebSocketUpgradeHandler)) {
62-
// websocket upgrade handlers aren't supported
63-
asyncHandler = new AsyncHandlerWrapper<>(asyncHandler, request, context, parentContext);
75+
public AsyncHandler<?> wrap(AsyncHandler<?> handler) {
76+
if (handler instanceof StreamedAsyncHandler) {
77+
return new StreamedAsyncHandlerWrapper<>(
78+
(StreamedAsyncHandler<?>) handler, request, context, parentContext);
79+
} else if (!(handler instanceof WebSocketUpgradeHandler)) {
80+
// websocket upgrade handlers aren't supported
81+
return new AsyncHandlerWrapper<>(handler, request, context, parentContext);
82+
}
83+
return handler;
84+
}
85+
86+
public void end(@Nullable Throwable throwable) {
87+
scope.close();
88+
if (throwable != null) {
89+
instrumenter().end(context, request, null, throwable);
90+
}
6491
}
6592
}
6693

94+
@Advice.AssignReturned.ToArguments(@ToArgument(value = 1, index = 1))
95+
@Advice.OnMethodEnter(suppress = Throwable.class)
96+
public static Object[] methodEnter(
97+
@Advice.Argument(0) Request request,
98+
@Advice.Argument(1) AsyncHandler<?> originalAsyncHandler) {
99+
// intermediate variable required for inlined advice
100+
AsyncHandler<?> asyncHandler = originalAsyncHandler;
101+
AdviceScope adviceScope = AdviceScope.start(request);
102+
if (adviceScope != null) {
103+
asyncHandler = adviceScope.wrap(asyncHandler);
104+
}
105+
return new Object[] {adviceScope, asyncHandler};
106+
}
107+
67108
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
68109
public static void methodExit(
69110
@Advice.Argument(0) Request request,
70-
@Advice.Thrown Throwable throwable,
71-
@Advice.Local("otelContext") Context context,
72-
@Advice.Local("otelScope") Scope scope) {
73-
if (scope == null) {
74-
return;
75-
}
76-
scope.close();
111+
@Advice.Thrown @Nullable Throwable throwable,
112+
@Advice.Enter Object[] enterResult) {
77113

78-
if (throwable != null) {
79-
instrumenter().end(context, request, null, throwable);
114+
AdviceScope adviceScope = (AdviceScope) enterResult[0];
115+
if (adviceScope != null) {
116+
adviceScope.end(throwable);
80117
}
81118
}
82119
}

instrumentation/play/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/PlayWsInstrumentationModule.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,23 @@
1313
import io.opentelemetry.context.Context;
1414
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1515
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
16+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1617
import io.opentelemetry.javaagent.instrumentation.playws.AbstractBootstrapInstrumentation;
1718
import io.opentelemetry.javaagent.instrumentation.playws.AsyncHttpClientInstrumentation;
1819
import io.opentelemetry.javaagent.instrumentation.playws.HandlerPublisherInstrumentation;
1920
import java.util.List;
21+
import javax.annotation.Nullable;
2022
import net.bytebuddy.asm.Advice;
23+
import net.bytebuddy.asm.Advice.AssignReturned;
24+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2125
import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
2226
import play.shaded.ahc.org.asynchttpclient.Request;
2327
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
2428
import play.shaded.ahc.org.asynchttpclient.ws.WebSocketUpgradeHandler;
2529

2630
@AutoService(InstrumentationModule.class)
27-
public class PlayWsInstrumentationModule extends InstrumentationModule {
31+
public class PlayWsInstrumentationModule extends InstrumentationModule
32+
implements ExperimentalInstrumentationModule {
2833
public PlayWsInstrumentationModule() {
2934
super("play-ws", "play-ws-2.0");
3035
}
@@ -37,20 +42,26 @@ public List<TypeInstrumentation> typeInstrumentations() {
3742
new AbstractBootstrapInstrumentation());
3843
}
3944

45+
@Override
46+
public boolean isIndyReady() {
47+
return true;
48+
}
49+
4050
@SuppressWarnings("unused")
4151
public static class ClientAdvice {
4252

53+
@AssignReturned.ToArguments(@ToArgument(value = 1, index = 1))
4354
@Advice.OnMethodEnter(suppress = Throwable.class)
44-
public static void methodEnter(
55+
public static Object[] methodEnter(
4556
@Advice.Argument(0) Request request,
46-
@Advice.Argument(value = 1, readOnly = false) AsyncHandler<?> asyncHandler,
47-
@Advice.Local("otelContext") Context context) {
57+
@Advice.Argument(1) AsyncHandler<?> originalAsyncHandler) {
58+
AsyncHandler<?> asyncHandler = originalAsyncHandler;
4859
Context parentContext = currentContext();
4960
if (!instrumenter().shouldStart(parentContext, request)) {
50-
return;
61+
return new Object[] {null, asyncHandler};
5162
}
5263

53-
context = instrumenter().start(parentContext, request);
64+
Context context = instrumenter().start(parentContext, request);
5465

5566
if (asyncHandler instanceof StreamedAsyncHandler) {
5667
asyncHandler =
@@ -60,13 +71,15 @@ public static void methodEnter(
6071
// websocket upgrade handlers aren't supported
6172
asyncHandler = new AsyncHandlerWrapper<>(asyncHandler, request, context, parentContext);
6273
}
74+
return new Object[] {context, asyncHandler};
6375
}
6476

6577
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
6678
public static void methodExit(
6779
@Advice.Argument(0) Request request,
68-
@Advice.Thrown Throwable throwable,
69-
@Advice.Local("otelContext") Context context) {
80+
@Advice.Thrown @Nullable Throwable throwable,
81+
@Advice.Enter Object[] enterResult) {
82+
Context context = (Context) enterResult[0];
7083
if (context != null && throwable != null) {
7184
instrumenter().end(context, request, null, throwable);
7285
}

instrumentation/play/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/PlayWsInstrumentationModule.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,23 @@
1313
import io.opentelemetry.context.Context;
1414
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1515
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
16+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1617
import io.opentelemetry.javaagent.instrumentation.playws.AbstractBootstrapInstrumentation;
1718
import io.opentelemetry.javaagent.instrumentation.playws.AsyncHttpClientInstrumentation;
1819
import io.opentelemetry.javaagent.instrumentation.playws.HandlerPublisherInstrumentation;
1920
import java.util.List;
21+
import javax.annotation.Nullable;
2022
import net.bytebuddy.asm.Advice;
23+
import net.bytebuddy.asm.Advice.AssignReturned;
24+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2125
import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
2226
import play.shaded.ahc.org.asynchttpclient.Request;
2327
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
2428
import play.shaded.ahc.org.asynchttpclient.ws.WebSocketUpgradeHandler;
2529

2630
@AutoService(InstrumentationModule.class)
27-
public class PlayWsInstrumentationModule extends InstrumentationModule {
31+
public class PlayWsInstrumentationModule extends InstrumentationModule
32+
implements ExperimentalInstrumentationModule {
2833
public PlayWsInstrumentationModule() {
2934
super("play-ws", "play-ws-2.1");
3035
}
@@ -37,20 +42,26 @@ public List<TypeInstrumentation> typeInstrumentations() {
3742
new AbstractBootstrapInstrumentation());
3843
}
3944

45+
@Override
46+
public boolean isIndyReady() {
47+
return true;
48+
}
49+
4050
@SuppressWarnings("unused")
4151
public static class ClientAdvice {
4252

53+
@AssignReturned.ToArguments(@ToArgument(value = 1, index = 1))
4354
@Advice.OnMethodEnter(suppress = Throwable.class)
44-
public static void methodEnter(
55+
public static Object[] methodEnter(
4556
@Advice.Argument(0) Request request,
46-
@Advice.Argument(value = 1, readOnly = false) AsyncHandler<?> asyncHandler,
47-
@Advice.Local("otelContext") Context context) {
57+
@Advice.Argument(1) AsyncHandler<?> originalAsyncHandler) {
58+
AsyncHandler<?> asyncHandler = originalAsyncHandler;
4859
Context parentContext = currentContext();
4960
if (!instrumenter().shouldStart(parentContext, request)) {
50-
return;
61+
return new Object[] {null, asyncHandler};
5162
}
5263

53-
context = instrumenter().start(parentContext, request);
64+
Context context = instrumenter().start(parentContext, request);
5465

5566
if (asyncHandler instanceof StreamedAsyncHandler) {
5667
asyncHandler =
@@ -60,13 +71,15 @@ public static void methodEnter(
6071
// websocket upgrade handlers aren't supported
6172
asyncHandler = new AsyncHandlerWrapper<>(asyncHandler, request, context, parentContext);
6273
}
74+
return new Object[] {context, asyncHandler};
6375
}
6476

6577
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
6678
public static void methodExit(
6779
@Advice.Argument(0) Request request,
68-
@Advice.Thrown Throwable throwable,
69-
@Advice.Local("otelContext") Context context) {
80+
@Advice.Thrown @Nullable Throwable throwable,
81+
@Advice.Enter Object[] enterResult) {
82+
Context context = (Context) enterResult[0];
7083
if (context != null && throwable != null) {
7184
instrumenter().end(context, request, null, throwable);
7285
}

instrumentation/play/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HandlerPublisherInstrumentation.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1313
import net.bytebuddy.asm.Advice;
14+
import net.bytebuddy.asm.Advice.AssignReturned;
15+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
1416
import net.bytebuddy.description.type.TypeDescription;
1517
import net.bytebuddy.matcher.ElementMatcher;
1618
import org.reactivestreams.Subscriber;
@@ -31,10 +33,10 @@ public void transform(TypeTransformer transformer) {
3133
@SuppressWarnings("unused")
3234
public static class WrapSubscriberAdvice {
3335

36+
@AssignReturned.ToArguments(@ToArgument(0))
3437
@Advice.OnMethodEnter(suppress = Throwable.class)
35-
public static void enter(
36-
@Advice.Argument(value = 0, readOnly = false) Subscriber<?> subscriber) {
37-
subscriber = new SubscriberWrapper<>(subscriber, Java8BytecodeBridge.currentContext());
38+
public static Subscriber<?> enter(@Advice.Argument(0) Subscriber<?> subscriber) {
39+
return new SubscriberWrapper<>(subscriber, Java8BytecodeBridge.currentContext());
3840
}
3941
}
4042
}

0 commit comments

Comments
 (0)