能否为Spring Boot Prometheus已有http_server_requests_seconds指标新增维度标签?
可行性结论
完全可以实现。Spring Boot 基于 Micrometer 生成的 http_server_requests_seconds_* 系列默认指标,官方预留了自定义标签的扩展点,无需新建独立指标就能追加自定义维度。
实现步骤(Spring MVC 环境)
普通非响应式的 Spring Boot REST API 按照以下步骤操作即可:
- 实现
WebMvcTagsContributor接口并注入到 Spring 容器,该接口会在每次请求结束统计指标时被调用,用于追加自定义标签
import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class CustomHttpMetricsTagContributor implements WebMvcTagsContributor { @Override public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler, Throwable exception) { Tags tags = Tags.empty(); // 仅针对创建用户的接口追加失败标签,避免无效维度 if ("POST".equals(request.getMethod()) && "/users".equals(request.getRequestURI())) { // 仅请求失败时添加具体错误原因 if (response.getStatus() >= 400 || exception != null) { String failureReason = (String) request.getAttribute("failure_reason"); if (failureReason == null && exception != null) { failureReason = exception.getClass().getSimpleName(); } tags = tags.and(Tag.of("failure_reason", failureReason != null ? failureReason : "unknown")); return tags; } } // 非目标接口/请求成功时标签统一设为none,避免维度爆炸 return tags.and(Tag.of("failure_reason", "none")); } }
- 在业务代码中往请求属性中写入自定义标签值
以创建用户接口为例,业务逻辑判断到失败场景时,将需要记录的额外信息存入HttpServletRequest的属性中,供标签生成逻辑读取:
@PostMapping("/users") public ResponseEntity<UserDTO> createUser(@RequestBody CreateUserReq req, HttpServletRequest request) { // 用户名重复的业务失败场景 if (userService.existsByUsername(req.getUsername())) { request.setAttribute("failure_reason", "username_duplicate"); return ResponseEntity.badRequest().build(); } try { return ResponseEntity.ok(userService.create(req)); } catch (Exception e) { // 系统异常场景 request.setAttribute("failure_reason", "system_error"); throw e; } }
- 验证效果
重启应用后调用几次失败的创建用户接口,访问/actuator/prometheus端点即可看到http_server_requests_seconds_count指标已经新增了failure_reason自定义标签。
如果是 WebFlux 响应式项目,将实现的接口替换为WebFluxTagsContributor即可,整体逻辑一致。
注意事项
- 标签值禁止使用高基数内容(如用户ID、订单ID、请求ID等取值无上限的内容),否则会导致Prometheus存储压力陡增,严重影响服务性能。
- 标签生成逻辑要尽量轻量,不要加入复杂计算或IO操作,避免影响接口本身的响应性能。
- 自定义标签的取值范围尽量提前收敛,避免出现过多非预期的标签值。
内容的提问来源于stack exchange,提问作者romeucr
相关产品推荐
相关产品推荐

