Paramètres Codahale: utiliser l'annotation @Timed metrics en Java simple

j'essaie d'ajouter des paramètres à une application Java simple en utilisant des paramètres codahale. J'aimerais utiliser l'annotation @Timed, mais je ne sais pas quel MetricRegistry il utilise, ou comment lui dire quel MetricRegistry utiliser. L'application est une application Java 8 simple, construit avec Maven 3, Pas de ressort, pas D'hibernation.

Je ne trouve aucune documentation sur la façon d'implémenter @Timed dans la documentation dropwizard: https://dropwizard.github.io/metrics/3.1.0/manual/

j'ai ajouté ces dépendances:

<dependency>
  <groupId>io.dropwizard.metrics</groupId>
  <artifactId>metrics-core</artifactId>
  <version>3.1.0</version>
</dependency>
<dependency>
  <groupId>com.codahale.metrics</groupId>
  <artifactId>metrics-annotation</artifactId>
  <version>3.0.2</version>
</dependency>

quand j'utilise un appel programmatique à Timer, je peux obtenir des rapports parce que je sais quel MetricsRegistry est utilisé:

static final MetricRegistry metrics = new MetricRegistry();
private void update() throws SQLException {
  Timer.Context time = metrics.timer("domainobject.update").time();
  try {
    [...]
  } finally {
    time.stop();
  }
}

mais quand j'utilise l'annotation beaucoup plus élégante @Timed, Je n'ai aucune idée de quel registre est utilisé, et donc je ne peux pas créer un reporter, ce qui signifie que je ne peux pas obtenir les mesures rapportées (Je ne suis même pas sûr si cela fait quoi que ce soit):

@Timed(name = "domainobject.update")
private void update() throws SQLException {
    [...]
}

veuillez indiquer comment faire fonctionner les annotations @Timed et autres paramètres dans une application Java régulière.

informations Supplémentaires: la raison pour laquelle je trouve cela étrange est que j'ai ajouté le framework Lombok et les annotations @Slf4j fonctionnent. J'ai ajouté Lombok comme dépendance dans le maven pom.xml:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.14.8</version>
</dependency>

et je peux utiliser l'annotation de classe @Sl4fj pour ajouter un logger à la classe sans encombrer le membre variables:

@Slf4j
public class App {
  public void logsome(){
    log.info("Hello there");
  }
}

donc si c'est possible en ajoutant simplement une dépendance, je pense que je manque juste une dépendance ou une configuration pour obtenir le travail d'annotation codahale @Timed, comme décrit ci-dessus.

(au passage, admirez Lombok, il rendra votre vie plus facile: http://projectlombok.org/ )

33
demandé sur Rolf 2015-02-13 15:26:37

8 réponses

pour faire court, vous ne pouvez pas utiliser @Timed sans une sorte de AOP (que ce soit AOP de printemps ou AspectJ).

il y a une semaine ou deux, j'ai également décidé d'ajouter des mesures à notre projet et j'ai choisi AspectJ pour cette tâche (principalement parce que je l'ai utilisé dans le passé dans un but similaire et parce qu'il permet de tisser le temps de compilation alors que le printemps ne permet que l'exécution via proxies).

Vous devriez être en mesure de trouver toutes les informations et instructions nécessaires ici: https://github.com/astefanutti/metrics-aspectj.

pour ce qui est de Lombok, je suppose qu'ils utilisent un processeur d'annotations javac intégré:

un autre point de discorde est l'implémentation du code supportant L'intégration IDE ainsi que le processeur d'annotation javac. Ces deux pièces du projet Lombok utilisent des API non publiques pour accomplir leur sorcellerie. Cela signifie qu'il y a un risque que le projet Lombok ne soit pas Sorties IDE ou JDK.

13
répondu Andrew Logvinov 2015-02-14 11:35:48

en utilisant @Timed ne nécessite pas réellement l'utilisation d'AOP, comme cela a déjà été affirmé dans la réponse la mieux cotée, si vous êtes à l'intérieur d'un conteneur et en utilisant l'une des bibliothèques d'instrumentation de Dropwizard. Voir le Jersey 2.x module par exemple, que vous pouvez voir utilise la réflexion (comme le font les autres, j'ai regardé), si vous lisez le source.

Vous pouvez lire sur tous ces modules dans le Dropwizard docs sous le" Instrumentation ____" les balles.

je comprends que L'OP ne fonctionnait pas explicitement dans un tel container, mais je voulais offrir cette information, car beaucoup d'entre nous recherchant cette réponse peuvent travailler sur un service web moderne qui peut enregistrer de telles ressources dans son environnement runtime.

10
répondu Michael Zalimeni 2016-08-23 16:05:50

utilisez le MetricRegistry intégré accédé à partir du paramètre bootstrap dans la méthode initialize de votre classe d'application.

@Override
public void initialize(final Bootstrap<Configuration> bootstrap) {
    final JmxReporter reporter = JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build();
    reporter.start();
}
5
répondu joev 2015-08-04 19:21:31

comme l'autre réponse l'indique, vous devez avoir quelque chose dans l'application pour écouter vos classes instanciées et les vérifier pour l'annotation @Timed.

Si vous êtes à l'aide de Guice, vous pouvez utiliser: https://github.com/palominolabs/metrics-guice

3
répondu woxwoxwoxwox 2015-03-08 01:27:49

AOP est exagéré et ne convient pas à l'utilisation de @timed, en général parler.

le registre de mesures par défaut écrit @timed metrics à un Concordenthashmap et ne fixe aucun auditeur significatif.

DropWizard Bootstrap constructor:

/**
 * Creates a new {@link Bootstrap} for the given application.
 * @param application a Dropwizard {@link Application}
 */
public Bootstrap(Application<T> application) {
    this.application = application;
    this.objectMapper = Jackson.newObjectMapper();
    this.bundles = Lists.newArrayList();
    this.configuredBundles = Lists.newArrayList();
    this.commands = Lists.newArrayList();
    this.validatorFactory = Validators.newValidatorFactory();


    // returns new ConcurrentHashMap<String, Metric>(); 
    this.metricRegistry = new MetricRegistry(); 


    this.configurationSourceProvider = new FileConfigurationSourceProvider();
    this.classLoader = Thread.currentThread().getContextClassLoader();
    this.configurationFactoryFactory = new DefaultConfigurationFactoryFactory<T>();
}

vous devez donc construire/démarrer/enregistrer le registre métrique approprié dans afin de voir les résultats.

ici j'utilise JMX:

@Override
public void initialize(Bootstrap<PayloadStorageConfiguration> bootstrap) {
    JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build().start();
}

C'est tout ce que vous devez faire.

voici un exemple de sortie (exécutez jconsole contre votre application/serveur Java pour voir les résultats JMX):

enter image description here

3
répondu Robert Christian 2016-03-22 23:14:51

Vous pouvez également utiliser stagemonitor-core. Voir la documentation ici et ici. L'avantage est que stagemonitor (qui est libre et open source btw) ne dépend pas d'AOP basé sur un conteneur comme ressort AOP ou EJB intercepteurs. Il utilise la manipulation de bytecode via la pièce jointe runtime ce qui signifie que vous n'avez même pas à ajouter un -javaagent indicateur de démarrage de votre application - une simple dépendance suffit.

Si vous voulez mesurer l'exécution temps dans une application web ou dans une application EJB distante, vous n'avez même pas à annoter manuellement votre code. Stagemonitor propose également des tableaux de bord Grafana et Kibana préconfigurés.

Disclaimer: je suis un des développeurs de stagemonitor

0
répondu Felix 2016-05-19 09:33:16

dans les versions Dropwizard plus récentes (j'utilise 0.9.2), vous pouvez accéder à la valeur par défaut MetricRegistry par le biais de la configuration de l'environnement io.dropwizard.setup.Environment. Cette valeur par défaut MetricRegistry a déjà un InstrumentedResourceMethodApplicationListener associé à elle, qui écoute toutes les mesures de vos ressources.

Si vous avez enregistré une ressource avec le JerseyEnvironment comme dans,

environment.jersey().register(resource);

vous n'avez qu'à annoter votre méthode ressource (ou classe) avec @Timed,@Metered ou @ExceptionMetered pour enregistrer les métrique.

@POST
@Timed
public String show() {
    return "yay";
}

vous pouvez assigner un Reporter (par exemple Slf4jReporter ou JmxReporter) à la valeur par défaut MetricRegistry

Slf4jReporter.forRegistry(environment.metrics()).build();

comme un test rapide pour voir si vos paramètres ont été enregistrés, vous pouvez faire un GET appel à l'URL http://localhost:8081/metrics ou L'URL de mesure D'administrateur correspondante dans votre environnement de test.

certaines autres versions vous demandent d'enregistrer explicitement un InstrumentedResourceMethodApplicationListener comme le montre dans ce Doc

0
répondu Faraz 2017-07-07 15:38:13

cette simple/droit-de-la-exemple de point d'https://karollotkowski.wordpress.com/2015/10/19/api-endpoint-in-one-minute-with-dropwizard/ a juste montré qu'il suffit de disposer de l'annotation

enter image description here

0
répondu gli00001 2018-04-16 20:01:24