Springboot 使用 prometheus 监控
作者:琦彦
- 2022-10-13 中国香港
本文字数:2617 字
阅读完需:约 9 分钟

添加 prometheus 的 Maven 坐标
<dependency> <groupId>io.prometheus</groupId> <artifactId>simpleclient_spring_boot</artifactId> <version>0.0.26</version></dependency>
复制代码
启动类增加 prometheus 注解
package com.newcapec;import io.prometheus.client.spring.boot.EnablePrometheusEndpoint;import io.prometheus.client.spring.boot.EnableSpringBootMetricsCollector;import org.mybatis.spring.annotation.MapperScan;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * @version V1.0 * @Title: 应用主类 * @ClassName: com.newcapec.SpringbootdemoApplication.java * @Description: * @Copyright 2016-2017 - Powered By 研发中心 * @author: fly * @date:2017-03-15 8:01 */@SpringBootApplication@EnablePrometheusEndpoint@EnableSpringBootMetricsCollector@MapperScan("com.newcapec.dao.mapper")public class SpringbootdemoApplication { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public static void main(String[] args) { SpringApplication.run(SpringbootdemoApplication.class, args); /* SpringApplicationBuilder builder = new SpringApplicationBuilder(SpringbootdemoApplication.class); //修改Banner的模式为OFF builder.bannerMode(Banner.Mode.OFF).run(args);*/ }}
复制代码
配置文****件设置
在application.xml里设置属性:spring.metrics.servo.enabled=false,去掉重复的metrics,不然在prometheus的控制台的targets页签里,会一直显示此endpoint为down状态。
复制代码
#应用可视化监控management.security.enabled=falsespring.metrics.servo.enabled=false
复制代码
配置****prometheus.yml,指定 SpringBoot 应用的 ip 和端口
自定义 prometheus 注解
package com.newcapec.config.annotation;import java.lang.annotation.*;
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface PrometheusMetrics { /** * 默认为空,程序使用method signature作为Metric name * 如果name有设置值,使用name作为Metric name * @return */ String name() default "";}
复制代码
自定义 prometheus 切面
package com.newcapec.config.aspect;import com.newcapec.config.annotation.PrometheusMetrics;import groovy.util.logging.Slf4j;import io.prometheus.client.Counter;import io.prometheus.client.Histogram;import org.apache.commons.lang3.StringUtils;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
@Aspect@Component@Slf4jpublic class PrometheusMetricsAspect { private static final Counter requestTotal = Counter.build().name("couter_all").labelNames("api").help ("total request couter of api").register(); private static final Counter requestError = Counter.build().name("couter_error").labelNames("api").help ("response Error couter of api").register(); private static final Histogram histogram = Histogram.build().name("histogram_consuming").labelNames("api").help ("response consuming of api").register(); // 自定义Prometheus注解的全路径 @Pointcut("@annotation(com.newcapec.config.annotation.PrometheusMetrics)") public void pcMethod() { } @Around(value="pcMethod() && @annotation(annotation)") public Object MetricsCollector(ProceedingJoinPoint joinPoint, PrometheusMetrics annotation) throws Throwable { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); PrometheusMetrics prometheusMetrics = methodSignature.getMethod().getAnnotation(PrometheusMetrics.class); if (prometheusMetrics != null) { String name; if (StringUtils.isNotEmpty(prometheusMetrics.name()) ){ name = prometheusMetrics.name(); }else{ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); name = request.getRequestURI(); } requestTotal.labels(name).inc(); Histogram.Timer requestTimer = histogram.labels(name).startTimer(); Object object; try { object = joinPoint.proceed(); } catch (Exception e) { requestError.labels(name).inc(); throw e; } finally { requestTimer.observeDuration(); } return object; } else { return joinPoint.proceed(); } }}
复制代码
被监控的方****法上添加--自定义 prometheus 注解
@RequestMapping(value ="/hello", method = RequestMethod.GET)@ResponseBody@PrometheusMetricspublic String index() { return "Hello World";}
复制代码
prometheus 的监控页面
http://localhost:9090/targets
复制代码
多次访问 http://localhost:8888/web项目名/hello,然后在prometheus控制台查看相关metrics信息,couter_all,2个页签:Graph,Console
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 3
版权声明: 本文为 InfoQ 作者【琦彦】的原创文章。
原文链接:【http://xie.infoq.cn/article/f21b68fb44fae5abbab811e9d】。文章转载请联系作者。
琦彦
关注
孤独的技术没有价值 2019-08-24 加入
还未添加个人简介










评论