【问题标题】:Including spring boot endpoint path variable as a metric dimension包括 spring boot 端点路径变量作为度量维度
【发布时间】:2019-03-24 09:48:46
【问题描述】:

我有 api 端点:/user/{tenant}/create

我正在使用带有千分尺的 spring boot 2 作为指标。

默认情况下,spring boot 2 端点的@Timer 注解包含以下标签:异常、方法、uri、状态

我想将 api 参数“租户”的传递值添加为端点的额外标记

如何使用 spring boot 2 和千分尺来做到这一点

【问题讨论】:

    标签: java spring-boot micrometer spring-micrometer


    【解决方案1】:

    从 Spring Boot 2.3.0 开始,如果你想为某些请求添加额外的标签到默认标签,更好的方法是添加类 WebMvcTagsContributor 的 @Bean。这样您的代码就不必担心放入默认标签。

    https://github.com/spring-projects/spring-boot/issues/20175中实现

    代码如下所示:

    @Bean
    public WebMvcTagsContributor webMvcTagsContributor() {
        return new WebMvcTagsContributor() {
            @Override
            public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) {
                Tags tags = Tags.empty();
                tags = tags.and(Tag.of("my_tag", "somevalue"));
                return tags;
            }
    
            @Override
            public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
                return null;
            }
        };
    }
    

    【讨论】:

      【解决方案2】:

      将路径变量添加到默认标签的方法:

      import io.micrometer.core.instrument.Tag;
      import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.HandlerMapping;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.util.Map;
      import java.util.stream.Collectors;
      
      @Configuration
      public class WebMvcTagsProviderConfig {
      
          @Bean
          public WebMvcTagsContributor webMvcTagsContributor() {
              return new WebMvcTagsContributor() {
                  @Override
                  public Iterable<Tag> getTags(
                          HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception
                  ) {
                      Map<String, String> pathVariables = ((Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE));
                      return pathVariables == null
                              ? null
                              : pathVariables
                                      .entrySet()
                                      .stream()
                                      .map(entry -> Tag.of(entry.getKey(), entry.getValue()))
                                      .collect(Collectors.toList());
                  }
      
                  @Override
                  public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
                      return null;
                  }
              };
          }
      
      }
      

      【讨论】:

        【解决方案3】:
        @Bean
        public WebMvcTagsProvider webMvcTagsProvider() {
            return new CustomWebMvcTagsProvider();
        }
        
        
            public class CustomWebMvcTagsProvider extends DefaultWebMvcTagsProvider {
              public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) {
                return Tags.of(super.getTags(request, response, handler, exception)).and(getTenantTag(request));
              }
        
              private Tag getTenantTag(HttpServletRequest request) {
                String tenant = ((Map<String, String>)request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)).get("tenant");
                if(tenant == null){
                    tenant = "na";
                }
                return Tag.of("tenant", tenant);
              }
            }
        
        

        【讨论】:

          【解决方案4】:

          使用自定义WebMvcTagsProvider,例如:

          @Bean
          public WebMvcTagsProvider webMvcTagsProvider() {
              return new WebMvcTagsProvider() {
                  @Override
                  public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) {
                      return ((Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE))
                              .entrySet()
                              .stream()
                              .map(entry -> new ImmutableTag(entry.getKey(), entry.getValue()))
                              .collect(Collectors.toList());
                  }
          
                  @Override
                  public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
                      return new ArrayList<>();
                  }
              };
          }
          

          【讨论】:

          • 谢谢!参考您的代码,编写的代码仅提取所需的路径变量。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-24
          • 2021-04-01
          相关资源
          最近更新 更多