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=false
spring.metrics.servo.enabled=false
复制代码
配置****prometheus.yml,指定 SpringBoot 应用的 ip 和端口
自定义 prometheus 注解
package com.newcapec.config.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @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
@Slf4j
public 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
@PrometheusMetrics
public 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 加入
还未添加个人简介
评论