• Grafana+Prometheus系统监控之SpringBoot


    前言

    前一段时间使用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>
    

    配置Application

    @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("项目启动 ");
    	}
    }
    

    配置MonitoringConfig

    @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");
        }
    }
    

    配置Interceptor

    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);
        }
    }
    

    配置Controller

    主要是为了测试拦截器的效果

    @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));
         }
    }
    

    以上都配置完成后启动项目即可。

    配置Prometheus

    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 测试一下效果

    配置Grafana

    如图所示:

    参考链接

    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/

  • 相关阅读:
    Eclipse配置方法注释模板
    彻底清除Github上某个文件以及历史
    eclipse快捷键
    Hibernate执行原生SQL
    API接口规范
    eclipse配置google代码风格
    eclipse format xml
    git撤销commit
    使用postman测试文件上传
    centos7下部署elasticSearch集群
  • 原文地址:https://www.cnblogs.com/smallSevens/p/7905596.html
Copyright © 2020-2023  润新知