SpringBoot整合Prometheus

一、需求

实现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 中查看指标数据

在 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();
    }
}

四、代码路径

gitee.com/huan1993/sp…

五、参考链接

1、docs.spring.io/spring-boot…
2、代码路径-io.micrometer.prometheus.PrometheusNamingConvention#name
3、代码路径-org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter#record


作者:huan1993
链接:https://juejin.cn/post/6939810444391481381