Hi,
I created a simple project with these dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
And create a simple Controller
@RestController
public class DemoController {
private Random random = new Random();
@GetMapping("/")
@Timed
public String calculateTimed() throws InterruptedException {
Thread.sleep(random.nextInt(1000));
return "This is a test";
}
}
And I am expected to see the timed metric when I called /actuator/metrics but I didn't get anything
Here is the result to http://localhost:9999/actuator/metrics
{
names: [
"jvm.buffer.memory.used",
"jvm.memory.used",
"jvm.buffer.count",
"logback.events",
"process.uptime",
"jvm.memory.committed",
"system.load.average.1m",
"jvm.buffer.total.capacity",
"jvm.memory.max",
"system.cpu.count",
"http.server.requests",
"process.start.time"
]
}
Do I need to add an additional dependency?
Thanks
Looks like the metric is there. It is called http.server.requests. FYI, by default all @GetMappings are timed, even if you don't annotate them with @Timed. This default can be reversed so that only those that methods or classes that are annotated are timed.
I simplify my first test. Here is a more complex example that doesn't work.
@RestController
public class DemoController {
@Autowired
private DemoService demoService;
@GetMapping("/")
public String hello() {
return demoService.hello();
}
@GetMapping("/service")
public String hello1() {
return demoService.hello1();
}
}
@Component
public class DemoService {
@Autowired
private MeterRegistry meterRegistry;
private Random random = new Random();
public String hello() {
Timer timer = meterRegistry.timer("hello");
timer.record(() -> {
try {
Thread.sleep(random.nextInt(500));
System.out.println("Jello");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return "Hello";
}
@Timed
public String hello1() {
try {
Thread.sleep(random.nextInt(500));
System.out.println("Jello");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello2";
}
}
As you can see only the one created without the annotation works.
{
names: [
"jvm.buffer.memory.used",
"jvm.memory.used",
"jvm.buffer.count",
"logback.events",
"process.uptime",
"jvm.memory.committed",
"http.server.requests",
**"hello",**
"system.load.average.1m",
"jvm.buffer.total.capacity",
"jvm.memory.max",
"system.cpu.count",
"process.start.time"
]
}
Did you test before closing?
Im still quite confused by this. If I have something like
@GetMapping("/")
@Timed("my.awesome.timer")
public String calculateTimed() throws InterruptedException {
return "asdf";
}
What do I need to do, so that the new timer my.awesome.timer just for this specific endpoint shows up in /actuator/metrics?
*/actuator/metrics instead of /metrics
@kleino By /metrics, are you implying this is a Boot 1.5.x app you are working on?
If so, we backport Micrometer support to 1.5.x, but do not replace the old Boot 1.5.x metrics at the same time. So what shows up in /metrics in Boot 1.5.x is whatever showed up there as a consequence of Boot's existing code.
Your my.awesome.timer does show up in monitoring systems that Micrometer is exporting to with the micrometer-spring-legacy backport applied, however.
@jkschneider thx for the fast response. I'v tried it with boot 2.0.0.RC1 & M7 and micrometer-core', version: '1.0.0-rc.7 + spring webflux so I guess my problem is related to https://github.com/micrometer-metrics/micrometer/issues/199
@Bean TimedAspect should be created, below is the offical guidence :
https://micrometer.io/docs/concepts#_the_code_timed_code_annotation
@seedily But it still doesn't working. I tired using @Timed on arbitrary methods after configuring TimedAspect but isn't really working
@seedily But it still doesn't working. I tried using @timed on arbitrary methods after configuring TimedAspect but isn't really working
was this really fixed? I have followed the official documentation and I cannot see TimedAspect being invoked.
I have been trying with SpringBoot (and associated) 2.1.8.RELEASE and 2.1.5.RELEASE, micrometer (and co) on 1.1.4, 1.1.6 and 1.3.0, Java 11, Java 12 and no joy.
I have learned that it works for some people and not for some other people. Any ideas here?
EDIT:
Seemingly it works if you call a @Timed method in a _@Component_ from another _@Component_
Is this how it is supposed to work? The documentation still says that it is supported on _arbitrary_ methods with the TimedAspect but seemingly that does not work.
The @Timed from my understanding must be on a Spring managed @Component (or their derivatives like @Service, ...) in order for the aspect weaving to happen by Spring. The caller itself must not necessarily be Spring managed, but it must perform calls on the aspect-woven instance and not an otherwise instantiated one.
If one is instantiating the callee class himself, then the aspect-weaving needs to be carried out manually.
I had dependency injected the @Component that had the @Timed but called it from an thread happening in just plain old executor and it did not work. Though I referenced it trough a parent class instance field so it might be that the call bypassed the weaving.
To make this work I had to do the following. I'm creating a counter, but for a timer it's similar.
First, add a dependency to org.aspectj:aspectjweaver to my Spring Boot application:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
Then, create the counter by creating a MeterRegistryCustomizer bean (for example in the Spring Boot application class; you can also do this in any other @Configuration-annotated class):
@Bean
public MeterRegistryCustomizer<MeterRegistry> meterRegistryCustomizer() {
return registry -> registry.counter("calendar.create");
}
In the same class, create a CountedAspect bean. This registers an AspectJ aspect that will handle the @Counted annotation:
@Bean
public CountedAspect countedAspect(MeterRegistry meterRegistry) {
return new CountedAspect(meterRegistry);
}
If you want to use the @Timer annotation, you would have to create a TimedAspect bean in the same way:
@Bean
public TimedAspect timedAspect(MeterRegistry meterRegistry) {
return new TimedAspect(meterRegistry);
}
Then you can use the @Counted and @Timed annotations, for example on your controller methods:
@RestController
public class CalendarController {
// ...
@PostMapping("/items")
@Counted("calendar.create")
public CalendarItem create(@RequestBody CalendarItem calendarItem) {
// ...
}
}
@jesperdj I don't think that the following is required.
@Bean
public MeterRegistryCustomizer<MeterRegistry> meterRegistryCustomizer() {
return registry -> registry.counter("calendar.create");
}
When you run the method annotated with @Timed once, you will have the name in the list.
@fsi-kanchana I think you are right; explicitly creating the counter is not necessary, it's indeed created at first use automatically.
Hello Team,
I am currently using 2.4.1 recently released.
The issue is still here I believe.
Created an out of the box Webflux project out of spring.io.
No @Timed annotation, can see the usual
# TYPE http_server_requests_seconds summary
http_server_requests_seconds_count{exception="None",method="POST",outcome="SUCCESS",status="200",uri="/myRoute",} 1.0
http_server_requests_seconds_sum{exception="None",method="POST",outcome="SUCCESS",status="200",uri="/myRoute",} 0.610389546
# HELP http_server_requests_seconds_max
# TYPE http_server_requests_seconds_max gauge
http_server_requests_seconds_max{exception="None",method="POST",outcome="SUCCESS",status="200",uri="/myRoute",} 0.610389546
However, annotated my controller with @Timed("pleasefindme")
and getting the exact same under /prometheus endpoint.
A little help please?
Thank you
@patpatpat123 commenting on this old closed issue is not the best way to get support. See https://github.com/spring-projects/spring-boot/issues/18680; the feature you're trying to use is not in Spring Boot yet.
Most helpful comment
@seedily But it still doesn't working. I tired using @Timed on arbitrary methods after configuring TimedAspect but isn't really working