从SpringBoot2.0开始,所有的指标metrics都采用MicroMeter的公共接口来实现,所以要在SpringBoot中创建自定义指标,需要先了解MicroMeter。
MicroMeter概念
1. 那什么是MicroMeter呢?
其实他是一组接口,类似于Slf4j提供了关于日志的统一接口一样,MicroMeter提供了一组关于监控指标统一的接口,有了这组接口,可以让使用者可以不再关心监控指标的底层实现,同时也可以更容易的切换不同的监控系统实现。
MicroMeter名词含义:MicroMeter - 千分尺(类似于游标卡尺)或者是微米,可以认为是度量长度最小单位的工具。这里,Meter(米)就是长度系统里的一个指标单位,那么MicroMeter可以理解为是长度指标系统里最小的单位(微米)或者度量工具(千分尺)。在MicroMeter里,指标Metric被称为Meter。
2. 基本概念
一个指标的组成部分:时间 + 一组维度 + 一组数值
时间通常是采集时间,可由采集方产生
维度:由维度名:维度值组成,其中维度值是有限集合,这也是维度与数值的区别。例如,维度名为性别,则维度值有{男,女},维度名为HttpStatus,则维度值是http状态码,例如404,500等。
数值:也是由数值名与数值组成,其中数值名通常取名要直观,例如计数count,最大值max等等
3. 基本组成
在MicroMeter的世界里,主要有Registry、Meter组成,其中Meter下又有Measurement与Statistics组成。
Registry: 就是保存Meter以及相关信息的仓库,不同的监控系统实现者会提供不同的Registry,来实现各自的规范。
Meter:对应着每一个指标,其内部有一组Measurement(度量)组成,每一个Measurement(度量)由有统计名称(Statistics)和数值(value)组成。
常见的Meter有Counter(计数),Gauge(数值),Timer(一段时间内的统计)。
4. 基本操作
a. 注册指标Meter:根据监控指标的不同,创建不同的Meter类型,例如创建Counter:
Counter counter = Counter
.builder("http.requests.counter") //指标名字
.baseUnit("beans") // optional
.description("a description of what this counter does") // optional
.tags("region", "test") // optional
.register(registry);
b. 记录数值
counter.increment()
//或者 先从regitry获取指标再计数
registry.counter("http.requests.counter").increment()
SpringBoot Actuator
上面说了在MicroMeter里如何创建一个指标,那么假如现在有了这个指标Meter,那它又是如何在SpringBoot中被获取然后输出结果的呢?
题外话:其实SpringBoot Actuator内提供了丰富的production-ready的功能,除了监控指标外,还提供了例如健康检查HealthCheck、HttpTracing、Auditing等功能,详细请参考官方文档:docs.spring.io/spring-boot…
1. 如何输出结果
在Actuator中,不单单是监控指标,所有的信息输出都是通过Endpoint方式来实现的,这个Endpoint同时也是注解,有点类似于Controller。但为什么不叫Controller要重新定义一个Endpoint注解呢?那是因为,Controller用户Spring MVC只提供Http的访问方式,但对于系统信息内的输出,除了采用http的方式外,很多时候采用的是JMX的技术,所以为了同时支持这两种方式,Spring提供了Endpoint这个注解。关于这个注解怎么使用,以及Actuator对它的权限控制,可以参考官方文档关于Endpoints这个章节的介绍。docs.spring.io/spring-boot…
所以,为了能够输出指标数据,Actuator也提供了一个默认Endpoint,MetricsEndpoint。看源码可知,主要有两个只读方法(被ReadOperation注解):listNames和metric。分别是列举所有的指标名字和输出对应指标的数值信息。分别对应的url为:/actuator/metrics/ 和/actuator/metrics/{metric-name}。
2. 如何将MicroMeter的指标与Actuator绑定
从上面我们已经知道Actuator是可以输出指标的,那么如何让Actuator知道我们新建了一个指标呢?
一个简单的方式是实现MeterBinder这个接口,Actuator会对每一个MeterBinder类型的bean注入MeterRegitry,详细源码参见:MeterRegistryConfigurer。
自定义Meter的方式可以参考http.server.requests这个指标实现,主要包含的class有:TomcatMetrics、TomcatMetricsBinder、WebMvcMetricsFilter。
下面是一个自定义Meter的Demo:
public class CustomCacheMetrics implements MeterBinder {
public CustomCacheMetrics() {
log.info("custom cache metrics");
}
@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder("redis.queue.failed", () -> getFailedCount())
.baseUnit("次数")
.description("redis queue failed size count")
.register(registry);
Gauge.builder("redis.queue.tohandle", () -> getToHandleCount())
.baseUnit("次数")
.description("redis queue to handle size count")
.register(registry);
}
private Number getFailedCount() {
return System.currentTimeMillis()/1000;
}
private Number getToHandleCount() {
return System.currentTimeMillis();
}
}
最后把这个class在configuration内配置成bean即可,然后访问/actuator/metrics/redis.queue.failed即能获取结果。
参考: