当前位置:

首页 > 编程开发 > Spring Boot怎么自定义监控指标

Spring Boot怎么自定义监控指标

1.创建项目pom.xml引入相关依赖4.0.0com.oliveprometheus-meter-demo0.0.1-SNAPSHOTorg.springframework.bootspring-boot-starter-parent2.3.7.RELEASE1.8UTF-8UTF-82.3.7.RELEASEorg.springframework.bootspring-boot-starter-aoporg.springframework.bootspring-boot-starter-weborg.

本文目录

      1.创建项目

      pom.xml引入相关依赖

      
      	4.0.0
      	com.olive
      	prometheus-meter-demo
      	0.0.1-SNAPSHOT
      	
      		org.springframework.boot
      		spring-boot-starter-parent
      		2.3.7.RELEASE
      		
      	
      	
      		1.8
      		UTF-8
      		UTF-8
      		2.3.7.RELEASE
      	
      	
      		
      			org.springframework.boot
      			spring-boot-starter-aop
      		
      		
      			org.springframework.boot
      			spring-boot-starter-web
      		
      		
      			org.springframework.boot
      			spring-boot-starter-actuator
      		
      		
      		
      			io.micrometer
      			micrometer-registry-prometheus
      		
      	
      	
      		
      			
      				org.springframework.boot
      				spring-boot-dependencies
      				${spring-boot.version}
      				pom
      				import
      			
      		
      	
      

      2.自定义指标

      方式一

      直接使用micrometer核心包的类进行指标定义和注册

      package com.olive.monitor;
       
      import javax.annotation.PostConstruct;
       
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Component;
       
      import io.micrometer.core.instrument.Counter;
      import io.micrometer.core.instrument.DistributionSummary;
      import io.micrometer.core.instrument.MeterRegistry;
       
      @Component
      public class NativeMetricsMontior {
       
      	/**
      	 * 支付次数
      	 */
      	private Counter payCount;
       
      	/**
      	 * 支付金额统计
      	 */
      	private DistributionSummary payAmountSum;
       
      	@Autowired
      	private MeterRegistry registry;
       
      	@PostConstruct
      	private void init() {
      		payCount = registry.counter("pay_request_count", "payCount", "pay-count");
      		payAmountSum = registry.summary("pay_amount_sum", "payAmountSum", "pay-amount-sum");
      	}
       
      	public Counter getPayCount() {
      		return payCount;
      	}
       
      	public DistributionSummary getPayAmountSum() {
      		return payAmountSum;
      	}
       
      }

      方式二

      通过引入micrometer-registry-prometheus包,该包结合prometheus,对micrometer进行了封装

      
      			io.micrometer
      			micrometer-registry-prometheus
      		

      同样定义两个metrics

      package com.olive.monitor;
       
      import javax.annotation.PostConstruct;
       
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Component;
       
      import io.prometheus.client.CollectorRegistry;
      import io.prometheus.client.Counter;
       
      @Component
      public class PrometheusMetricsMonitor {
       
      	/**
      	 * 订单发起次数
      	 */
      	private Counter orderCount;
       
      	/**
      	 * 金额统计
      	 */
      	private Counter orderAmountSum;
      	
      	@Autowired
      	private CollectorRegistry registry;
      	@PostConstruct
      	private void init() {
      		orderCount = Counter.build().name("order_request_count")
      				.help("order request count.")
      				.labelNames("orderCount")
      				.register();
      		orderAmountSum = Counter.build().name("order_amount_sum")
      				.help("order amount sum.")
      				.labelNames("orderAmountSum")
      				.register();
      		registry.register(orderCount);
      		registry.register(orderAmountSum);
      	}
       
      	public Counter getOrderCount() {
      		return orderCount;
      	}
       
      	public Counter getOrderAmountSum() {
      		return orderAmountSum;
      	}
       
      }

      prometheus 4种常用Metrics

      Counter

      连续增加不会减少的计数器,可以用于记录只增不减的类型,例如:网站访问人数,系统运行时间等。

      对于Counter类型的指标,只包含一个inc()的方法,就是用于计数器+1.

      一般而言,Counter类型的metric指标在冥冥中我们使用_total结束,如http_requests_total.

      Gauge

      可增可减的仪表盘,曲线图

      对于这类可增可减的指标,用于反应应用的当前状态。

      例如在监控主机时,主机当前空闲的内存大小,可用内存大小等等。

      对于Gauge指标的对象则包含两个主要的方法inc()和dec(),用于增加和减少计数。

      Histogram

      主要用来统计数据的分布情况,这是一种特殊的metrics数据类型,代表的是一种近似的百分比估算数值,统计所有离散的指标数据在各个取值区段内的次数。例如:我们想统计一段时间内http请求响应小于0.005秒、小于0.01秒、小于0.025秒的数据分布情况。那么使用Histogram采集每一次http请求的时间,同时设置bucket。

      Summary

      Summary和Histogram非常相似,都可以统计事件发生的次数或者大小,以及其分布情况,他们都提供了对时间的计数_count以及值的汇总_sum,也都提供了可以计算统计样本分布情况的功能,不同之处在于Histogram可以通过histogram_quantile函数在服务器计算分位数。而Sumamry的分位数则是直接在客户端进行定义的。因此对于分位数的计算,Summary在通过PromQL进行查询的时候有更好的性能表现,而Histogram则会消耗更多的资源,但是相对于客户端而言Histogram消耗的资源就更少。用哪个都行,根据实际场景自由调整即可。

      3. 测试

      定义两个controller分别使用NativeMetricsMontior和PrometheusMetricsMonitor

      package com.olive.controller;
       
      import java.util.Random;
       
      import javax.annotation.Resource;
       
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
       
      import com.olive.monitor.NativeMetricsMontior;
       
      @RestController
      public class PayController {
       
      	@Resource
      	private NativeMetricsMontior monitor;
       
      	@RequestMapping("/pay")
      	public String pay(@RequestParam("amount") Double amount) throws Exception {
      		// 统计支付次数
      		monitor.getPayCount().increment();
       
      		Random random = new Random();
      		//int amount = random.nextInt(100);
      		if(amount==null) {
      			amount = 0.0;
      		}
      		// 统计支付总金额
      		monitor.getPayAmountSum().record(amount);
      		return "支付成功, 支付金额: " + amount;
      	}
       
      }
      package com.olive.controller;
       
      import java.util.Random;
       
      import javax.annotation.Resource;
       
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
       
      import com.olive.monitor.PrometheusMetricsMonitor;
       
      @RestController
      public class OrderController {
       
      	@Resource
      	private PrometheusMetricsMonitor monitor;
       
      	@RequestMapping("/order")
      	public String order(@RequestParam("amount") Double amount) throws Exception {
      		// 订单总数
      		monitor.getOrderCount()
      			.labels("orderCount")
      			.inc();
       
      		Random random = new Random();
      		//int amount = random.nextInt(100);
      		if(amount==null) {
      			amount = 0.0;
      		}
      		// 统计订单总金额
      		monitor.getOrderAmountSum()
      			.labels("orderAmountSum")
      			.inc(amount);
      		return "下单成功, 订单金额: " + amount;
      	}
       
      }

      启动服务

      访问http://127.0.0.1:9595/actuator/prometheus;正常看到监测数据

      Spring Boot怎么自定义监控指标

      改变amount多次方式http://127.0.0.1:8080/order?amount=100和http://127.0.0.1:8080/pay?amount=10后;再访问http://127.0.0.1:9595/actuator/prometheus。查看监控数据

      Spring Boot怎么自定义监控指标

      4.项目中的应用

      项目中按照上面说的方式进行数据埋点监控不太现实;在spring项目中基本通过AOP进行埋点监测。比如写一个切面Aspect;这样的方式就非常友好。能在入口就做了数据埋点监测,无须在controller里进行代码编写。

      package com.olive.aspect;
       
      import java.time.LocalDate;
      import java.util.concurrent.TimeUnit;
       
      import javax.servlet.http.HttpServletRequest;
       
      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.springframework.stereotype.Component;
      import org.springframework.util.StringUtils;
      import org.springframework.web.context.request.RequestContextHolder;
      import org.springframework.web.context.request.ServletRequestAttributes;
       
      import io.micrometer.core.instrument.Metrics;
       
      @Aspect
      @Component
      public class PrometheusMetricsAspect {
       
          // 切入所有controller包下的请求方法
          @Pointcut("execution(* com.olive.controller..*.*(..))")
          public void controllerPointcut() {
          }
       
          @Around("controllerPointcut()")
          public Object MetricsCollector(ProceedingJoinPoint joinPoint) throws Throwable {
       
              HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
              String userId = StringUtils.hasText(request.getParameter("userId")) ? 
              		request.getParameter("userId") : "no userId";
              
              // 获取api url
              String api = request.getServletPath();
              // 获取请求方法
              String method = request.getMethod();
              long startTs = System.currentTimeMillis();
              LocalDate now = LocalDate.now();
              String[] tags = new String[10];
              tags[0] = "api";
              tags[1] = api;
              tags[2] = "method";
              tags[3] = method;
              tags[4] = "day";
              tags[5] = now.toString();
              tags[6] = "userId";
              tags[7] = userId;
              
              String amount = StringUtils.hasText(request.getParameter("amount")) ? 
              		request.getParameter("amount") : "0.0";
              
              tags[8] = "amount";
              tags[9] = amount;
              // 请求次数加1
              //自定义的指标名称:custom_http_request_all,指标包含数据
              Metrics.counter("custom_http_request_all", tags).increment();
              Object object = null;
              try {
                  object = joinPoint.proceed();
              } catch (Exception e) {
                  //请求失败次数加1
                  Metrics.counter("custom_http_request_error", tags).increment();
                  throw e;
              } finally {
                  long endTs = System.currentTimeMillis() - startTs;
                  //记录请求响应时间
                 Metrics.timer("custom_http_request_time", tags).record(endTs, TimeUnit.MILLISECONDS);
              }
              return object;
          }
      }

      编写好切面后,重启服务;访问controller的接口,同样可以进行自定义监控指标埋点

      Spring Boot怎么自定义监控指标

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发
      相关文章 更多
      springBoot项目常用目录有哪些
      springBoot项目常用目录有哪些

      springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

      解析SpringBoot和SpringMVC之间的异同
      解析SpringBoot和SpringMVC之间的异同

      解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

      探索SpringCloud和SpringBoot在微服务领域的不同应用方式
      探索SpringCloud和SpringBoot在微服务领域的不同应用方式

      近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

      SpringBoot和SpringMVC有何区别?
      SpringBoot和SpringMVC有何区别?

      SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

      比较SpringBoot和SpringMVC的异同
      比较SpringBoot和SpringMVC的异同

      SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

      SpringBoot与SpringMVC的不同点是什么?
      SpringBoot与SpringMVC的不同点是什么?

      SpringBoot和SpringMVC是Java开发中常用的两个框架,它们都是由Spring框架所提供的,但在功能和使用方式上有着一些区别。本文将分别介绍SpringBoot和SpringMVC的特点和区别。一、SpringBoot的特点:简化配置:SpringBoot通过约定优于配置的原则,大大简化了项目的配置过程。它可以自动配置项目所需要的参数,开发人

      比较和选择指南:SpringCloud与SpringBoot的功能比较
      比较和选择指南:SpringCloud与SpringBoot的功能比较

      SpringCloud和SpringBoot是目前Java领域中最热门的开源框架,它们分别提供了一套完善的微服务架构和快速构建应用程序的解决方案。本文将对它们的功能进行比较,并给出选择指南,以帮助读者了解它们的优势和适用场景。SpringBoot是一个用于开发Java应用程序的框架,它提供了一个简化的开发流程,集成了大量常用的功能和组件,减少了开发者的工作量

      SpringCloud与SpringBoot:分析它们之间的相似与不同
      SpringCloud与SpringBoot:分析它们之间的相似与不同

      深入剖析SpringCloud和SpringBoot的异同引言:在构建企业级应用程序时,Spring框架已经成为开发者们的首选。它提供了一种简单而强大的方式来构建独立于平台的应用程序。Spring框架由两个核心模块组成:SpringBoot和SpringCloud。虽然它们都可以帮助开发者快速搭建应用程序,但它们的目标和用途存在一些差异。本文将深入剖析Spr

      从架构角度看SpringCloud与SpringBoot的差异
      从架构角度看SpringCloud与SpringBoot的差异

      从架构角度看SpringCloud与SpringBoot的差异引言:在当今的互联网时代,构建分布式系统已经成为了一种必要的需求。而SpringBoot和SpringCloud正是为了满足这个需求而诞生的。尽管它们都是由Spring框架所提供的解决方案,但从架构角度来看,它们存在着一些重要的差异。本文将从架构的角度出发,对SpringBoot和SpringCl

      Java API 开发中使用 SpringBoot 的利弊分析
      Java API 开发中使用 SpringBoot 的利弊分析

      JavaAPI开发中使用SpringBoot的利弊分析随着互联网的快速发展和技术的不断更新迭代,Java技术在开发中的广泛应用引起了人们的重视。而SpringBoot作为一种微服务架构的解决方案,已经逐渐成为Java开发中的热门选择。那么,在JavaAPI开发中使用SpringBoot,到底有哪些利弊呢?下面来分析一下。利:简化开发

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。