SpringBoot系列之Prometheus自定义埋点姿势二

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
简介: 关于Prometheus的自定义埋点,前一篇博文已经介绍了,为啥这里又来一次?看过前文的小伙伴可能会知道,之前采用的simpleclient包定义的几个metric来实现的,实际上有更简单方便的姿势,那就是直接借助MeterRegistry来创建Metric来实现数据采集即可

image.png

SpringBoot系列之Prometheus自定义埋点姿势二


关于Prometheus的自定义埋点,前一篇博文已经介绍了,为啥这里又来一次?

看过前文的小伙伴可能会知道,之前采用的simpleclient包定义的几个metric来实现的,实际上有更简单方便的姿势,那就是直接借助MeterRegistry来创建Metric来实现数据采集即可


相比较于前文的实现,总的来说简易程度可见一般,上篇文章可以点击下文查看


  • 【中间件】Prometheus自定义埋点上报 | 一灰灰Blog


II. 自定义上报


依然是搭建一个基础项目工程,本文演示的项目主要为SpringBoot2.2.1版本,更高的版本使用姿势没有太大的区别,至于1.x版本的不确保可行(因为我并没有测试)


1.依赖


pom依赖,主要是下面几个包

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
</dependencies>
复制代码


2. 配置信息


其次是配置文件,注册下Prometheus的相关信息

spring:
  application:
    name: prometheus-example
management:
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    tags:
      application: ${spring.application.name}
复制代码


上面配置中,有两个关键信息,前面博文也有介绍,这里简单说明


  • management.endpoints.web.exposure.include 这里指定所有的web接口都会上报
  • metrics.tags.application 这个应用所有上报的metrics 都会带上application这个标签


配置完毕之后,会提供一个 /actuator/prometheus的端点,供prometheus来拉取Metrics信息


3. 自定义拦截器实现采集上报


实现一个基础的拦截器,用来拦截所有的http请求,然后收集请求信息上报


public class MetricInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private MeterRegistry meterRegistry;
    private ThreadLocal<Timer.Sample> threadLocal = new ThreadLocal<>();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 总计数 + 1
        meterRegistry.counter("micro_req_total", Tags.of("url", request.getRequestURI(), "method", request.getMethod())).increment();
        // 处理中计数 +1
        meterRegistry.gauge("micro_process_req", Tags.of("url", request.getRequestURI(), "method", request.getMethod()), 1);
        Timer.Sample sample = Timer.start();
        threadLocal.set(sample);
        return super.preHandle(request, response, handler);
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        try {
            super.postHandle(request, response, handler, modelAndView);
        } finally {
            meterRegistry.gauge("micro_process_req", Tags.of("url", request.getRequestURI(), "method", request.getMethod()), -1);
            //  Timer timer = meterRegistry.timer("micro_req_histogram", Tags.of("url", request.getRequestURI(), "method", request.getMethod(), "code", String.valueOf(response.getStatus())));
            Timer timer = Timer.builder("micro_req_histogram").minimumExpectedValue(Duration.ofMillis(1)).maximumExpectedValue(Duration.ofMinutes(3))
                    .sla(Duration.ofMillis(10), Duration.ofMillis(50), Duration.ofMillis(100), Duration.ofMillis(300), Duration.ofMillis(1000))
                    .tags(Tags.of("url", request.getRequestURI(), "method", request.getMethod(), "code", String.valueOf(response.getStatus())))
                    .register(meterRegistry);
            threadLocal.get().stop(timer);
            threadLocal.remove();
        }
    }
}
复制代码


注意上面的三种Metric的创建方式


  • Counter: 直接使用 meterRegistry.counter()来创建metric并实现计数+1
  • 传参中,Tags组成的就是propmetheus中定义的label,kv格式,第一个参数用来定义MetricName
  • Gauge: 使用姿势与上面基本相同,不过需要注意计数的加减是直接在传参中
  • Histogram: 它的使用姿势就需要特别注意下了,在preHander中定义的是 Timer.Sampler对象,在 postHandler中实现的数据采集


上面短短一点代码,就实现了一个简单的自定义信息上报;接下来就是注册拦截器了


4. 注册并测试


拦截器依赖了Spring的bean对象,因此需要将它定义为bean对象


@RestController
@SpringBootApplication
public class Application implements WebMvcConfigurer {
    private Random random = new Random();
    @Bean
    public MetricInterceptor metricInterceptor() {
        return new MetricInterceptor();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(metricInterceptor()).addPathPatterns("/**");
    }
    @GetMapping(path = "hello")
    public String hello(String name) {
        int sleep = random.nextInt(200);
        try {
            Thread.sleep(sleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello sleep: " + sleep + " for " + name;
    }
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}
复制代码


基于此一个简单的自定义采集上报就完成了;项目启动之后,通过访问采集端点查看是否有数据上报


image.png


最后小结一下,虽然SpringBoot可以非常方便的接入prometheus来采集一些常见的指标,但是当我们有自定义上报指标的需求时,直接使用MeterRegistry来收集信息,创建Metric是个不错的选择,通常我们选择的三种类型作用如下


  • 总的请求数:采用Counter
  • 当前正在处理的请求数:采用Gauge
  • 请求耗时直方图: Histogram



相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
相关文章
|
3月前
|
Prometheus 监控 Cloud Native
自定义grafana_table(数据源Prometheus)
综上所述,自定义 Grafana 表格并将 Prometheus 作为数据源的关键是理解 PromQL 的查询机制、熟悉 Grafana 面板的配置选项,并利用 Grafana 强大的转换和自定义功能使数据展示更为直观和有洞见性。随着对这些工具更深入的了解,您将可以创建出更高级的监控仪表盘,以支持复杂的业务监控需求。
271 1
|
3月前
|
Prometheus 监控 Cloud Native
Spring Boot 性能护航!Prometheus、Grafana、ELK 组合拳,点燃数字化时代应用稳定之火
【8月更文挑战第29天】在现代软件开发中,保证应用性能与稳定至关重要。Spring Boot 作为流行的 Java 框架,结合 Prometheus、Grafana 和 ELK 可显著提升监控与分析能力。Prometheus 负责收集时间序列数据,Grafana 将数据可视化,而 ELK (Elasticsearch、Logstash、Kibana)则管理并分析应用日志。通过具体实例演示了如何在 Spring Boot 应用中集成这些工具:配置 Prometheus 获取度量信息、Grafana 显示结果及 ELK 分析日志,从而帮助开发者快速定位问题,确保应用稳定高效运行。
105 1
|
4月前
|
Prometheus 监控 Cloud Native
使用Spring Boot和Prometheus进行监控
使用Spring Boot和Prometheus进行监控
|
5月前
|
Prometheus 监控 Cloud Native
性能监控神器Prometheus、Grafana、ELK 在springboot中的运用
【6月更文挑战第27天】在 Spring Boot 应用中,监控和日志管理是确保系统稳定性和性能的重要手段。
331 4
|
5月前
|
Prometheus Cloud Native Java
springboot集成prometheus异常处理
springboot集成prometheus异常处理
78 2
|
5月前
|
Prometheus 监控 Cloud Native
SpringBoot2.x整合Prometheus+Grafana【附源码】
SpringBoot2.x整合Prometheus+Grafana【附源码】
89 1
|
Java 应用服务中间件 Maven
传统maven项目和现在spring boot项目的区别
Spring Boot:传统 Web 项目与采用 Spring Boot 项目区别
489 0
传统maven项目和现在spring boot项目的区别
|
XML Java 数据库连接
创建springboot项目的基本流程——以宠物类别为例
创建springboot项目的基本流程——以宠物类别为例
153 0
创建springboot项目的基本流程——以宠物类别为例
|
存储 机器学习/深度学习 IDE
SpringBoot 项目与被开发快速迁移|学习笔记
快速学习 SpringBoot 项目与被开发快速迁移
SpringBoot 项目与被开发快速迁移|学习笔记
|
Java Spring
自定义SpringBoot项目的启动Banner
``Banner``是``SpringBoot``框架一个特色的部分,其设计的目的无非就是一个框架的标识,其中包含了版本号、框架名称等内容,既然``SpringBoot``为我们提供了这个模块,它肯定也是可以更换的这也是``Spring``开源框架的设计理念。