Spring Boot 3.0.X 中 http.client.requests 指标的 URI 标记为 NONE

问题描述 投票:0回答:2

从 Spring Boot 2.7.5 迁移到 Spring Boot 3.0.1 后。

指标 http.client.requests 上的标签 URI 在所有情况下都具有值 none。

我们构建restTemplate的URI,就像

URI uri = UriComponentsBuilder.fromUri(restTemplate.getUriTemplateHandler().expand("/hello"))
   .build()
   .toUri();

return restTemplate.getForObject(uri, String.class);

我习惯这样做,因为添加查询参数,我认为它更容易阅读和管理。

为了重现它,我在 这个存储库 中创建了两个小应用程序,一个在 Spring Boot 2.7.7 上,另一个在 3.0.1 上

我发现它与 Spring 6 上的新可观察性相关联,并与 Spring Boot 上的此问题相关联。

Spring boot 2 自定义 UriTemplateHandler 并将 urlTemplate 存储在 ThreadLocal 中。并使用这个双端队列作为标签 uri。

文档我知道我可以通过提供新的@Bean ClientRequestObservationConvention来增强标签。

我还可以使用 org.springframework.web.client.RestTemplate#getForObject(java.lang.String, java.lang.Class, java.util.Map)。喜欢

return restTemplate.getForObject("/hello", String.class);

但我想知道是否有办法获得以前的行为并仍然使用org.springframework.web.client.RestTemplate#getForEntity(java.net.URI, java.lang.Class).

spring-boot spring-boot-actuator
2个回答
2
投票

在 Spring Boot 3 和可观察性改进之前,

RestTemplate
确实会使用完整的请求 URI 作为“uri”标签。这是错误的,因为 URI 值在应用程序中不受限制,并且可能会导致指标系统中的基数爆炸。

例如,客户端可以使用

"/user/12"
"/user/23"
等报告 uri 标签。正确的标签应该是低基数,并使用像
"/user/{userId}"
这样的请求模式。

在 Spring Boot 2.x 中,出于兼容性原因,我们没有改变此行为,而是添加了一个

MeterFilter
,一旦达到阈值,它就会停止记录指标。从 Spring Framework 6 开始,仪表直接内置于
RestTemplate
中。仅当
RestTemplate
方法接受字符串模板时才会记录此标记,就像您注意到的
restTemplate.getForObject("/hello", String.class)
一样。

您可以通过提供自己的

ClientRequestObservationConvention
来恢复到以前的行为(有关更多信息,请参阅 迁移 wiki ),但请注意,您还需要确保基数爆炸不会成为应用程序中的问题。

参见 这个 Spring Boot 问题,看起来非常相似


0
投票

他是一些示例代码,用于让 URI 指标标记在 Spring Boot 3 中再次工作。定义 ExtendedServerRequestObservationConvention 类。

import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.observation.ServerRequestObservationContext;

import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;

public class ExtendedServerRequestObservationConvention extends DefaultServerRequestObservationConvention {

    @Override
    public KeyValues getLowCardinalityKeyValues(final ServerRequestObservationContext context) {
        return super.getLowCardinalityKeyValues(context).and(custom(context));
    }

    protected KeyValue custom(final ServerRequestObservationContext context) {
        return KeyValue.of("uri", context.getCarrier().getRequestURI());
}

}

然后添加一个bean,以便Spring创建该类的实例

@Bean
    public ExtendedServerRequestObservationConvention extendedServerRequestObservationConvention() {
        return new ExtendedServerRequestObservationConvention();
}
© www.soinside.com 2019 - 2024. All rights reserved.