为 Spring 个网络客户端默认指标添加标签
Add tags for Spring webclient default metrics
我目前正在开发一个 Spring webflux 项目,该项目具有 Actuator、Micrometer 依赖项,如下所示,
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
公开默认指标(包括 Spring webClient 指标)。我有 4 个不同的端点,我使用 Spring WebClient 调用它们。我想知道是否有办法为每个添加到默认指标的 webclient 调用添加特定标签。我有一些指标,例如来自 Webclient 的 Histogram,暴露在 /actuator/prometheus 端点,如下所示,
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.001048576",} 0.0
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.002088576",} 1.0
在我的代码中,我想在 Webclient 调用中为上述所有指标添加一些额外的标签。例如这样的东西,
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.001048576",investor="A", version="v1"} 0.0
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.002088576",investor="A", version="v1"} 1.0
注意我添加的 2 个自定义标签 investor="A", version="v1"。我正在寻找一些可能看起来像这样的代码,
@Autowire
private WebClient webclient; // Assume there is already a bean created for us
public Mono<String> getShopsList(String... extraTags) {
return webclient.baseUrl("http://my-app.com")
.build()
.get()
.uri("/shops")
.tags(extraTags) // Some extra tags I want callers of the method to pass. Note there are only 4-5 methods that call "getShopsList()" method
.retrieve()
.bodyToMono(String.class);
}
有人可以帮忙提供实现此目标的最佳方法吗?
实现此目的的预期方法是引入您的自定义标签提供商:
@Component
public class CustomWebClientExchangeTagsProvider extends DefaultWebClientExchangeTagsProvider {
public static final String VERSION_ATTRIBUTE = "custom.webclient.version";
public static final String INVESTOR_ATTRIBUTE = "custom.webclient.investor";
@Override
public Iterable<Tag> tags(ClientRequest request, ClientResponse response, Throwable throwable) {
Tag method = WebClientExchangeTags.method(request);
Tag investor = getInvestorTag(request);
Tag version = getVersionTag(request);
return asList(method, investor, version, WebClientExchangeTags.status(response, throwable), WebClientExchangeTags.outcome(response));
}
private Tag getInvestorTag(ClientRequest request) {
return request.attribute(INVESTOR_ATTRIBUTE)
.map(name -> Tag.of("investor", (String) name))
.orElse(WebClientExchangeTags.clientName(request));
}
private Tag getVersionTag(ClientRequest request) {
return request.attribute(VERSION_ATTRIBUTE)
.map(uri -> Tag.of("version", (String) uri))
.orElse(WebClientExchangeTags.uri(request));
}
}
您必须以这种方式检测您的自定义 Web 客户端:
@Bean
public WebClient webClient(MetricsWebClientCustomizer metricsCustomizer) {
TcpClient timeoutClient = ...
WebClient.Builder builder = WebClient.builder();
metricsCustomizer.customize(builder);
return ...;
}
最后,你需要像这样设置两个属性:
return webClient.get()
.uri(filePath)
.attribute(INVESTOR_ATTRIBUTE, "A")
.attribute(VERSION_ATTRIBUTE, "v1")
.retrieve()
.bodyToMono(String.class);
示例结果:
http_client_requests_seconds_count{investor="A",method="GET",outcome="CLIENT_ERROR",status="401",version="v1",} 1.0
http_client_requests_seconds_sum{investor="A",method="GET",outcome="CLIENT_ERROR",status="401",version="v1",} 0.073818807
编辑
根据文档:
S attributes(Consumer<Map<String,Object>> attributesConsumer)
Provides access to every attribute declared so far with the
possibility to add, replace, or remove values.
是的,您可以使用它来添加多个属性。
我目前正在开发一个 Spring webflux 项目,该项目具有 Actuator、Micrometer 依赖项,如下所示,
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
公开默认指标(包括 Spring webClient 指标)。我有 4 个不同的端点,我使用 Spring WebClient 调用它们。我想知道是否有办法为每个添加到默认指标的 webclient 调用添加特定标签。我有一些指标,例如来自 Webclient 的 Histogram,暴露在 /actuator/prometheus 端点,如下所示,
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.001048576",} 0.0
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.002088576",} 1.0
在我的代码中,我想在 Webclient 调用中为上述所有指标添加一些额外的标签。例如这样的东西,
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.001048576",investor="A", version="v1"} 0.0
http_client_requests_seconds_bucket{clientName="my-app.com",method="GET",outcome="SUCCESS",status="200",uri="/shops",le="0.002088576",investor="A", version="v1"} 1.0
注意我添加的 2 个自定义标签 investor="A", version="v1"。我正在寻找一些可能看起来像这样的代码,
@Autowire
private WebClient webclient; // Assume there is already a bean created for us
public Mono<String> getShopsList(String... extraTags) {
return webclient.baseUrl("http://my-app.com")
.build()
.get()
.uri("/shops")
.tags(extraTags) // Some extra tags I want callers of the method to pass. Note there are only 4-5 methods that call "getShopsList()" method
.retrieve()
.bodyToMono(String.class);
}
有人可以帮忙提供实现此目标的最佳方法吗?
实现此目的的预期方法是引入您的自定义标签提供商:
@Component
public class CustomWebClientExchangeTagsProvider extends DefaultWebClientExchangeTagsProvider {
public static final String VERSION_ATTRIBUTE = "custom.webclient.version";
public static final String INVESTOR_ATTRIBUTE = "custom.webclient.investor";
@Override
public Iterable<Tag> tags(ClientRequest request, ClientResponse response, Throwable throwable) {
Tag method = WebClientExchangeTags.method(request);
Tag investor = getInvestorTag(request);
Tag version = getVersionTag(request);
return asList(method, investor, version, WebClientExchangeTags.status(response, throwable), WebClientExchangeTags.outcome(response));
}
private Tag getInvestorTag(ClientRequest request) {
return request.attribute(INVESTOR_ATTRIBUTE)
.map(name -> Tag.of("investor", (String) name))
.orElse(WebClientExchangeTags.clientName(request));
}
private Tag getVersionTag(ClientRequest request) {
return request.attribute(VERSION_ATTRIBUTE)
.map(uri -> Tag.of("version", (String) uri))
.orElse(WebClientExchangeTags.uri(request));
}
}
您必须以这种方式检测您的自定义 Web 客户端:
@Bean
public WebClient webClient(MetricsWebClientCustomizer metricsCustomizer) {
TcpClient timeoutClient = ...
WebClient.Builder builder = WebClient.builder();
metricsCustomizer.customize(builder);
return ...;
}
最后,你需要像这样设置两个属性:
return webClient.get()
.uri(filePath)
.attribute(INVESTOR_ATTRIBUTE, "A")
.attribute(VERSION_ATTRIBUTE, "v1")
.retrieve()
.bodyToMono(String.class);
示例结果:
http_client_requests_seconds_count{investor="A",method="GET",outcome="CLIENT_ERROR",status="401",version="v1",} 1.0
http_client_requests_seconds_sum{investor="A",method="GET",outcome="CLIENT_ERROR",status="401",version="v1",} 0.073818807
编辑
根据文档:
S attributes(Consumer<Map<String,Object>> attributesConsumer)
Provides access to every attribute declared so far with the possibility to add, replace, or remove values.
是的,您可以使用它来添加多个属性。