获取 Micrometer 指标的可用 Grails URL

问题描述

我很高兴听到 Spring 使用 Micrometer 并将其集成到 Spring Boot 中,并在我们的 Grails 4 应用程序之一中进行了尝试。结果就在那里……但并不令人满意。特别是通过 Prometheus 的 http_server_requests_* 路径:

# HELP http_server_requests_seconds  
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{exception="None",method="GET",outcome="CLIENT_ERROR",status="404",uri="NOT_FOUND",} 1.0
http_server_requests_seconds_sum{exception="None",} 0.02043081
http_server_requests_seconds_count{exception="None",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 18.0
http_server_requests_seconds_sum{exception="None",} 0.176840301
http_server_requests_seconds_count{exception="None",uri="/actuator/health/{component}",} 0.004094051
http_server_requests_seconds_count{exception="None",uri="root",} 8.208040143

令人失望的是所有 Grails 路由都all 映射为 root - 远没有用。这意味着 /index/book/book/1/book/1/authors 的记录相同。

是时候开始挖掘了。

我发现 Spring MVC implementation 查找请求属性 HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE。我尝试了多种方法在 Grails 中复制它,我发现最成功的方法是将 UrlMappingsHandlerMapping 扩展如下:

class AnotherUrlMappingsHandlerMapping extends UrlMappingsHandlerMapping {
    AnotherUrlMappingsHandlerMapping(UrlMappingsHolder urlMappingsHolder) {
        super(urlMappingsHolder)
    }

    @Override
    protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
        Object o = super.getHandlerInternal(request)

        // Leverage the underpinnings being spring boot to set the url path for proper tags
        if (o && o instanceof GrailsControllerUrlMappingInfo) {
            // Todo why toString() the getUrlData method always returns null...?
            String urlPattern = o.info?.toString()
            if (urlPattern) {
                request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE,urlPattern)
            }
        }

        return o
    }
}

此时我觉得重要的是我停下来问问是否有原因 GrailsControllerUrlMappingInfo#getUrlData() 总是返回 null?奇怪的是 toString() 方法会给我我需要的东西(有点)所以我可以使用它,但是把它锁起来似乎很奇怪......

我也知道我在技术上不需要使用 BEST_MATCHING_PATTERN_ATTRIBUTE,但它涉及最少的更改来使某些工作正常工作。可以提供 GrailsWebMvcTagsProvider,但就我而言,这里没有必要。

重回正轨。所以此时我有 urlPattern 并且它被成功记录为 prometheus 的 uri:

http_server_requests_seconds_count{exception="None",uri="/book/(*)",} 0.002445454
http_server_requests_seconds_count{exception="None",uri="/book/(*)/authors/(*)",} 0.003589445

更好,但仍然不完美。模式就在那里,每个端点都有 disctint,但我认为它可能会更好。比较这对:

  • Spring MVC - /actuator/health/{component}
  • Grails - /book/(*)

我的问题:

  1. 还有其他方法可以获取信息更丰富的 url 模式吗?类似于 urlmappings.groovy 中的实际内容
   "/book/$bookId/authors/$id"(controller: 'application',action: 'path')
  1. 是否有更好的方法来立即执行这些指标?我可能会错过最简单的事情...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)