13

I am new to using spring-boot metrics and started with micrometer. I couldn't find good examples(the fact that its new) for performing timer Metrics in my spring-boot app. I am using spring-boot-starter-web:2.0.2.RELEASE dependency . But running spring-boot server and starting jconsole, I didn't see it showing Metrics (MBeans),so I also explicitly included below dependency:

spring-boot-starter-actuator:2.0.2.RELEASE

Also micrometer dependency : 'io.micrometer:micrometer-registry-jmx:latest' After adding actuator ,it does show Metrics folder but I do not see my timer(app.timer)attribute in the list. Am I doing something wrong? Any suggestions appreciated!

Below code snippet:

MeterRegistry registry = new CompositeMeterRegistry();
long start = System.currentTimeMillis();
Timer timer = registry.timer("app.timer", "type", "ping");
timer.record(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);

This works:

Metrics.timer("app.timer").record(()-> {

 didSomeLogic;
 long t = timeOccurred - timeScheduled;
 LOG.info("recorded timer = {}", t);
});
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
anonymous-explorer
  • 365
  • 1
  • 12
  • 26

3 Answers3

10

See this part of the docs. I tweaked it to be more similar to what you want. You just have to register your Timer with the AutoConfigured MetricRegistry:

@Component
public class SampleBean {

    private final Timer timer;

    public SampleBean(MeterRegistry registry) {
        long start = System.currentTimeMillis();
        this.timer = registry.timer("app.timer", "type", "ping");
    }

    public void handleMessage(String message) {
        timer.record(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
    }

}
Dovmo
  • 8,121
  • 3
  • 30
  • 44
  • Thanks dovmo for the reply. I'll check this out. But can I use timer() Metric without creating registry? Something like Metrics.timer().record(). I don't think I want to create a custom registry . I just want to be able to record timer metrics for my app. – anonymous-explorer Aug 21 '18 at 16:46
  • Ah, I see. Let me revise. You want to use the one that's autoconfigured – Dovmo Aug 21 '18 at 17:05
  • So I was able to make it work with above code(Edited at the end of post), kindly check. In JMX console, I can now see the metric details but no visuals graphs, so not sure if there is a better way to understand these metric visually. – anonymous-explorer Aug 21 '18 at 20:54
  • Great! If you could upvote and choose my answer as correct, then that would be great. In terms of the visualization, JMX will only give you the instantaneous values. Other monitoring systems plug in to JMX to make the visualizations. See here for the list of monitoring tools you can use (even if just locally) to view that data: https://micrometer.io/docs; Atlas, Datadog, etc. – Dovmo Aug 21 '18 at 21:07
  • I tried to upvote but unfortunately since I have less reputations it might not show. It's recorded though as per notification I received. Thanks! – anonymous-explorer Sep 03 '18 at 00:20
  • Better to use System.nanoTime as currentTimeMillis may be updated during execution, for more details: https://stackoverflow.com/a/57258891/2580829 – David Barda Dec 10 '20 at 12:03
  • true, that handleMessage() does the main part. – GvSharma Nov 28 '22 at 14:08
9

This could be. If you are using Spring Boot 2, just call Timer wherever you want, no need to use a constructor.

public void methodName(){
    //start
    Stopwatch stopwatch = Stopwatch.createStarted();// Google Guava
    
    // your job here
         
    // check time
    Metrics.timer("metric-name",
            "tag1", this.getClass().getSimpleName(), //class
            "tag2", new Exception().getStackTrace()[0].getMethodName()) // method 
            .record(stopwatch.stop().elapsed());
}
Martin Schröder
  • 4,176
  • 7
  • 47
  • 81
Alexandr Kovalenko
  • 934
  • 1
  • 12
  • 13
  • This is the example I was looking for, regarding how to use not only Metrics.timer() (that I use instead via the annotation @Timer on the method in Spring Boot 2.3.4, since it is for me simpler), but also Metrics.summary(), with which I log in Prometheus the size of the elaborated data. – marcor92 Apr 02 '21 at 21:01
4

Another way to output the timer information with Spring Boot Micrometer, is to add the annotation io.micrometer.core.annotation.Timed to the method whose execution to track, and add in the ApplicationContext class, or in any class that has the @Configuration annotation, the following method:

@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
    return new TimedAspect(registry);
}

After that, a working example would be:

@PostMapping(value = "/save", produces = "application/json")
@Timed(description = "Time spent saving results")
public ResponseEntity<Integer> saveResults(@CookieValue(name = "JSESSIONID") String sessionId) {
    return new ResponseEntity<>(importer.saveResults(sessionId), HttpStatus.OK);
}

See also this answer: https://stackoverflow.com/a/49193908/5538923 .

marcor92
  • 417
  • 5
  • 13