-
Notifications
You must be signed in to change notification settings - Fork 873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update webflux to Instrumenter API (and improvements/simplifications) #3798
Update webflux to Instrumenter API (and improvements/simplifications) #3798
Conversation
This reverts commit 9df4a14.
if (handler instanceof HandlerMethod) { | ||
// Special case for requests mapped with annotations | ||
HandlerMethod handlerMethod = (HandlerMethod) handler; | ||
spanName = SpanNames.fromMethod(handlerMethod.getMethod()); | ||
handlerType = handlerMethod.getMethod().getDeclaringClass().getName(); | ||
} else { | ||
spanName = AdviceUtils.spanNameForHandler(handler); | ||
handlerType = handler.getClass().getName(); | ||
} | ||
|
||
span.updateName(spanName); | ||
if (SpringWebfluxConfig.captureExperimentalSpanAttributes()) { | ||
span.setAttribute("spring-webflux.handler.type", handlerType); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we move that code inside instrumenter.start()
call?
AdviceUtils.finishSpanIfPresent(exchange, throwable); | ||
@Advice.Return(readOnly = false) Mono<Void> mono) { | ||
if (mono != null) { | ||
// note: it seems like this code should go in HandleAdvice @OnMethodExit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean Enter? This code seems to be in HandleAdvice.OnMethodExit right now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh no, two different HandleAdvice
classes, I fixed the comment 👍
.../main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/AdviceUtils.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trask I couldn't reproduce it either, perhaps something else has changed that makes triggering this harder.
@@ -61,6 +61,7 @@ dependencies { | |||
tasks.withType<Test>().configureEach { | |||
// TODO run tests both with and without experimental span attributes | |||
jvmArgs("-Dotel.instrumentation.spring-webflux.experimental-span-attributes=true") | |||
// TODO(trask): try removing this if/when latest webflux instrumentations changes prove out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it, strict context check still fails. I believe we need to wait for netty request processing to complete before doing context leaks check. I'll create a pr for this.
|
||
public class AdviceUtils { | ||
|
||
public static final String CONTEXT_ATTRIBUTE = AdviceUtils.class.getName() + ".Context"; | ||
public static final String ON_SPAN_END = AdviceUtils.class.getName() + ".Context"; | ||
|
||
public static String spanNameForHandler(Object handler) { | ||
String className = ClassNames.simpleName(handler.getClass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this part wasn't changed in this pr getting a span name from an object is also used in other instrumentations so it would be nice if someone figured out how to do this properly. The problem here is that handler could be anything. For example SpringWebFluxTestApplication
when you add
@Component("greetingHandlerFunction")
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
static class GreetingHandlerFunction implements HandlerFunction<ServerResponse> {
private final GreetingHandler greetingHandler
GreetingHandlerFunction(GreetingHandler greetingHandler) {
this.greetingHandler = greetingHandler
}
@Override
Mono<ServerResponse> handle(ServerRequest request) {
return greetingHandler.defaultGreet()
}
}
and change the start of greetRouterFunction
to
@Bean
RouterFunction<ServerResponse> greetRouterFunction(GreetingHandler greetingHandler, HandlerFunction<ServerResponse> greetingHandlerFunction) {
return route(GET("/greet"), greetingHandlerFunction
Then span name is
SpringWebFluxTestApplication$GreetingHandlerFunction$$EnhancerBySpringCGLIB$$d662c0c3.handle
When you change scope annotation to
@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
then span name is
$Proxy119.handle
If we'd assume that handler is a spring bean we could try to unwrap it with something like spring-projects/spring-framework@efe3a35
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I created issue for this #3813
HandlerMethod handlerMethod = (HandlerMethod) handler; | ||
return handlerMethod.getMethod().getDeclaringClass().getName(); | ||
} else { | ||
return handler.getClass().getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handler could be a proxy so name could be SpringWebFluxTestApplication$GreetingHandlerFunction$$EnhancerBySpringCGLIB$$d662c0c3
or $Proxy119
…ava/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/AdviceUtils.java Co-authored-by: Mateusz Rzeszutek <[email protected]>
@HaloFour have you seen the cancellation issue that was fixed in #3150? I'm wondering if you have any thoughts whether that fix should be applied to the |
The Reactor instrumentation for I also have another PR up which refactors the Reactor instrumentation to allow for multiple subscriptions and in that implementation I follow a similar approach to the PR you referenced: https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/3751/files#diff-0865720f5bd8562039a4e795c46fd7f745a94a5ba6852ff463ffa0d0424fa236R65 |
This reverts commit 04e4bf3.
putting this PR on hold until #3816 |
In addition to updating to Instrumenter API:
Handler span now maps to
org.springframework.web.reactive.HandlerAdapter.handle()
instead oforg.springframework.web.reactive.DispatcherHandler.handle()
, which more closely maps to the user handler. This aligns better with other handler spans, and the previous (strange to me) handler instrumentation placement was what motivated What is a "handler span"? #3144. Also, I think this change addresses the flaky problems that required Fix flaky spring webflux tests #3150 previously (without needing the fix from Fix flaky spring webflux tests #3150). @laurit I was not able to get any flakes following your notes to repro the flaky problem (increased request count to 300 for "Multiple GETs to delaying route" test and used spring boot 2.5.0), but would be great if you have time to give it a look/try also.Removed
spring-webflux.request.predicate
experimental attribute because the handler span is not available yet when this is calculated. If anyone wants to keep this, I can either put it on the SERVER span, or propagate it down to where the handler span is started.