简单公共和私有(服务)方法上的 Micrometer @Timed 注释

Edw*_*ard 16 java metrics spring-boot prometheus spring-micrometer

我正在尝试使用千分尺注释应用普罗米修斯指标@Timed。我发现它们只适用于控制器端点,而不适用于“简单”的公共和私有方法。

给出这个例子:

@RestController
public class TestController {

    @GetMapping("/test")
    @Timed("test-endpoint") //does create prometheus metrics
    public String test() {
        privateMethod();
        publicMethod();
        return "test";
    }

    @Timed("test-private") //does NOT create prometheus metrics
    private void privateMethod() {System.out.println("private stuff");}

    @Timed("test-public") //does NOT create prometheus metrics
    public void publicMethod() {System.out.println("public stuff");}
}
Run Code Online (Sandbox Code Playgroud)

创建以下指标:

...
# HELP test_endpoint_seconds  
# TYPE test_endpoint_seconds summary
test_endpoint_seconds_count{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 1.0
test_endpoint_seconds_sum{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 0.0076286
# HELP test_endpoint_seconds_max  
# TYPE test_endpoint_seconds_max gauge
test_endpoint_seconds_max{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 0.0076286
...
Run Code Online (Sandbox Code Playgroud)

没有找到@Timed("test-private")和 的指标@Timed("test-public"),这是为什么?


注意:我在这个 github thread上读到,Spring Boot 无法识别@Timed任意方法上的注释,并且您需要手动配置TimedAspectBean 才能使其工作。我已经尝试过了,但仍然没有结果。

...
# HELP test_endpoint_seconds  
# TYPE test_endpoint_seconds summary
test_endpoint_seconds_count{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 1.0
test_endpoint_seconds_sum{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 0.0076286
# HELP test_endpoint_seconds_max  
# TYPE test_endpoint_seconds_max gauge
test_endpoint_seconds_max{class="com.example.micrometerannotationexample.TestController",exception="none",method="test",} 0.0076286
...
Run Code Online (Sandbox Code Playgroud)

要在本地尝试此操作,请参阅此处的必要要点

XII*_*XII 24

@Timed仅适用于public另一个类调用的方法。

@Timed像/这样的 Spring Boot 注释@Transactional需要所谓的代理,该代理仅在public方法调用之间发生。

一个很好的解释是这个/sf/answers/240083021/

  • 这里的问题是,Spring 的 AOP 代理不会扩展,而是包装您的服务实例来拦截调用。这具有的效果是,从服务实例内对“this”的任何调用都会直接在该实例上调用,并且不能被包装代理拦截(代理甚至不知道任何此类调用)。跟上 AOP 的速度,但是来自您答案中同一链接的这个答案对我来说很好地解释了。 (2认同)