如何在SLA和标签上注册Micrometer Timer?

Eth*_*roy 1 java spring-boot prometheus micrometer

我正在尝试将我的Prometheus指标迁移到千分尺,但现在我在这里遇到了一件事......

目前我的Prometheus直方图配置如下:

private static final Histogram REQUEST_DURATION = Histogram
        .build("http_request_duration_milliseconds", "Duration in milliseconds for processing a request.")
        .labelNames("http_method", "http_status", "java_class", "java_method")
        .buckets(10, 25, 50, 100, 500, 1000)
        .register();
Run Code Online (Sandbox Code Playgroud)

因此,为了切换到千分尺,我将其替换为如下:

Timer.builder("http.request.duration")
            .description("Duration in seconds for processing a request.")
            .sla(Duration.ofMillis(10), Duration.ofMillis(25), Duration.ofMillis(50), Duration.ofMillis(100), Duration.ofMillis(500), Duration.ofMillis(1000), Duration.ofMillis(5000))
            .register(registry);
Run Code Online (Sandbox Code Playgroud)

好.让我们看看我想如何使用它...目前我只是打电话

REQUEST_DURATION.labels(httpMethod, httpStatus, javaClass, javaMethod).observe(milliseconds);
Run Code Online (Sandbox Code Playgroud)

所以我把它换成了

Metrics.timer("http.request.duration",
            "http.method", httpMethod,
            "http.status", httpStatus,
            "java.class", javaClass,
            "java.method", javaMethod)
            .record(Duration.ofNanos(nanoseconds));
Run Code Online (Sandbox Code Playgroud)

但现在的问题是,Micrometer抱怨我以前配置了没有这些标签的指标.当然我做了,因为我不知道那时的价值观.这里的例外:

java.lang.IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter containing tag keys []. The meter you are attempting to register has keys [http.method, http.status, java.class, java.method].

好.所以我想,然后让我们用Metrics.timer调用来指定桶.但这不起作用,因为没有传递这些值的方法.

所以...我如何设置sla,并tags我的指标?

Eth*_*roy 7

我得到了Micrometer松弛通道的答案.Micrometer-解决这个问题的方法不是注册度量本身,而是注册过滤器,如下所示:

registry.config().meterFilter(new MeterFilter() {
    @Override
    public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
        if (id.getName().equals("http.request.duration")) {
            return DistributionStatisticConfig.builder()
                    .sla(Duration.ofMillis(10).toNanos(),
                         Duration.ofMillis(25).toNanos(),
                         Duration.ofMillis(50).toNanos(), 
                         Duration.ofMillis(100).toNanos(),
                         Duration.ofMillis(500).toNanos(),
                         Duration.ofMillis(1000).toNanos(), 
                         Duration.ofMillis(5000).toNanos())
                    .build()
                    .merge(config);
        }
        return config;
    }
});
Run Code Online (Sandbox Code Playgroud)

使用Metrics.timer(...)上述千分尺推送度量值时,将调用此过滤器并应用此处指定的所有配置.该过滤器仅呼吁米的初始化,即当Metrics.timer(...)被称为第一次与这个特定的nametags.所以我们不必担心这里的表现.