Using Spring Boot Web & Spring Boot Actuator (2.0.0 M4) I want to monitor all http requests.
When I look at the metrics, static resources like an index.html file, images, css & js files aren't being tracked, nor is the root of the web app.
First observations are that the HandlerExecutionChains don't have the proper MetricsHandlerInterceptor set.
Here you can find a working gradle project: https://github.com/TYsewyn/canary-deployment-demo
/cc @jkschneider
@bclozel Looking at resourceHandlerMapping(), the handler mapping is deliberately using a particular interceptor rather than those used by the bean name, request mapping, and view controller handler mappings. What's the recommended way, if there is one, to add an interceptor to the resource handler mapping?
I've created SPR-16034 to address that. Spring Framework 5.0.1 should be released after our 2.0.0.M5, so I'll reschedule this issue for the next milestone.
Fixed in SPR-16034; we'll be able to test that as soon we've upgraded, see #10587.
@jkschneider I think we'll need some of your expertise here please. With @bclozel's Framework change in place, MetricsHandlerInterceptor is now called for static resource requests but nothing happens. This is because WebMvcMetrics doesn't do anything when the handler's a ResourceHttpRequestHandler (as it is when it's a request for a static resource). I prototyped this change:
diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java
index 7d74712ea9..98f7405d1c 100644
--- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java
+++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java
@@ -46,6 +46,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
/**
* Support class for Spring MVC metrics.
@@ -194,6 +195,10 @@ public class WebMvcMetrics {
if (handler instanceof HandlerMethod) {
return timed((HandlerMethod) handler);
}
+ if (handler instanceof ResourceHttpRequestHandler && this.autoTimeRequests) {
+ return Collections.singleton(
+ new TimerConfig(getServerRequestName(), this.recordAsPercentiles));
+ }
return Collections.emptySet();
}
But I am far from convinced that it's the right thing to do. For example, the tags end up using the mapping for static resources (static/**) as the uri when doesn't seem very useful. However, that's probably better than the actual uri which would lead to a potential explosion of metrics if people requested non-existent static resources.
@jkschneider When you have a moment, can you please give us some pointers?
Is there any way we can get the actual URI and shunt the uri tag to NON_EXISTENT or something like that in the event of a 404?
We could use HttpServletRequest::getRequestURI but I'm not sure how we'd know when to use that vs when to use the best matching pattern. I guess we could use the pattern for a 404 handled by a ResourceHttpRequestHandler and getRequestURI for when it matched a static resource?
We're going to have to stick with /** as the URI. The code that uses the best matching pattern doesn't know that it was a static resource request vs any other sort of request. If we start using the actual URI across the board, a request to a controller with a parameterised URL (/users/{id} for example) will result in an explosion of metrics.
Ugh... seems like a further modification to ResourceHttpRequestHandler would be preferred?
@jkschneider We could change org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsProvider.httpRequestTags to take the handler as an argument. That would align it with httpLongRequestTags and would also let us provide different tags for different types of handler. What do you think?
Micrometer 1.0 RC3 is going to move to a filter so we'll need to re-evaluate this when the PR from @jkschneider lands.
We still get nothing for a root resource that's treated as a welcome page as the handler is a org.springframework.web.servlet.mvc.ParameterizableViewController which causes org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetrics.timed(Object) to return an empty set.