web-dev-qa-db-fra.com

Comment mesurer les méthodes d'entretien à l'aide de la botte à ressort 2 et du micromètre

J'ai commencé mon premier projet sur Spring Boot 2 (RC1). Grâce à la documentation déjà bonne, cela n'a pas été trop difficile à faire avec Spring Boot 1.x.

Cependant, maintenant que je veux intégrer des mesures, je stumbeling. Pour autant que j'ai pu trouver actuellement, il n'y a que de la documentation pour les métriques livrées par défaut. Mais je voudrais également mesurer le temps d'exécution du niveau de service ainsi que le temps utilisé dans dynamodb.

[~ # ~] modifier [~ # ~] Je recherche une solution en utilisant Micrometer, la bibliothèque utilisée dans la nouvelle bibliothèque d'actionneurs livrée avec ressort -boot 2.

Existe-t-il un guide sur la manière de procéder? De this J'ai lu qu'il n'y a pas encore de solution basée sur des annotations faciles pour les haricots de printemps arbitraires. Pourrait s.o. donnez-moi un exemple/un lien vers la documentation sur la façon dont une méthode comme ci-dessous pourrait être mesurée?

@Service
@Timed
public class MyService {
    public void doSomething() {
        ...;
    }
}
13
Christian Frommeyer

Voici un petit échantillon qui devrait vous permettre de continuer. Il existe d'autres variantes de Timer.record() qui ne sont pas présentées ici. (Aussi: l'injection de champ n'est utilisée que par souci de concision.) Vous n'avez pas besoin de mettre le nom des méthodes appelées dans une balise. Vous pouvez également l'intégrer au nom de la métrique elle-même. Je voulais juste montrer ce que tu pouvais faire.

Mise à jour 2018-03-12: À partir du Micrometer 1.0.0 a TimedAspect a été introduit afin que vous puissiez également utiliser le @Timed annotation. Pour l'instant, vous devez enregistrer vous-même le Bean. (Vous devez cependant être prudent lorsque vous avez personnalisé @Timed annotations sur vos ressources Spring-MVC ou Jersey.) Ceci a déjà été mentionné par Michal Stepan dans un suivi réponse .

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();
    }

}

Si vous optez pour Prometheus, vous vous retrouveriez avec quelque chose comme ça:

# 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
12
mweirauch

@io.micrometer.core.annotation.Timed l'annotation semble être hors service pour les appels personnalisés en raison de la réduction de la portée, elle est mentionnée dans le lien dans votre question .

Vous devez configurer manuellement un aspect:

@Configuration
@EnableAspectJAutoProxy
public class AutoTimingConfiguration {
    @Bean
    public TimedAspect timedAspect(MeterRegistry registry) {
        return new TimedAspect(registry);
        }
}

Cette méthode comme celle-ci:

@Timed("GET_CARS")
public List<Car> getCars(){
        return Lists.newArrayList();
}

aura pour résultat GET_CARS métrique dans /actuator/metrics (par défaut) endpoint.

18
Michal Stepan