看次文章前首先参考,这样才没有断片的感觉:参考链接
前几篇我们通过切面、单个处理、全局指标类型等方式监控业务接口,今天我们通过boot拦截器的方式监控业务接口:
1、 启动添加拦截器:
package com.nandao.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author wanghuainan
* @date 2021/9/24
*/
@Component
public class WebConfig implements WebMvcConfigurer {
@Autowired
private PrometheusMetricsInterceptor prometheusMetricsInterceptor;
/**
* 添加自定义拦截器
* @param registry
*/
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(prometheusMetricsInterceptor).addPathPatterns("/**");
}
}
2、启动时创建拦截器:
package com.nandao.demo.config;
import io.micrometer.core.instrument.Counter;
import io.prometheus.client.Summary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
/**
* @author wanghuainan
* @date 2021/9/24
*/
@Component
public class PrometheusMetricsInterceptor extends HandlerInterceptorAdapter {
@Autowired
private Counter requestCounter;
@Autowired
private Summary requestLatency;
/**
* 业务调用时的前置接口监控
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
request.setAttribute("startTime", new Date().getTime());
return true;
}
/**
* 业务调用时的后置接口调用
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
String service = request.getRequestURI();
/*requestCounter.labels(service, request.getMethod(), String.valueOf(response.getStatus()))
.inc();*/
requestCounter.increment();
long duration = new Date().getTime() - (Long)request.getAttribute("startTime");
requestLatency.labels(service, request.getMethod(), String.valueOf(response.getStatus()))
.observe(duration);
}
}
3、配置的自定义指标:
/**
* 摘要分析
* @return
*/
@Bean
Summary getSummary(){
return Summary.build().labelNames("application","uri", "accessType", "code","msg")
.name("pc_cost_summary").help("请求耗时summary")
.quantile(0.5, 0.05)
.quantile(0.9, 0.01)
.register(registry.getPrometheusRegistry());
}
/**
* 只增不减的计数器
* @return
*/
@Bean
Counter createCounter(){
return Counter.builder("name") //名称
.baseUnit("unit") //基础单位
.description("desc") //描述
.tag("tagKey", "tagValue")//标签
.tags("a","A","b","B","c","C") //标签list
.register(new SimpleMeterRegistry());//绑定的MeterRegistry
}
到此,服务启动后访问接口是就通过前置和后置来监控接口的请求状态了。