TP: Monitoring
Principe
- Instrumenter des applications
- Ajout de logs pour suivre l’exécution
- Ajout de métriques
- Contextualisation des logs
Dans ce TP, on travaillera sur les applications API et Worker du TP Déploiement Kubernetes. Il faudra pouvoir redéployer vos propres versions de ces applications, donc pousser vos propres images sur vos dépôts harbor.
Sondes dans les applications api et worker
Modifier le déploiement de l’application worker
afin d’y ajouter une sonde de liveness.
Note: le code de worker embarque déjà une route pour la sonde en question, il y donc uniquement à changer le déploiement.
Modifier l’application api
afin d’ajouter des routes pour deux sondes:
- une sonde de liveness qui indiquera que le serveur fonctionne
- une sonde de readiness qui vérifiera en plus que le service worker est vivant
Redéployer api
en y ajoutant les deux sondes et tester leur bon fonctionnement, par exemple en descendant à 0 le nombre de workers.
Logs dans les applications api et worker
Modifier api et worker afin d’ajouter des logs:
- sur les réceptions de requêtes
- sur la réussite ou l’échec des requêtes
- sur les actions des différents services
Ajouter également des logs de debug permettant de suivre les principaux appels de méthodes entre les composants au sein de chacune des applications.
Redéployer et vérifier que les logs sont bien visibles avec kubectl logs
.
Mesures au sein des applications
On souhaite à présent ajouter des mesures aux différents déploiements.
Déploiement de prometheus
Déployer un serveur prometheus. On pourra utiliser par exemple l’image bitnami/prometheus:2
(doc). Ci-dessous un fichier de configuration à placer dans une ConfigMap qui sera montée à l’emplacement /opt/bitnami/prometheus/conf/prometheus.yml
:
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: "prometheus"
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ["localhost:9090"]
Pour le moment ce fichier contient une configuration de récupération de métriques (dans scrape_configs
): prometheus lui-même.
Rediriger le port 9090 en local via kubectl port-forward
, puis accéder à la route /graph
de prometheus. Dans la zone de recherche, taper scrap
et sélectionner scrape_samples_scraped
parmi les suggestions. Basculer dans le tab Graph pour afficher une courbe sur une période de temps (par défaut 1h).
Instrumentation de PostgreSQL
PostgreSQL ne rend pas directement accessible ses métriques à Prometheus. On va passer par un conteneur annexe dédié à cette tâche. On utilisera pour ça le PostgreSQL Server Exporter.
Modifier le déploiement de postgresql de façon à ajouter un side container base sur le PostgreSQL Server Exporter. Comme les deux conteneurs (postgresql et l’exporteur) sont dans le même pod, l’adresse pour accéder à postgresql devrait être localhost
.
Modifier la configuration de prometheus pour récupérer les métriques ainsi exportées et vérifier que la récupération fonctionne (par exemple en regardant l’onglet status -> targets ou en affichant la métrique pg_stat
).
Métriques dans les applications Spring
Monitoring par défaut
Ajouter les dépendances suivantes au projets Spring:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.8.2</version>
</dependency>
Ajouter également les entrées suivantes dans application.properties
:
# Monitoring, see https://dzone.com/articles/monitoring-and-profiling-spring-boot-application
# Enable prometheus exporter
management.metrics.export.prometheus.enabled=true
# Enable prometheus end point
management.endpoints.web.exposure.include=prometheus
# enable percentile-based histogram for http requests
management.metrics.distribution.percentiles-histogram.http.server.requests=true
# http SLA histogram buckets
management.metrics.distribution.sla.http.server.requests=100ms,150ms,250ms,500ms,1s
# enable JVM metrics
management.metrics.enable.jvm=true
Repackager l’application, la lancer en local vérifier qu’elle répond bien sur la route /actuator
et que le point d’accès pour prometheus fourni bien des métriques. Noter le chemin de récupération des métriques prometheus, puis arrêter le serveur.
Redéployer les applications dans kubernetes.
Ajouter une configuration de scraping pour ces applications dans la configuration de prometheus. Au même niveau que le job_name
, ajouter une entrée metrics_path
avec comme valeur le chemin noté précédement.
Une fois la configuration mise en place, vérifier que les métriques sont disponibles (e.g. jvm_memory_used_bytes
).
Monitoring spécifique
En s’inspirant de la section Custom Metrics du tutoriel Monitoring and Profiling Your Spring Boot Application, ajouter un gauge pour mesurer le nombre d’appels à la route de chiffrement d’api
et un compteur pour compter le nombre total de clés. Redéployer, puis vérifier la présence des mesures dans Prometheus.
Utiliser ensuite l’annotation @io.micrometer.core.annotation.Timed
sur une des méthodes du contrôleur EncryptController
et effectuer une requête, puis vérifier la présence de la mesure. Quelles mesures supplémentaires on été créées? Remarque: Timed
prend plusieurs arguments optionels dont le nom de la mesure. Spécifier des tags supplémentaires via extraTags
(le tableau de String
s contient une clé puis sa valeur, puis une autre clé, puis la valeur de la deuxième clé, etc). Déployer et vérifier la présence des tags dans la mesure.
Remarque: Les mesures produites par @Timed
permettent également de récupérer le nombre d’appels aux méthodes annotées.
Logs contextualisés et suivi de requête
En suivant les explications sur les MDC, ajouter un contexte aux logs de l’api associant à chaque requête un identifiant unique. Modifier l’appel à worker afin d’y ajouter un header contenant également cet identifiant.
Du côté de worker, récupérer le contenu du header puis l’injecter comme contexte dans les logs de worker.
Redéployer et vérifier que vous pouvez tracer à travers les logs les appels liés à une requête dans API jusque dans worker.