非Spring Boot的Spring项目如何通过Micrometer采集REST端点指标
非Spring Boot环境下Micrometer采集HTTP请求指标实现方案
核心实现思路
由于非Spring Boot环境没有默认的HTTP指标自动配置能力,我们可以通过Spring MVC原生的拦截器机制实现全局埋点,无需修改现有REST接口代码即可完成全量请求的指标采集。
具体实现步骤
- 步骤1:补充依赖(若已传递引入可跳过)
如果你项目中没有自动引入micrometer核心包,可补充如下依赖:<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-core</artifactId> <version>1.7.5</version> </dependency> - 步骤2:实现HTTP指标采集拦截器
自定义拦截器实现请求耗时、请求次数、状态码等维度的统计:
注意:不要直接将带动态参数的实际请求路径作为uri标签值,否则会导致指标基数过大,大幅提升Prometheus存储和查询压力import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.concurrent.TimeUnit; @Component public class HttpMetricsInterceptor implements HandlerInterceptor { private static final String REQUEST_START_TIME_ATTR = "http_request_start_time"; private final MeterRegistry meterRegistry; public HttpMetricsInterceptor(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { request.setAttribute(REQUEST_START_TIME_ATTR, System.currentTimeMillis()); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { Long startTime = (Long) request.getAttribute(REQUEST_START_TIME_ATTR); if (startTime == null) { return; } long duration = System.currentTimeMillis() - startTime; // 优先取Spring匹配的接口模板路径,避免动态参数导致指标维度爆炸 String uri = (String) request.getAttribute(org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); if (uri == null) { uri = request.getRequestURI(); } // 记录请求指标,自带计数、耗时统计能力 Timer.builder("http.server.requests") .tag("method", request.getMethod()) .tag("status", String.valueOf(response.getStatus())) .tag("uri", uri) .description("HTTP服务端请求指标") .register(meterRegistry) .record(duration, TimeUnit.MILLISECONDS); } } - 步骤3:注册拦截器到Spring MVC上下文
将自定义拦截器注册到全局拦截链,使其生效:
如果你使用的是Spring 4及更早版本,可继承import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMetricsConfig implements WebMvcConfigurer { private final HttpMetricsInterceptor httpMetricsInterceptor; public WebMetricsConfig(HttpMetricsInterceptor httpMetricsInterceptor) { this.httpMetricsInterceptor = httpMetricsInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { // 可根据需求调整拦截路径范围,此处拦截所有请求 registry.addInterceptor(httpMetricsInterceptor).addPathPatterns("/**"); } }WebMvcConfigurerAdapter完成相同配置。 - 步骤4:验证指标
项目重启后,调用现有REST接口后访问Prometheus指标拉取端点,即可看到http_server_requests_seconds_count(请求次数)、http_server_requests_seconds_sum(总耗时)等相关指标,自带method、status、uri多个维度标签。
磁盘空间指标补充
如果需要采集磁盘空间指标,可在项目启动时将磁盘指标绑定到MeterRegistry即可自动采集:
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.binder.system.DiskSpaceMetrics; import javax.annotation.PostConstruct; import java.io.File; @Component public class ExtraMetricsBinder { private final MeterRegistry meterRegistry; public ExtraMetricsBinder(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @PostConstruct public void bindMetrics() { // 可替换为你需要监控的磁盘挂载路径 new DiskSpaceMetrics(new File("/")).bindTo(meterRegistry); } }
内容的提问来源于stack exchange,提问作者Sachin Chandra
相关产品推荐
相关产品推荐

