You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Micrometer的_seconds系列指标生成位置及自定义扩展咨询

Micrometer指标生成位置与自定义扩展指南

一、标准分位数指标的生成位置

你贴的这种带_bucket、_count、_sum的指标,是Micrometer里Timer类型指标的默认输出格式(对应Prometheus exporter的输出)。核心生成逻辑分布在这些类中:

  • io.micrometer.core.instrument.Timer:Timer的核心接口,定义了分位数、计数、总耗时的统计逻辑
  • io.micrometer.prometheus.PrometheusMeterRegistry:Prometheus导出器的核心类,负责把Timer的统计数据格式化成你看到的文本行格式

简单来说,当你在代码里创建并使用Timer(比如调用Timer.start()或record()方法),Micrometer的核心统计模块会自动累积分位数、请求计数、总耗时数据,最后由Prometheus注册表将这些数据转换为指定的指标格式输出。

二、扩展自定义指标(均值、吞吐量)

要新增metric_name_seconds_mean和metric_name_seconds_throughput,可以通过两种实用方式实现:

方式1:基于现有Timer数据计算

直接复用Timer已统计的count()和totalTime()数据,快速计算均值和吞吐量:

// 假设已创建并注册了目标Timer
Timer timer = Timer.builder("metric_name")
        .tags("key", "value")
        .register(meterRegistry);

// 注册均值指标:总耗时/请求数
Gauge.builder("metric_name_seconds_mean", timer, t -> t.totalTime(TimeUnit.SECONDS) / t.count())
        .tags(timer.getId().getTags())
        .register(meterRegistry);

// 注册吞吐量指标:单位时间内的请求数(示例用FunctionCounter统计累计请求数,Prometheus侧可通过rate函数计算瞬时吞吐量)
FunctionCounter.builder("metric_name_seconds_throughput", timer, Timer::count)
        .tags(timer.getId().getTags())
        .register(meterRegistry);

这种方式无需额外埋点,适合快速扩展基础衍生指标。

方式2:自定义统计逻辑(灵活适配特殊场景)

如果需要自定义统计窗口或特殊计算规则,可以实现自己的统计类:

class CustomTimerStats {
    private final AtomicLong requestCount = new AtomicLong(0);
    private final DoubleAdder totalElapsedSeconds = new DoubleAdder();
    private final Instant startTime = Instant.now();

    // 埋点时调用,记录单次请求耗时
    public void record(double elapsedSeconds) {
        requestCount.incrementAndGet();
        totalElapsedSeconds.add(elapsedSeconds);
    }

    // 向注册表注册自定义指标
    public void register(MeterRegistry registry, String metricName, Iterable<Tag> tags) {
        // 注册均值指标
        Gauge.builder(metricName + "_seconds_mean", this, stats -> {
            long count = stats.requestCount.get();
            return count == 0 ? 0 : stats.totalElapsedSeconds.sum() / count;
        })
                .tags(tags)
                .register(registry);

        // 注册吞吐量指标:累计请求数/运行时长(也可自定义滑动窗口)
        Gauge.builder(metricName + "_seconds_throughput", this, stats -> {
            long elapsedSeconds = Duration.between(startTime, Instant.now()).getSeconds();
            return elapsedSeconds == 0 ? 0 : stats.requestCount.get() / (double) elapsedSeconds;
        })
                .tags(tags)
                .register(registry);
    }
}

// 使用示例
CustomTimerStats customStats = new CustomTimerStats();
customStats.register(meterRegistry, "metric_name", Tags.of("key", "value"));

// 业务埋点
customStats.record(0.256);

注意事项

  • 自定义指标命名需符合Prometheus规范:小写字母、下划线分隔,避免特殊字符
  • Spring Boot环境下,MeterRegistry实例会自动注入,直接使用即可
  • 注册指标前可通过meterRegistry.find(metricName).tags(tags).gauge()检查是否已存在,避免重复注册

内容的提问来源于stack exchange,提问作者John Warestone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:10:27