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