springcloud gateway在集成Prometheus后看到监控图中uri是UNKNOWN,如下图:
这里问题有很多同伴都有遇到,如下面一个: https://blog.csdn.net/a1033025319/article/details/90518867 文章中也有进去分析源码是如何工作的,但是没有给出解决方案,这里我们就讨论下如何修改已有metrics的tag或者增加tag
了解springcloud gateway原理的应该了解gateway是依托于spring webflux,想要了解webflux可以在搜索相关资料,这里不做详细介绍,我们进入debug模式,可以观察到最终指标监控代码是进入到了DefaultWebFluxTagsProvider这个类,这个类代码如下:
package org.springframework.boot.actuate.metrics.web.reactive.server;
import io.micrometer.core.instrument.Tag;
import java.util.Arrays;
import org.springframework.web.server.ServerWebExchange;
public class DefaultWebFluxTagsProvider implements WebFluxTagsProvider {
public DefaultWebFluxTagsProvider() {
}
public Iterable<tag> httpRequestTags(ServerWebExchange exchange, Throwable exception) {
return Arrays.asList(WebFluxTags.method(exchange), WebFluxTags.uri(exchange), WebFluxTags.exception(exception), WebFluxTags.status(exchange), WebFluxTags.outcome(exchange));
}
}
这里就是背景中有一个问题中的调用方,这里我们可以自己实现一个WebFluxTagsProvider 来自定义监控tag,举个例子,我们在上一章springcloud gateway高级功能之根据参数自定义路由Predicate 中读取了参数,这里我们就可以根据参数来修改tag,如果没有参数我们也可以将获取指定url注入
@Bean
public WebFluxTagsProvider webFluxTagsProvider() {
return new WebFluxTagsProvider() {
@Override
public Iterable<tag> httpRequestTags(ServerWebExchange exchange,
Throwable exception) {
Tag urlTag;
Object obj=exchange.getAttributes().get(RecommendFacadeConstants.CACHE_REQUEST_BODY_OBJECT_KEY);
if(obj!=null){
urlTag=Tag.of("uri", ((Request)obj).getParams);
}else{
urlTag=Tag.of("uri", exchange.getRequest().getURI().getPath());
}
return Arrays.asList(WebFluxTags.method(exchange), urlTag,
WebFluxTags.exception(exception), WebFluxTags.status(exchange),
WebFluxTags.outcome(exchange));
}
};
}
上面代码不仅仅可以修改,还可以添加tag,这里我就不写demo了,下面是改造后的效果,如下:
这里顺便提一下,如果我们没有使用springcloud gateway,而是使用spring mvc,这里我们同样可以进行改造来修改tag,同上,mvc也是用的default provider,如下
package org.springframework.boot.actuate.metrics.web.servlet;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DefaultWebMvcTagsProvider implements WebMvcTagsProvider {
public DefaultWebMvcTagsProvider() {
}
public Iterable<tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) {
return Tags.of(new Tag[]{WebMvcTags.method(request), WebMvcTags.uri(request, response), WebMvcTags.exception(exception), WebMvcTags.status(response), WebMvcTags.outcome(response)});
}
public Iterable<tag> getLongRequestTags(HttpServletRequest request, Object handler) {
return Tags.of(new Tag[]{WebMvcTags.method(request), WebMvcTags.uri(request, (HttpServletResponse)null)});
}
}
参考上面的配置,我们同样可以改造WebMvcTagsProvider ,我们可以读取request中的参数来修改tag,这里如果是post,则需要httprequest的装饰器来读取post body,详细代码我这里不举例子了,如果需要可以在网上搜索,然后实现自定义的WebMvcTagsProvider