Skip to content

Commit b5492e8

Browse files
indy ready migration - part1 (#13759)
Co-authored-by: Jonas Kunz <[email protected]> Co-authored-by: Jonas Kunz <[email protected]>
1 parent 05deb0e commit b5492e8

File tree

15 files changed

+206
-88
lines changed

15 files changed

+206
-88
lines changed

instrumentation/activej-http-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/activejhttp/ActivejAsyncServletInstrumentation.java

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1717
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
1818

19-
import io.activej.http.AsyncServlet;
2019
import io.activej.http.HttpRequest;
2120
import io.activej.http.HttpResponse;
2221
import io.activej.promise.Promise;
2322
import io.opentelemetry.context.Context;
2423
import io.opentelemetry.context.Scope;
2524
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2625
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
26+
import javax.annotation.Nullable;
2727
import net.bytebuddy.asm.Advice;
28+
import net.bytebuddy.asm.Advice.AssignReturned;
2829
import net.bytebuddy.description.type.TypeDescription;
2930
import net.bytebuddy.matcher.ElementMatcher;
3031

@@ -52,39 +53,57 @@ public void transform(TypeTransformer transformer) {
5253
@SuppressWarnings("unused")
5354
public static class ServeAdvice {
5455

55-
@Advice.OnMethodEnter(suppress = Throwable.class)
56-
public static void methodEnter(
57-
@Advice.This AsyncServlet asyncServlet,
58-
@Advice.Argument(0) HttpRequest request,
59-
@Advice.Local("otelContext") Context context,
60-
@Advice.Local("otelScope") Scope scope,
61-
@Advice.Local("httpRequest") HttpRequest httpRequest) {
62-
Context parentContext = currentContext();
63-
httpRequest = request;
64-
if (!instrumenter().shouldStart(parentContext, request)) {
65-
return;
56+
public static class AdviceScope {
57+
private final HttpRequest httpRequest;
58+
private final Context context;
59+
private final Scope scope;
60+
61+
private AdviceScope(Context context, Scope scope, HttpRequest httpRequest) {
62+
this.context = context;
63+
this.scope = scope;
64+
this.httpRequest = httpRequest;
65+
}
66+
67+
@Nullable
68+
public static AdviceScope start(HttpRequest request) {
69+
Context parentContext = currentContext();
70+
if (!instrumenter().shouldStart(parentContext, request)) {
71+
return null;
72+
}
73+
Context context = instrumenter().start(parentContext, request);
74+
return new AdviceScope(context, context.makeCurrent(), request);
75+
}
76+
77+
public Promise<HttpResponse> end(Promise<HttpResponse> responsePromise, Throwable throwable) {
78+
scope.close();
79+
Promise<HttpResponse> returnValue = responsePromise;
80+
if (throwable != null) {
81+
instrumenter().end(context, httpRequest, null, throwable);
82+
return responsePromise;
83+
} else {
84+
return PromiseWrapper.wrap(responsePromise, httpRequest, context);
85+
}
6686
}
67-
context = instrumenter().start(parentContext, request);
68-
scope = context.makeCurrent();
6987
}
7088

89+
@Nullable
90+
@Advice.OnMethodEnter(suppress = Throwable.class)
91+
public static AdviceScope methodEnter(@Advice.Argument(0) HttpRequest request) {
92+
return AdviceScope.start(request);
93+
}
94+
95+
@AssignReturned.ToReturned
7196
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
72-
public static void methodExit(
73-
@Advice.This AsyncServlet asyncServlet,
74-
@Advice.Return(readOnly = false) Promise<HttpResponse> responsePromise,
97+
public static Promise<HttpResponse> methodExit(
98+
@Advice.Return Promise<HttpResponse> responsePromise,
7599
@Advice.Thrown Throwable throwable,
76-
@Advice.Local("otelContext") Context context,
77-
@Advice.Local("otelScope") Scope scope,
78-
@Advice.Local("httpRequest") HttpRequest httpRequest) {
79-
if (scope == null) {
80-
return;
81-
}
82-
scope.close();
83-
if (throwable != null) {
84-
instrumenter().end(context, httpRequest, null, throwable);
85-
} else {
86-
responsePromise = PromiseWrapper.wrap(responsePromise, httpRequest, context);
100+
@Advice.Enter @Nullable AdviceScope adviceScope) {
101+
102+
if (adviceScope == null) {
103+
return responsePromise;
87104
}
105+
106+
return adviceScope.end(responsePromise, throwable);
88107
}
89108
}
90109
}

instrumentation/activej-http-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/activejhttp/ActivejHttpServerInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,23 @@
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 ActivejHttpServerInstrumentationModule extends InstrumentationModule {
19+
public class ActivejHttpServerInstrumentationModule extends InstrumentationModule
20+
implements ExperimentalInstrumentationModule {
1921

2022
public ActivejHttpServerInstrumentationModule() {
2123
super("activej-http", "activej-http-6.0");
2224
}
2325

26+
@Override
27+
public boolean isIndyReady() {
28+
return true;
29+
}
30+
2431
@Override
2532
public List<TypeInstrumentation> typeInstrumentations() {
2633
return singletonList(new ActivejAsyncServletInstrumentation());

instrumentation/akka/akka-actor-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkaactor/AkkaActorInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,21 @@
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 AkkaActorInstrumentationModule extends InstrumentationModule {
17+
public class AkkaActorInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719
public AkkaActorInstrumentationModule() {
1820
super("akka-actor", "akka-actor-2.3");
1921
}
2022

23+
@Override
24+
public boolean isIndyReady() {
25+
return true;
26+
}
27+
2128
@Override
2229
public List<TypeInstrumentation> typeInstrumentations() {
2330
return asList(

instrumentation/akka/akka-actor-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkaactor/AkkaScheduleInstrumentation.java

Lines changed: 8 additions & 6 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

@@ -41,20 +43,20 @@ public void transform(TypeTransformer transformer) {
4143
@SuppressWarnings("unused")
4244
public static class ScheduleAdvice {
4345

46+
@AssignReturned.ToArguments(@ToArgument(2))
4447
@Advice.OnMethodEnter(suppress = Throwable.class)
45-
public static void enterSchedule(
46-
@Advice.Argument(value = 2, readOnly = false) Runnable runnable) {
47-
runnable = AkkaSchedulerTaskWrapper.wrap(runnable);
48+
public static Runnable enterSchedule(@Advice.Argument(2) Runnable runnable) {
49+
return AkkaSchedulerTaskWrapper.wrap(runnable);
4850
}
4951
}
5052

5153
@SuppressWarnings("unused")
5254
public static class ScheduleOnceAdvice {
5355

56+
@AssignReturned.ToArguments(@ToArgument(1))
5457
@Advice.OnMethodEnter(suppress = Throwable.class)
55-
public static void enterScheduleOnce(
56-
@Advice.Argument(value = 1, readOnly = false) Runnable runnable) {
57-
runnable = AkkaSchedulerTaskWrapper.wrap(runnable);
58+
public static Runnable enterScheduleOnce(@Advice.Argument(1) Runnable runnable) {
59+
return AkkaSchedulerTaskWrapper.wrap(runnable);
5860
}
5961
}
6062
}

instrumentation/akka/akka-actor-fork-join-2.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkaactor/AkkaActorForkJoinInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,21 @@
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 AkkaActorForkJoinInstrumentationModule extends InstrumentationModule {
17+
public class AkkaActorForkJoinInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719
public AkkaActorForkJoinInstrumentationModule() {
1820
super("akka-actor-fork-join", "akka-actor-fork-join-2.5", "akka-actor");
1921
}
2022

23+
@Override
24+
public boolean isIndyReady() {
25+
return true;
26+
}
27+
2128
@Override
2229
public List<TypeInstrumentation> typeInstrumentations() {
2330
return asList(new AkkaForkJoinPoolInstrumentation(), new AkkaForkJoinTaskInstrumentation());

instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/client/AkkaHttpClientInstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,21 @@
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 AkkaHttpClientInstrumentationModule extends InstrumentationModule {
17+
public class AkkaHttpClientInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719
public AkkaHttpClientInstrumentationModule() {
1820
super("akka-http", "akka-http-10.0", "akka-http-client");
1921
}
2022

23+
@Override
24+
public boolean isIndyReady() {
25+
return true;
26+
}
27+
2128
@Override
2229
public List<TypeInstrumentation> typeInstrumentations() {
2330
return asList(new HttpExtClientInstrumentation(), new PoolMasterActorInstrumentation());

instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/client/HttpExtClientInstrumentation.java

Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import io.opentelemetry.context.Scope;
2121
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2222
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
23+
import javax.annotation.Nullable;
2324
import net.bytebuddy.asm.Advice;
25+
import net.bytebuddy.asm.Advice.AssignReturned;
26+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
2427
import net.bytebuddy.description.type.TypeDescription;
2528
import net.bytebuddy.matcher.ElementMatcher;
2629
import scala.concurrent.Future;
@@ -43,55 +46,82 @@ public void transform(TypeTransformer transformer) {
4346
@SuppressWarnings("unused")
4447
public static class SingleRequestAdvice {
4548

49+
public static class AdviceScope {
50+
private final Context context;
51+
private final Scope scope;
52+
53+
private AdviceScope(Context context, Scope scope) {
54+
this.context = context;
55+
this.scope = scope;
56+
}
57+
58+
public static AdviceScope start(HttpRequest request) {
59+
Context parentContext = currentContext();
60+
if (!instrumenter().shouldStart(parentContext, request)) {
61+
return null;
62+
}
63+
Context context = instrumenter().start(parentContext, request);
64+
// Making context current is required for header context propagation to work as expected
65+
// because it implicitly relies on the current context when injecting headers.
66+
Scope scope = context.makeCurrent();
67+
return new AdviceScope(context, scope);
68+
}
69+
70+
public HttpRequest injectHeaders(HttpRequest request) {
71+
// Request is immutable, so we have to assign a new value once we update headers
72+
return setter().inject(request);
73+
}
74+
75+
public Future<HttpResponse> end(
76+
@Nullable ActorSystem actorSystem,
77+
HttpRequest request,
78+
@Nullable Future<HttpResponse> responseFuture,
79+
@Nullable Throwable throwable) {
80+
81+
scope.close();
82+
if (actorSystem != null) {
83+
if (throwable == null) {
84+
responseFuture.onComplete(
85+
new OnCompleteHandler(context, request), actorSystem.dispatcher());
86+
return FutureWrapper.wrap(responseFuture, actorSystem.dispatcher(), currentContext());
87+
} else {
88+
instrumenter().end(context, request, null, throwable);
89+
}
90+
}
91+
return responseFuture;
92+
}
93+
}
94+
95+
@AssignReturned.ToArguments(@ToArgument(value = 0, index = 1))
4696
@Advice.OnMethodEnter(suppress = Throwable.class)
47-
public static void methodEnter(
48-
@Advice.Argument(value = 0, readOnly = false) HttpRequest request,
49-
@Advice.Local("otelContext") Context context,
50-
@Advice.Local("otelScope") Scope scope) {
97+
public static Object[] methodEnter(@Advice.Argument(0) HttpRequest request) {
98+
5199
/*
52100
Versions 10.0 and 10.1 have slightly different structure that is hard to distinguish so here
53101
we cast 'wider net' and avoid instrumenting twice.
54102
In the future we may want to separate these, but since lots of code is reused we would need to come up
55103
with way of continuing to reusing it.
56104
*/
57-
Context parentContext = currentContext();
58-
if (!instrumenter().shouldStart(parentContext, request)) {
59-
return;
60-
}
61-
62-
context = instrumenter().start(parentContext, request);
63-
scope = context.makeCurrent();
64-
// Request is immutable, so we have to assign new value once we update headers
65-
request = setter().inject(request);
105+
AdviceScope adviceScope = AdviceScope.start(request);
106+
return new Object[] {
107+
adviceScope, adviceScope == null ? request : adviceScope.injectHeaders(request)
108+
};
66109
}
67110

111+
@AssignReturned.ToReturned
68112
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
69-
public static void methodExit(
70-
@Advice.Argument(0) HttpRequest request,
113+
public static Future<HttpResponse> methodExit(
71114
@Advice.This HttpExt thiz,
72-
@Advice.Return(readOnly = false) Future<HttpResponse> responseFuture,
73-
@Advice.Thrown Throwable throwable,
74-
@Advice.Local("otelContext") Context context,
75-
@Advice.Local("otelScope") Scope scope) {
76-
if (scope == null) {
77-
return;
78-
}
115+
@Advice.Return @Nullable Future<HttpResponse> responseFuture,
116+
@Advice.Thrown @Nullable Throwable throwable,
117+
@Advice.Enter Object[] enterResult) {
79118

80-
scope.close();
81-
ActorSystem actorSystem = AkkaHttpClientUtil.getActorSystem(thiz);
82-
if (actorSystem == null) {
83-
return;
84-
}
85-
if (throwable == null) {
86-
responseFuture.onComplete(
87-
new OnCompleteHandler(context, request), actorSystem.dispatcher());
88-
} else {
89-
instrumenter().end(context, request, null, throwable);
90-
}
91-
if (responseFuture != null) {
92-
responseFuture =
93-
FutureWrapper.wrap(responseFuture, actorSystem.dispatcher(), currentContext());
119+
AdviceScope adviceScope = (AdviceScope) enterResult[0];
120+
if (adviceScope == null) {
121+
return responseFuture;
94122
}
123+
ActorSystem actorSystem = AkkaHttpClientUtil.getActorSystem(thiz);
124+
return adviceScope.end(actorSystem, (HttpRequest) enterResult[1], responseFuture, throwable);
95125
}
96126
}
97127
}

instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public AkkaHttpServerInstrumentationModule() {
2222
super("akka-http", "akka-http-10.0", "akka-http-server");
2323
}
2424

25+
@Override
26+
public boolean isIndyReady() {
27+
return true;
28+
}
29+
2530
@Override
2631
public String getModuleGroup() {
2732
return "akka-http";

instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerSourceInstrumentation.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1515
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1616
import net.bytebuddy.asm.Advice;
17+
import net.bytebuddy.asm.Advice.AssignReturned;
18+
import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument;
1719
import net.bytebuddy.description.type.TypeDescription;
1820
import net.bytebuddy.matcher.ElementMatcher;
1921

@@ -33,10 +35,11 @@ public void transform(TypeTransformer transformer) {
3335
@SuppressWarnings("unused")
3436
public static class AkkaBindAndHandleAdvice {
3537

38+
@AssignReturned.ToArguments(@ToArgument(0))
3639
@Advice.OnMethodEnter(suppress = Throwable.class)
37-
public static void wrapHandler(
38-
@Advice.Argument(value = 0, readOnly = false) Flow<HttpRequest, HttpResponse, ?> handler) {
39-
handler = AkkaFlowWrapper.wrap(handler);
40+
public static Flow<HttpRequest, HttpResponse, ?> wrapHandler(
41+
@Advice.Argument(0) Flow<HttpRequest, HttpResponse, ?> handler) {
42+
return AkkaFlowWrapper.wrap(handler);
4043
}
4144
}
4245
}

0 commit comments

Comments
 (0)