Skip to content

Commit 004a5cd

Browse files
committed
webflux
1 parent 91b80f7 commit 004a5cd

File tree

6 files changed

+78
-39
lines changed

6 files changed

+78
-39
lines changed

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/DispatcherHandlerInstrumentation.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
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;
1718
import net.bytebuddy.description.type.TypeDescription;
1819
import net.bytebuddy.matcher.ElementMatcher;
1920
import org.springframework.web.server.ServerWebExchange;
@@ -45,28 +46,31 @@ public void transform(TypeTransformer transformer) {
4546
@SuppressWarnings("unused")
4647
public static class HandleAdvice {
4748

49+
@AssignReturned.ToReturned
4850
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
49-
public static void methodExit(
51+
public static Mono<Void> methodExit(
5052
@Advice.Thrown Throwable throwable,
5153
@Advice.Argument(0) ServerWebExchange exchange,
52-
@Advice.Return(readOnly = false) Mono<Void> mono) {
54+
@Advice.Return Mono<Void> originalMono) {
55+
Mono<Void> mono = originalMono;
5356
if (mono != null) {
5457
// note: it seems like this code should go in @OnMethodExit of
5558
// HandlerAdapterInstrumentation.HandleAdvice instead, but for some reason "GET to bad
5659
// endpoint annotation API fail Mono" test fails with that placement
5760
mono = AdviceUtils.end(mono, exchange);
5861
}
62+
return mono;
5963
}
6064
}
6165

6266
@SuppressWarnings("unused")
6367
public static class HandleResultAdvice {
6468

69+
@AssignReturned.ToReturned
6570
@Advice.OnMethodExit(suppress = Throwable.class)
66-
public static void methodExit(
67-
@Advice.Argument(0) ServerWebExchange exchange,
68-
@Advice.Return(readOnly = false) Mono<Void> mono) {
69-
mono = AdviceUtils.wrapMono(mono, exchange.getAttribute(AdviceUtils.CONTEXT));
71+
public static Mono<Void> methodExit(
72+
@Advice.Argument(0) ServerWebExchange exchange, @Advice.Return Mono<Void> mono) {
73+
return AdviceUtils.wrapMono(mono, exchange.getAttribute(AdviceUtils.CONTEXT));
7074
}
7175
}
7276
}

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/HandlerAdapterInstrumentation.java

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource;
2424
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2525
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
26+
import javax.annotation.Nullable;
2627
import net.bytebuddy.asm.Advice;
28+
import net.bytebuddy.asm.Advice.AssignReturned;
2729
import net.bytebuddy.description.type.TypeDescription;
2830
import net.bytebuddy.matcher.ElementMatcher;
2931
import org.springframework.web.reactive.HandlerResult;
@@ -58,12 +60,40 @@ public void transform(TypeTransformer transformer) {
5860
@SuppressWarnings("unused")
5961
public static class HandleAdvice {
6062

63+
public static class AdviceScope {
64+
private final Context context;
65+
private final Scope scope;
66+
67+
public AdviceScope(Context context, Scope scope) {
68+
this.context = context;
69+
this.scope = scope;
70+
}
71+
72+
public Mono<HandlerResult> exit(
73+
Throwable throwable,
74+
ServerWebExchange exchange,
75+
Object handler,
76+
Mono<HandlerResult> mono) {
77+
scope.close();
78+
79+
if (throwable != null) {
80+
instrumenter().end(context, handler, null, throwable);
81+
} else {
82+
mono = AdviceUtils.wrapMono(mono, context);
83+
exchange.getAttributes().put(AdviceUtils.CONTEXT, context);
84+
AdviceUtils.registerOnSpanEnd(exchange, context, handler);
85+
// span finished by wrapped Mono in DispatcherHandlerInstrumentation
86+
// the Mono is already wrapped at this point, but doesn't read the ON_SPAN_END until
87+
// the Mono is resolved, which is after this point
88+
}
89+
return mono;
90+
}
91+
}
92+
93+
@Nullable
6194
@Advice.OnMethodEnter(suppress = Throwable.class)
62-
public static void methodEnter(
63-
@Advice.Argument(0) ServerWebExchange exchange,
64-
@Advice.Argument(1) Object handler,
65-
@Advice.Local("otelContext") Context context,
66-
@Advice.Local("otelScope") Scope scope) {
95+
public static AdviceScope methodEnter(
96+
@Advice.Argument(0) ServerWebExchange exchange, @Advice.Argument(1) Object handler) {
6797

6898
Context parentContext = Context.current();
6999

@@ -75,40 +105,30 @@ public static void methodEnter(
75105
parentContext, HttpServerRouteSource.NESTED_CONTROLLER, httpRouteGetter(), exchange);
76106

77107
if (handler == null) {
78-
return;
108+
return null;
79109
}
80110

81111
if (!instrumenter().shouldStart(parentContext, handler)) {
82-
return;
112+
return null;
83113
}
84-
85-
context = instrumenter().start(parentContext, handler);
86-
scope = context.makeCurrent();
114+
Context context = instrumenter().start(parentContext, handler);
115+
return new AdviceScope(context, context.makeCurrent());
87116
}
88117

118+
@AssignReturned.ToReturned
89119
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
90-
public static void methodExit(
91-
@Advice.Return(readOnly = false) Mono<HandlerResult> mono,
120+
public static Mono<HandlerResult> methodExit(
121+
@Advice.Return Mono<HandlerResult> mono,
92122
@Advice.Argument(0) ServerWebExchange exchange,
93123
@Advice.Argument(1) Object handler,
94124
@Advice.Thrown Throwable throwable,
95-
@Advice.Local("otelContext") Context context,
96-
@Advice.Local("otelScope") Scope scope) {
97-
if (scope == null) {
98-
return;
99-
}
100-
scope.close();
101-
102-
if (throwable != null) {
103-
instrumenter().end(context, handler, null, throwable);
104-
} else {
105-
mono = AdviceUtils.wrapMono(mono, context);
106-
exchange.getAttributes().put(AdviceUtils.CONTEXT, context);
107-
AdviceUtils.registerOnSpanEnd(exchange, context, handler);
108-
// span finished by wrapped Mono in DispatcherHandlerInstrumentation
109-
// the Mono is already wrapped at this point, but doesn't read the ON_SPAN_END until
110-
// the Mono is resolved, which is after this point
125+
@Advice.Enter @Nullable AdviceScope adviceScope) {
126+
127+
if (adviceScope == null) {
128+
return mono;
111129
}
130+
131+
return adviceScope.exit(throwable, exchange, handler, mono);
112132
}
113133
}
114134
}

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/RouterFunctionInstrumentation.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1919
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
2020
import net.bytebuddy.asm.Advice;
21+
import net.bytebuddy.asm.Advice.AssignReturned;
2122
import net.bytebuddy.description.type.TypeDescription;
2223
import net.bytebuddy.matcher.ElementMatcher;
2324
import org.springframework.web.reactive.function.server.HandlerFunction;
@@ -61,14 +62,17 @@ public void transform(TypeTransformer transformer) {
6162
@SuppressWarnings("unused")
6263
public static class RouteAdvice {
6364

65+
@AssignReturned.ToReturned
6466
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
65-
public static void methodExit(
67+
public static Mono<HandlerFunction<?>> methodExit(
6668
@Advice.This RouterFunction<?> thiz,
67-
@Advice.Return(readOnly = false) Mono<HandlerFunction<?>> result,
69+
@Advice.Return Mono<HandlerFunction<?>> originalResult,
6870
@Advice.Thrown Throwable throwable) {
71+
Mono<HandlerFunction<?>> result = originalResult;
6972
if (throwable == null) {
7073
result = result.doOnNext(new RouteOnSuccess(thiz));
7174
}
75+
return result;
7276
}
7377
}
7478
}

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/WebfluxServerInstrumentationModule.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 WebfluxServerInstrumentationModule extends InstrumentationModule {
17+
public class WebfluxServerInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719

1820
public WebfluxServerInstrumentationModule() {
1921
super("spring-webflux", "spring-webflux-5.0", "spring-webflux-server");
@@ -26,4 +28,9 @@ public List<TypeInstrumentation> typeInstrumentations() {
2628
new HandlerAdapterInstrumentation(),
2729
new RouterFunctionInstrumentation());
2830
}
31+
32+
@Override
33+
public boolean isIndyReady() {
34+
return true;
35+
}
2936
}

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ContextHandlerInstrumentation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.opentelemetry.instrumentation.netty.v4_1.internal.ServerContexts;
1515
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1616
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
17+
import javax.annotation.Nullable;
1718
import net.bytebuddy.asm.Advice;
1819
import net.bytebuddy.description.type.TypeDescription;
1920
import net.bytebuddy.matcher.ElementMatcher;
@@ -35,6 +36,7 @@ public void transform(TypeTransformer transformer) {
3536
@SuppressWarnings("unused")
3637
public static class CreateOperationsAdvice {
3738

39+
@Nullable
3840
@Advice.OnMethodEnter(suppress = Throwable.class)
3941
public static Scope onEnter(@Advice.Argument(0) Channel channel) {
4042
// set context to the first unprocessed request
@@ -46,7 +48,7 @@ public static Scope onEnter(@Advice.Argument(0) Channel channel) {
4648
}
4749

4850
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
49-
public static void onExit(@Advice.Enter Scope scope) {
51+
public static void onExit(@Advice.Enter @Nullable Scope scope) {
5052
if (scope != null) {
5153
scope.close();
5254
}

instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/HttpTrafficHandlerInstrumentation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.opentelemetry.instrumentation.netty.v4_1.internal.ServerContexts;
1515
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1616
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
17+
import javax.annotation.Nullable;
1718
import net.bytebuddy.asm.Advice;
1819
import net.bytebuddy.description.type.TypeDescription;
1920
import net.bytebuddy.matcher.ElementMatcher;
@@ -35,6 +36,7 @@ public void transform(TypeTransformer transformer) {
3536
@SuppressWarnings("unused")
3637
public static class RunAdvice {
3738

39+
@Nullable
3840
@Advice.OnMethodEnter(suppress = Throwable.class)
3941
public static Scope onEnter(
4042
@Advice.FieldValue("ctx") ChannelHandlerContext channelHandlerContext) {
@@ -47,7 +49,7 @@ public static Scope onEnter(
4749
}
4850

4951
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
50-
public static void onExit(@Advice.Enter Scope scope) {
52+
public static void onExit(@Advice.Enter @Nullable Scope scope) {
5153
if (scope != null) {
5254
scope.close();
5355
}

0 commit comments

Comments
 (0)