Metrics, Pour Mesurer Efficacement Les Performances : Intégration Avec JDBC, Logback Et Jersey
Présentation de Metrics
Je vous propose dans cette série de 4 articles, de vous présenter la librairie Metrics, initié par la société Yammer. Celle-ci permet de fournir des métriques au niveau applicatif et JVM.
Ce quatrième article, présente l’intégration de Metrics avec les drivers JDBC, logback et jersey.
avec les drivers JDBC
La librairie JDBCMetrics intégre JDBC avec Metrics. Cela permet :
d’avoir une vision globale de la charge de la base de données issue de votre application
d’avoir une vision précise du nombre et des performances des requêtes SQL pour chaque requête HTTP
Pour rajouter ce module à votre application, il faut rajouter la dépendance suivante à votre fichier maven pom.xml:
1
2
3
4
5
<dependency>
<groupId>com.soulgalore</groupId>
<artifactId>jdbcmetrics</artifactId>
<version>1.1</version>
</dependency>
La vision globale de la charge de la base de données induite par l’application est possible via la configuration du driver JDBC, soit via un Datasource (la librairie jouant le rôle de proxy), soit via le DriverManager.
Au passage DriverManager est une classe dépréciée, ayant un comportement incohérent au niveau du chargement du driver. Préférez donc le Datasource.
La vision précise de la charge au niveau base de données par requête HTTP, est permise de façon optionnelle via l’installation d’un servlet filter :
Metrics fournit une librairie d’intégration avec logback, pour remonter des informations concernant la fréquence des évenements logués suivant le niveau de log.
Pour intégrer Metrics et logback, il faut rajouter la dépendance suivante dans votre fichier pom.xml :
1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-logback</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
Voici le code à utiliser pour lier Metrics à logback.
1
2
3
4
5
6
7
final LoggerContext factory = (LoggerContext) LoggerFactory.getILoggerFactory();
final Logger root = factory.getLogger(Logger.ROOT_LOGGER_NAME);
final InstrumentedAppender metrics = new InstrumentedAppender(registry);
metrics.setContext(root.getLoggerContext());
metrics.start();
root.addAppender(metrics);
Une application concrète de cette intégration pourrait être une surveillance d’évenements logués en erreur ou warning, afin de réagir rapidement quand ceux-ci surviennent avec une fréquence importante.
Voici comment installer une mesure concernant les logs ayant le niveau error dans logback :
A noter qu’une intégation avec log4J existe aussi.
avec Jersey
Pour intégrer les mesures de Metrics avec les services REST exposés via Jersey et Spring, il est nécessaire d’intégrer le module suivant à votre fichier pom.xml :
1
2
3
4
5
<dependency>
<groupId>com.yammer.metrics</groupId>
<artifactId>metrics-jersey</artifactId>
<version>3.0.1</version>
</dependency>
Sérialisation du registre Metrics en JSON via jackson
Le module maven metrics-json, permet de sérialiser facilement les mesures au format JSON, via des modules Jackson dédiés.
l’ajout de la dépendance suivante dans votre pom.xml permet de les utiliser :
1
2
3
4
5
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-json</artifactId>
<version>3.0.1</version>
</dependency>
De plus, vous devez créer une ressource REST, qui va exposer la représentation JSON de votre registre Metrics comme dans l’exemple suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Path("/")
publicclassFooResource{
privatestaticfinal ObjectMapper mapper = new ObjectMapper().registerModules(
new com.codahale.metrics.json.MetricsModule(TimeUnit.SECONDS, TimeUnit.MILLISECONDS, false),new HealthCheckModule());
private MetricRegistry registry;
@Inject
publicFooResource(MetricRegistry registry){
this.registry = registry;
}
@Path("/metrics")
@GET
@Produces(MediaType.APPLICATION_JSON)
public String serializeMetricsRegistryInJSON()throws JsonProcessingException {
return mapper.writeValueAsString(registry);
}
}
Ainsi, cette ressource JAX-RS exposera sur l’url http://monhost:8080/metrics en GET une représentation JSON du registre Metrics.
Une exposition de ces métriques peut être utile, pour par exemple, une page de supervision habillant ces métriques avec du javascript.
conclusion
La librairie Metrics est très pratique. Son usage s’est largement répandu, ce qui se traduit par la présence de librairies tierces afin d’enrichir son usage. Les 4 articles de cette série vous ont permis j’espère, de vous familiariser avec cette librairie. J’ai mis en place cette solution chez un de mes clients, en envoyant les informations de Metrics vers un serveur Graphite, pour une historisation pérenne, et un travail à postériori sur les métriques techniques ou fonctionnelles remontées.
Afin de distinguer les métriques des différents environnements (poste de développement, recette, pre-production, production…), remontées vers le même serveur, j’ai mis en place un ServletContextListener qui configure au démarrage de l’application le reporter Graphite en fonction de variables positionnées au lancement du serveur. Les métriques seront donc présentes dans graphite dans des arborescences séparées, via un préfixe différent.