背景
springcloud gateway在集成Prometheus後看到監控圖中uri是UNKNOWN,如下圖:
這裏問題有很多同伴都有遇到,如下面一個: https://blog.csdn.net/a1033025319/article/details/90518867 文章中也有進去分析源碼是如何工作的,但是沒有給出解決方案,這裏我們就討論下如何修改已有metrics的tag或者增加tag
方案討論
webflux
瞭解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了,下面是改造後的效果,如下:
webMvc
這裏順便提一下,如果我們沒有使用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