micrometer和Spring Boot 2.x是无缝集成的。
但是在有的情况下,我们需要在很老的框架下,也使用它,比如Spring 3.X。我略作了调整,改成了JDK 1.8。
为了简单期间,我从mykong上找了3.X的脚手架工程,可以参考这里。
1 添加pom依赖
<!-- for micrometer --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <version>1.8.7</version> </dependency>
注意这里用的是servlet3.0,如果是2.5的话,后面没法拿response.status。
2 添加拦截器
这里的关键是需要手工造一个Registry,我这里直接用的JmxMeterRegistry,Prometheus也一样的原理。
package com.mkyong.web.interceptor; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.jmx.JmxConfig; import io.micrometer.jmx.JmxMeterRegistry; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Optional; public class MeterInterceptor implements HandlerInterceptor { private MeterRegistry meterRegistry = new JmxMeterRegistry(new JmxConfig() { @Override public String get(String s) { return null; } }, Clock.SYSTEM); private ThreadLocal<Long> tlTimer = new ThreadLocal<Long>(); private static Optional<String> getMethod(HttpServletRequest request, Object handler) { if (handler instanceof HandlerMethod) { return Optional.of(String.format("%s_%s_%s", ((HandlerMethod) handler).getBeanType().getSimpleName(), ((HandlerMethod) handler).getMethod().getName(), request.getMethod())); } else { return Optional.empty(); } } private void recordTimeDistribution(HttpServletRequest request, Object handler, long ms) { Optional<String> methodOp = getMethod(request, handler); if (methodOp.isPresent()) { DistributionSummary.builder("app_requests_time_ms") .tag("method", methodOp.get()) .publishPercentiles(0.5, 0.95) .publishPercentileHistogram() .register(meterRegistry) .record(ms); } } public Optional<Counter> getCounterOfTotalCounts(HttpServletRequest request, Object handler) { Optional<String> methodOp = getMethod(request, handler); if (methodOp.isPresent()) { return Optional.of(meterRegistry.counter("app_requests_total_counts", "method", methodOp.get())); } else { return Optional.empty(); } } public Optional<Counter> getCounterOfExceptionCounts(HttpServletRequest request, Object handler) { Optional<String> methodOp = getMethod(request, handler); if (methodOp.isPresent()) { return Optional.of(meterRegistry.counter("app_requests_exption_counts", "method", methodOp.get())); } else { return Optional.empty(); } } public Optional<Counter> getCounterOfRespCodeCounts(HttpServletRequest request, HttpServletResponse response, Object handler) { Optional<String> methodOp = getMethod(request, handler); if (methodOp.isPresent()) { return Optional.of(meterRegistry.counter(String.format("app_requests_resp%d_counts", response.getStatus()), "method", methodOp.get())); } else { return Optional.empty(); } } @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { tlTimer.set(System.currentTimeMillis()); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // record time recordTimeDistribution(request, handler, System.currentTimeMillis() - tlTimer.get()); tlTimer.remove(); // total counts getCounterOfTotalCounts(request, handler).ifPresent(counter -> counter.increment()); // different response code count getCounterOfRespCodeCounts(request, response, handler).ifPresent(counter -> counter.increment()); if (ex != null) { // exception counts getCounterOfExceptionCounts(request, handler).ifPresent(counter -> counter.increment()); } } }
3 在xml中声明
<mvc:interceptors> <bean class="com.mkyong.web.interceptor.MeterInterceptor" /> </mvc:interceptors>
4 启动,测试
mvn jetty:run
访问http://127.0.0.1/spring3,成功后,多访问几次
然后打开jconsole,就能看到统计的jmx了。