How to measure service methods using spring boot 2 and micrometer

前端 未结 2 1644
小鲜肉
小鲜肉 2020-12-29 04:25

I started my first project on Spring Boot 2 (RC1). Thanks to the already good documentation this has not been to hard coming from Spring Boot 1.x.

However now that I

2条回答
  •  萌比男神i
    2020-12-29 04:55

    Here's a little sample which should get you going. There's more variants to Timer.record() which aren't shown here. (Also: Field injection only used for brevity.) You don't have to put the called methods name into a tag. You can also make it part of the metric name itself. Just wanted to show what you could do.

    Update 2018-03-12: As of Micrometer 1.0.0 a TimedAspect has been introduced so that you can also use the @Timed annotation. For now you need to register the Bean yourself. (You need to be cautious though when you have custom @Timed annotations on your Spring-MVC or Jersey resources.) This was already mentioned by Michal Stepan in a follow-up answer.

    package io.github.mweirauch.micrometered.eval;
    
    import java.util.concurrent.TimeUnit;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Service;
    
    import io.micrometer.core.annotation.Timed;
    import io.micrometer.core.aop.TimedAspect;
    import io.micrometer.core.instrument.MeterRegistry;
    import io.micrometer.core.instrument.Timer;
    import io.micrometer.core.instrument.Timer.Sample;
    
    @Configuration
    @EnableAspectJAutoProxy
    public class TimingStuff {
    
        @Service
        static class MyService {
    
            @Autowired
            private MeterRegistry registry;
    
            public void helloManual() {
                // you can keep a ref to this; ok to call multiple times, though
                Timer timer = Timer.builder("myservice").tag("method", "manual").register(registry);
    
                // manually do the timing calculation
                long start = System.nanoTime();
                doSomething();
                timer.record(System.nanoTime() - start, TimeUnit.NANOSECONDS);
            }
    
            public void helloSupplier() {
                Timer timer = Timer.builder("myservice").tag("method", "supplier").register(registry);
    
                // execution of the method is timed internally
                timer.record(() -> doSomething());
            }
    
            public void helloSample() {
                Timer timer = Timer.builder("myservice").tag("method", "sample").register(registry);
    
                // records time taken between Sample creation and registering the
                // stop() with the given Timer
                Sample sample = Timer.start(registry);
                doSomething();
                sample.stop(timer);
            }
    
            // TimedAspect adds "class" and "method" tags
            @Timed(value = "myservice.aspect")
            public void helloAspect() {
                doSomething();
            }
    
            private void doSomething() {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    //
                }
            }
    
        }
    
        @Autowired
        private MyService myService;
    
        @Bean
        TimedAspect timedAspect(MeterRegistry registry) {
            return new TimedAspect(registry);
        }
    
        @Scheduled(fixedRate = 1000)
        public void postConstruct() {
            myService.helloManual();
            myService.helloSupplier();
            myService.helloSample();
            myService.helloAspect();
        }
    
    }
    

    In case you go for Prometheus, you'd end up with something like that:

    # HELP myservice_seconds  
    # TYPE myservice_seconds summary
    myservice_seconds_count{application="micrometered",method="manual",} 4.0
    myservice_seconds_sum{application="micrometered",method="manual",} 0.200378014
    myservice_seconds_max{application="micrometered",method="manual",} 0.050115291
    myservice_seconds_count{application="micrometered",method="supplier",} 4.0
    myservice_seconds_sum{application="micrometered",method="supplier",} 0.200393455
    myservice_seconds_max{application="micrometered",method="supplier",} 0.05011635
    myservice_seconds_count{application="micrometered",method="sample",} 4.0
    myservice_seconds_sum{application="micrometered",method="sample",} 0.200527005
    myservice_seconds_max{application="micrometered",method="sample",} 0.050250191
    # HELP myservice_aspect_seconds  
    # TYPE myservice_aspect_seconds summary
    myservice_aspect_seconds_count{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 4.0
    myservice_aspect_seconds_sum{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 0.201824272
    myservice_aspect_seconds_max{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 0.051014296
    

提交回复
热议问题