一、需求
实现SpringBoot和Prometheus的一个简单整合。
二、实现步骤
1、引入jar包
<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>
<scope>runtime</scope>
</dependency>
</dependencies>
复制代码
2、application.prometheus文件配置
1、启用prometheus端点。
2、给每个指标指定一个通用的标签,application见下方的截图。
3、指定管理的端口和路径。
spring.application.name=actuator-prometheus
server.port=10001
# 管理端点的跟路径,默认就是/actuator
management.endpoints.web.base-path=/actuator
# 管理端点的端口
management.server.port=10002
# 暴露出 prometheus 端口
management.endpoints.web.exposure.include=prometheus
# 启用 prometheus 端口,默认就是true
management.metrics.export.prometheus.enabled=true
# 增加每个指标的全局的tag,及给每个指标一个 application的 tag,值是 spring.application.name的值
management.metrics.tags.application=${spring.application.name}
3、查看指标数据
![查看指标数据](data:image/svg+xml;utf8,<?xml version="1.0"?>)
可以看到里面存在一个 process_files_open_files
指标,待会儿集成到prometheus
中,我们在prometheus
中查询一下这个指标,看是否存在。
4、接入到 prometheus 中
1、修改 prometheus.yml 配置文件
scrape_configs:
- job_name: 'spring-boot-actuator-exporter'
# 指定抓取的路径
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['localhost:10002']
labels:
nodename: 'spring-boot-actuator'
2、在 prometheus 中查看指标数据
三、个性化 MeterRegistry
1、增加全局标签
当我们和 prometheus 集成后,默认的 MeterRegistry是 PrometheusMeterRegistry
。 当我们要 个性化 MeterRegistry
时,可以实现MeterRegistryCustomizer
接口。
eg:
1、我们要为所有的指标增加一个 role=admin
的标签。
@Configuration
public class CustomMeterRegistryCustomizer implements MeterRegistryCustomizer<MeterRegistry> {
@Override
public void customize(MeterRegistry registry) {
registry.config().commonTags("role", "master");
}
}
2、对标签、指标名称等进行过滤。
比如:替换标签的值、判断是否需要该指标等等,此处实现只需要jvm开头的指标,其余的指标一律排除。
,需要实现MeterFilter
接口。
@Configuration
public class CustomMeterFilter implements MeterFilter {
/**
* 只需要和jvm相关的指标数据,其余的数据一律拒绝
*/
@Override
public MeterFilterReply accept(Meter.Id id) {
if (id.getName().startsWith("jvm")) {
return MeterFilterReply.ACCEPT;
}
return MeterFilterReply.DENY;
}
}
![只剩下jvm相关的指标](data:image/svg+xml;utf8,<?xml version="1.0"?>)
3、监控业务数据
1、如果我们的监控依赖其它的bean,推荐使用MeterBinder
注册
@Component
public class OrderAmountMeterBinder implements MeterBinder {
@Autowired
private OrderService orderService;
@Override
public void bindTo(@NonNull MeterRegistry registry) {
Gauge.builder("order_amount", orderService, service -> service.retrieveOrderAmount().doubleValue())
// 这个 fen 会接到 order_amount的后面及在 prometheus 中的指标名称为 order_amount_fen
.baseUnit("fen")
.description("获取订单的金额")
.tag("system", "order")
.strongReference(false)
.register(registry);
}
}
![image.png](data:image/svg+xml;utf8,<?xml version="1.0"?>)
2、不依赖其它bean
@Service
public class OrderService {
@Autowired
private MeterRegistry meterRegistry;
@PostConstruct
public void init() {
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(this::createOrder, 0, 1, TimeUnit.SECONDS);
}
/**
* 创建订单
*/
public int createOrder() {
Counter.builder("order_counter")
.tag("system", "order")
.baseUnit("total")
.description("订单的总数量")
.register(meterRegistry)
.increment();
return ORDER_CNT.get();
}
}
四、代码路径
五、参考链接
1、docs.spring.io/spring-boot…
2、代码路径-io.micrometer.prometheus.PrometheusNamingConvention#name
3、代码路径-org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter#record