Skip to content

Commit a8e6374

Browse files
authored
make Pekko instrumentation to indy compatible (#12428)
1 parent 7b1e6b5 commit a8e6374

File tree

6 files changed

+60
-48
lines changed

6 files changed

+60
-48
lines changed

instrumentation/pekko/pekko-actor-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkoactor/v1_0/PekkoScheduleInstrumentation.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
import static net.bytebuddy.matcher.ElementMatchers.named;
99
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1010

11-
import io.opentelemetry.context.Context;
1211
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
1312
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1413
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1514
import net.bytebuddy.asm.Advice;
15+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
1616
import net.bytebuddy.description.type.TypeDescription;
1717
import net.bytebuddy.matcher.ElementMatcher;
1818

@@ -43,22 +43,20 @@ public void transform(TypeTransformer transformer) {
4343
@SuppressWarnings("unused")
4444
public static class ScheduleAdvice {
4545

46+
@Advice.AssignReturned.ToArguments(@ToArgument(2))
4647
@Advice.OnMethodEnter(suppress = Throwable.class)
47-
public static void enterSchedule(
48-
@Advice.Argument(value = 2, readOnly = false) Runnable runnable) {
49-
Context context = Java8BytecodeBridge.currentContext();
50-
runnable = context.wrap(runnable);
48+
public static Runnable enterSchedule(@Advice.Argument(value = 2) Runnable runnable) {
49+
return Java8BytecodeBridge.currentContext().wrap(runnable);
5150
}
5251
}
5352

5453
@SuppressWarnings("unused")
5554
public static class ScheduleOnceAdvice {
5655

56+
@Advice.AssignReturned.ToArguments(@ToArgument(1))
5757
@Advice.OnMethodEnter(suppress = Throwable.class)
58-
public static void enterScheduleOnce(
59-
@Advice.Argument(value = 1, readOnly = false) Runnable runnable) {
60-
Context context = Java8BytecodeBridge.currentContext();
61-
runnable = context.wrap(runnable);
58+
public static Runnable enterScheduleOnce(@Advice.Argument(value = 1) Runnable runnable) {
59+
return Java8BytecodeBridge.currentContext().wrap(runnable);
6260
}
6361
}
6462
}

instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/client/HttpExtClientInstrumentation.java

+33-23
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1717
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1818
import net.bytebuddy.asm.Advice;
19+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
1920
import net.bytebuddy.description.type.TypeDescription;
2021
import net.bytebuddy.matcher.ElementMatcher;
2122
import org.apache.pekko.http.scaladsl.HttpExt;
@@ -39,46 +40,55 @@ public void transform(TypeTransformer transformer) {
3940

4041
@SuppressWarnings("unused")
4142
public static class SingleRequestAdvice {
42-
43+
@Advice.AssignReturned.ToArguments(@ToArgument(value = 0, index = 0))
4344
@Advice.OnMethodEnter(suppress = Throwable.class)
44-
public static void methodEnter(
45-
@Advice.Argument(value = 0, readOnly = false) HttpRequest request,
46-
@Advice.Local("otelContext") Context context,
47-
@Advice.Local("otelScope") Scope scope) {
45+
public static Object[] methodEnter(@Advice.Argument(value = 0) HttpRequest request) {
4846
Context parentContext = currentContext();
4947
if (!instrumenter().shouldStart(parentContext, request)) {
50-
return;
48+
return new Object[] {request, null, null};
5149
}
5250

53-
context = instrumenter().start(parentContext, request);
54-
scope = context.makeCurrent();
51+
Context context = instrumenter().start(parentContext, request);
52+
Scope scope = context.makeCurrent();
53+
5554
// Request is immutable, so we have to assign new value once we update headers
56-
request = setter().inject(request);
55+
HttpRequest modifiedRequest = setter().inject(request);
56+
57+
// Using array return form allows to provide at the same time
58+
// - an argument value to override
59+
// - propagate state from enter to exit advice
60+
//
61+
// As an array is already allocated we avoid creating another object
62+
// by storing context and scope directly into the array.
63+
return new Object[] {modifiedRequest, context, scope};
5764
}
5865

66+
@Advice.AssignReturned.ToReturned
5967
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
60-
public static void methodExit(
68+
public static Future<HttpResponse> methodExit(
6169
@Advice.Argument(0) HttpRequest request,
6270
@Advice.This HttpExt thiz,
63-
@Advice.Return(readOnly = false) Future<HttpResponse> responseFuture,
71+
@Advice.Return Future<HttpResponse> responseFuture,
6472
@Advice.Thrown Throwable throwable,
65-
@Advice.Local("otelContext") Context context,
66-
@Advice.Local("otelScope") Scope scope) {
67-
if (scope == null) {
68-
return;
73+
@Advice.Enter Object[] enter) {
74+
75+
if (!(enter[1] instanceof Context) || !(enter[2] instanceof Scope)) {
76+
return null;
6977
}
78+
((Scope) enter[2]).close();
79+
Context context = (Context) enter[1];
7080

71-
scope.close();
72-
if (throwable == null) {
73-
responseFuture.onComplete(
74-
new OnCompleteHandler(context, request), thiz.system().dispatcher());
75-
} else {
81+
if (throwable != null) {
7682
instrumenter().end(context, request, null, throwable);
83+
return responseFuture;
7784
}
78-
if (responseFuture != null) {
79-
responseFuture =
80-
FutureWrapper.wrap(responseFuture, thiz.system().dispatcher(), currentContext());
85+
if (responseFuture == null) {
86+
return null;
8187
}
88+
responseFuture.onComplete(
89+
new OnCompleteHandler(context, request), thiz.system().dispatcher());
90+
91+
return FutureWrapper.wrap(responseFuture, thiz.system().dispatcher(), currentContext());
8292
}
8393
}
8494
}

instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/HttpExtServerInstrumentation.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
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.ToArguments.ToArgument;
1415
import net.bytebuddy.description.type.TypeDescription;
1516
import net.bytebuddy.matcher.ElementMatcher;
1617
import org.apache.pekko.http.scaladsl.model.HttpRequest;
@@ -34,10 +35,11 @@ public void transform(TypeTransformer transformer) {
3435
@SuppressWarnings("unused")
3536
public static class PekkoBindAndHandleAdvice {
3637

38+
@Advice.AssignReturned.ToArguments(@ToArgument(0))
3739
@Advice.OnMethodEnter(suppress = Throwable.class)
38-
public static void wrapHandler(
39-
@Advice.Argument(value = 0, readOnly = false) Flow<HttpRequest, HttpResponse, ?> handler) {
40-
handler = PekkoFlowWrapper.wrap(handler);
40+
public static Flow<HttpRequest, HttpResponse, ?> wrapHandler(
41+
@Advice.Argument(value = 0) Flow<HttpRequest, HttpResponse, ?> handler) {
42+
return PekkoFlowWrapper.wrap(handler);
4143
}
4244
}
4345
}

instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerInstrumentationModule.java

+5-5
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 PekkoHttpServerInstrumentationModule extends InstrumentationModule {
19+
public class PekkoHttpServerInstrumentationModule extends InstrumentationModule
20+
implements ExperimentalInstrumentationModule {
1921
public PekkoHttpServerInstrumentationModule() {
2022
super("pekko-http", "pekko-http-1.0", "pekko-http-server");
2123
}
@@ -28,10 +30,8 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
2830
}
2931

3032
@Override
31-
public boolean isIndyModule() {
32-
// PekkoHttpServerInstrumentationModule and PekkoHttpServerRouteInstrumentationModule share
33-
// PekkoRouteHolder class
34-
return false;
33+
public String getModuleGroup() {
34+
return "pekko-server";
3535
}
3636

3737
@Override

instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerSourceInstrumentation.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
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.ToArguments.ToArgument;
1415
import net.bytebuddy.description.type.TypeDescription;
1516
import net.bytebuddy.matcher.ElementMatcher;
1617
import org.apache.pekko.http.scaladsl.model.HttpRequest;
@@ -33,10 +34,11 @@ public void transform(TypeTransformer transformer) {
3334
@SuppressWarnings("unused")
3435
public static class PekkoBindAndHandleAdvice {
3536

37+
@Advice.AssignReturned.ToArguments(@ToArgument(0))
3638
@Advice.OnMethodEnter(suppress = Throwable.class)
37-
public static void wrapHandler(
38-
@Advice.Argument(value = 0, readOnly = false) Flow<HttpRequest, HttpResponse, ?> handler) {
39-
handler = PekkoFlowWrapper.wrap(handler);
39+
public static Flow<HttpRequest, HttpResponse, ?> wrapHandler(
40+
@Advice.Argument(value = 0) Flow<HttpRequest, HttpResponse, ?> handler) {
41+
return PekkoFlowWrapper.wrap(handler);
4042
}
4143
}
4244
}

instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/route/PekkoHttpServerRouteInstrumentationModule.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@
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
/**
1617
* This instrumentation applies to classes in pekko-http.jar while
1718
* PekkoHttpServerInstrumentationModule applies to classes in pekko-http-core.jar
1819
*/
1920
@AutoService(InstrumentationModule.class)
20-
public class PekkoHttpServerRouteInstrumentationModule extends InstrumentationModule {
21+
public class PekkoHttpServerRouteInstrumentationModule extends InstrumentationModule
22+
implements ExperimentalInstrumentationModule {
2123
public PekkoHttpServerRouteInstrumentationModule() {
2224
super("pekko-http", "pekko-http-1.0", "pekko-http-server", "pekko-http-server-route");
2325
}
2426

2527
@Override
26-
public boolean isIndyModule() {
27-
// PekkoHttpServerInstrumentationModule and PekkoHttpServerRouteInstrumentationModule share
28-
// PekkoRouteHolder class
29-
return false;
28+
public String getModuleGroup() {
29+
return "pekko-server";
3030
}
3131

3232
@Override

0 commit comments

Comments
 (0)