在普罗米修斯中显示任意@Timed 指标

Posted

技术标签:

【中文标题】在普罗米修斯中显示任意@Timed 指标【英文标题】:Showing arbitrary @Timed metrics in prometheus 【发布时间】:2021-02-13 04:35:27 【问题描述】:

我正在尝试将时间指标添加到我的 spring-boot Web 应用程序。目前,该应用程序使用 micrometer、prometheus 和 spring-boot-actuator。

我可以通过 http://localhost:8080/actuator/prometheus 连接到我的应用程序并查看默认指标列表,例如:

# HELP jvm_gc_memory_allocated_bytes_total Incremented for an increase in the size of the young generation memory pool after one GC to before the next
# TYPE jvm_gc_memory_allocated_bytes_total counter
jvm_gc_memory_allocated_bytes_totalapplication="my app", 0.0
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
jvm_classes_loaded_classesapplication="my app", 7581.0
...

太棒了!

但现在我想将计时指标附加到我的一个控制器的方法中。我希望它就像在类中添加 @Timed 注释一样简单:

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.micrometer.core.annotation.Timed;

@RestController
@Timed
public class GreetingController 

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @GetMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) 
        doWork();
        return buildResponse(name);
    

    private void doWork() 
        try 
            Thread.sleep((long) (1000 * Math.random()));
         catch (InterruptedException e) 
        
    

    private Greeting buildResponse(String name) 
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    

但是,这似乎不会向 http://localhost:8080/actuator/prometheus 端点添加任何指标。

为了让端点报告GreetingController 类的计时指标,尤其是doWorkbuildResponse 方法,我需要采取哪些步骤?

-- 更新--

我已经设法获得了我想要的结果,但它比我预期的要多一些工作,我希望有一个更简单的方法。我明确地将Timer 对象添加到我想要测量的每个方法中,如下所示:

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;

@RestController
public class GreetingController 

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @Autowired
    MeterRegistry meterRegistry;

    @GetMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) 
        doWork();
        return buildResponse(name);
    

    private void doWork() 
        Timer timer = meterRegistry.timer(this.getClass().getSimpleName() + ".doWork");
        timer.record(() -> 
            try 
                Thread.sleep((long) (1000 * Math.random()));
             catch (InterruptedException e) 
            
        );
    

    private Greeting buildResponse(String name) 
        AtomicReference<Greeting> response = new AtomicReference<>();

        Timer timer = meterRegistry.timer(this.getClass().getSimpleName() + ".buildResponse");
        timer.record(() -> 
            response.set(new Greeting(counter.incrementAndGet(), String.format(template, name)));
        );

        return response.get();
    

但至少这让我得到了我正在寻找的结果:

# HELP GreetingController_buildResponse_seconds  
# TYPE GreetingController_buildResponse_seconds summary
GreetingController_buildResponse_seconds_countapplication="my app", 10.0
GreetingController_buildResponse_seconds_sumapplication="my app", 0.001531409
# HELP GreetingController_buildResponse_seconds_max  
# TYPE GreetingController_buildResponse_seconds_max gauge
GreetingController_buildResponse_seconds_maxapplication="my app", 2.52253E-4
# HELP GreetingController_doWork_seconds_max  
# TYPE GreetingController_doWork_seconds_max gauge
GreetingController_doWork_seconds_maxapplication="my app", 0.941169892
# HELP GreetingController_doWork_seconds  
# TYPE GreetingController_doWork_seconds summary
GreetingController_doWork_seconds_countapplication="my app", 10.0
GreetingController_doWork_seconds_sumapplication="my app", 4.767700907

有没有更清洁的方法?

【问题讨论】:

【参考方案1】:

将TimedAspect注册为配置类中的bean:

@Bean
public TimedAspect timedAspect(MeterRegistry meterRegistry) 
    return new TimedAspect(meterRegistry);

【讨论】:

【参考方案2】:

@Timed("问候") 必须附加标签

【讨论】:

以上是关于在普罗米修斯中显示任意@Timed 指标的主要内容,如果未能解决你的问题,请参考以下文章

指标在普罗米修斯中不可见

kubelet 指标未出现在普罗米修斯中

自定义指标未在普罗米修斯中公开

如何在普罗米修斯中公开 nginx 指标? [关闭]

如何在普罗米修斯中使用 relable_config 为指标添加前缀

如何在普罗米修斯中对具有高基数的指标发出警报