前一段时间使用SpringBoot创建了一个webhook项目,由于近期项目中也使用了不少SpringBoot相关的项目,趁着周末,配置一下使用prometheus监控微服务Springboot。
- <!-- Exposition spring_boot -->
- <dependency>
- <groupId>io.prometheus</groupId>
- <artifactId>simpleclient_spring_boot</artifactId>
- <version>0.1.0</version>
- </dependency>
- <!-- Hotspot JVM metrics -->
- <dependency>
- <groupId>io.prometheus</groupId>
- <artifactId>simpleclient_hotspot</artifactId>
- <version>0.1.0</version>
- </dependency>
- <!-- Exposition servlet -->
- <dependency>
- <groupId>io.prometheus</groupId>
- <artifactId>simpleclient_servlet</artifactId>
- <version>0.1.0</version>
- </dependency>
- @SpringBootApplication
- @EnablePrometheusEndpoint
- @EnableSpringBootMetricsCollector
- public class Application {
- private static final Logger logger = LoggerFactory.getLogger(Application.class);
- public static void main(String[] args) throws InterruptedException {
- SpringApplication.run(Application.class, args);
- logger.info("项目启动 ");
- }
- }
- @Configuration
- class MonitoringConfig {
- @Bean
- SpringBootMetricsCollector springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
- SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics);
- springBootMetricsCollector.register();
- return springBootMetricsCollector;
- }
- @Bean
- ServletRegistrationBean servletRegistrationBean() {
- DefaultExports.initialize();
- return new ServletRegistrationBean(new MetriCSServlet(), "/prometheus");
- }
- }
RequestCounterInterceptor(计数):
- public class RequestCounterInterceptor extends HandlerInterceptorAdapter {
- // @formatter:off
- // Note (1)
- private static final Counter requestTotal = Counter.build()
- .name("http_requests_total")
- .labelNames("method", "handler", "status")
- .help("Http Request Total").register();
- // @formatter:on
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e)
- throws Exception {
- // Update counters
- String handlerLabel = handler.toString();
- // get short form of handler method name
- if (handler instanceof HandlerMethod) {
- Method method = ((HandlerMethod) handler).getMethod();
- handlerLabel = method.getDeclaringClass().getSimpleName() + "." + method.getName();
- }
- // Note (2)
- requestTotal.labels(request.getMethod(), handlerLabel, Integer.toString(response.getStatus())).inc();
- }
- }
RequestTimingInterceptor(统计请求时间):
- package com.itstyle.webhook.interceptor;
- import java.lang.reflect.Method;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import io.prometheus.client.Summary;
- import org.springframework.web.method.HandlerMethod;
- import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
- public class RequestTimingInterceptor extends HandlerInterceptorAdapter {
- private static final String REQ_PARAM_TIMING = "timing";
- // @formatter:off
- // Note (1)
- private static final Summary responseTimeInMs = Summary
- .build()
- .name("http_response_time_milliseconds")
- .labelNames("method", "handler", "status")
- .help("Request completed time in milliseconds")
- .register();
- // @formatter:on
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- // Note (2)
- request.setAttribute(REQ_PARAM_TIMING, System.currentTimeMillis());
- return true;
- }
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
- Long timingAttr = (Long) request.getAttribute(REQ_PARAM_TIMING);
- long completedTime = System.currentTimeMillis() - timingAttr;
- String handlerLabel = handler.toString();
- // get short form of handler method name
- if (handler instanceof HandlerMethod) {
- Method method = ((HandlerMethod) handler).getMethod();
- handlerLabel = method.getDeclaringClass().getSimpleName() + "." + method.getName();
- }
- // Note (3)
- responseTimeInMs.labels(request.getMethod(), handlerLabel,
- Integer.toString(response.getStatus())).observe(completedTime);
- }
- }
主要是为了测试拦截器的效果
- @RestController
- public class HomeController {
- private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
- @RequestMapping("/endpointA")
- public void handlerA() throws InterruptedException {
- logger.info("/endpointA");
- Thread.sleep(RandomUtils.nextLong(0, 100));
- }
- @RequestMapping("/endpointB")
- public void handlerB() throws InterruptedException {
- logger.info("/endpointB");
- Thread.sleep(RandomUtils.nextLong(0, 100));
- }
- }
以上都配置完成后启动项目即可。
vi prometheus.yml
- - job_name: webhook
- metrics_path: '/prometheus'
- static_configs:
- - targets: ['localhost:8080']
- labels:
- instance: webhook
保存后重新启动Prometheus即可。
访问http://ip/targets 服务State 为up说明配置成功,查阅很多教程都说需要配置 spring.metrics.servo.enabled=false,否则在prometheus的控制台的targets页签里,会一直显示此endpoint为down状态,然貌似并没有配置也是ok的。
访问http://ip/graph 测试一下效果
如图所示:
https://blog.52itstyle.com/archives/1984/
https://blog.52itstyle.com/archives/2084/
https://raymondhlee.wordpress.com/2016/09/24/monitoring-spring-boot-applications-with-prometheus/
https://raymondhlee.wordpress.com/2016/10/03/monitoring-spring-boot-applications-with-prometheus-part-2/
来源: http://www.cnblogs.com/smallSevens/p/7905596.html