PR: Logging, tracing, monitoring - DIARRA NIANZOU TAPE#44
Open
EmmanuelNianzou wants to merge 2 commits into
Open
PR: Logging, tracing, monitoring - DIARRA NIANZOU TAPE#44EmmanuelNianzou wants to merge 2 commits into
EmmanuelNianzou wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR du Projet Doodle — Logging, Tracing, Monitoring & Observabilité
Équipe :
Table des matières
1. Contexte et objectifs
Dans le cadre du cours de DevOps de la deuxième année ingénieure à l'ESIR (Université de Rennes 1), nous avons eu à prendre un projet existant, une application de sondage de type Doodle, et à y intégrer une chaîne d'observabilité complète. Le dépôt de base a été cloné depuis https://github.com/selabs-ur1/doodle.git.
L'application Doodle permet de créer des sondages pour planifier des événements collectifs. Elle est composée d'une API REST Quarkus (Java), d'un frontend Angular et d'une base de données MySQL. Notre travail a consisté à ajouter autour de cette application tout le nécessaire pour observer son comportement en production, à savoir :
L'ensemble du déploiement est orchestré avec Docker Compose : une seule commande suffit pour lancer les 10 services qui composent le projet.
2. Choix technologiques et comparaison
Plusieurs solutions existent pour implémenter l'observabilité. Voici pourquoi nous avons retenu celles-ci plutôt que les alternatives.
2.1 Métriques : Prometheus + Micrometer vs Datadog vs SkyWalking
Nous avons choisi Prometheus (avec le client Micrometer côté Quarkus) pour collecter les métriques.
quarkus-micrometer-registry-prometheus)Pourquoi pas Datadog ? Datadog est un excellent outil en entreprise, mais il est payant et requiert d'envoyer les données vers des serveurs externes. Dans notre cas, vu que c'est un projet scolaire, et il est hébergé localement, cela n'allait pas nous être util. De plus, il crée une dépendance forte à un fournisseur.
Pourquoi pas SkyWalking ? SkyWalking est très complet (APM, métriques, logs, traces) mais sa mise en place est nettement plus complexe. Il utilise un agent Java qui modifie le bytecode à la volée, ce qui peut créer des incompatibilités. Il est davantage adapté à des environnements Kubernetes avec de nombreux microservices.
2.2 Logs : Loki + Promtail vs ELK Stack vs Fluentd
Nous avons retenu Loki (stockage de logs) + Promtail (collecteur de logs Docker).
Pourquoi pas ELK (Elasticsearch + Logstash + Kibana) ? L'ELK Stack est la référence pour la recherche dans les logs (full-text), mais Elasticsearch est extrêmement gourmand en ressources — il consomme facilement 2 à 4 Go de RAM sur un poste de développement. Pour notre projet, la recherche par labels (application, niveau de log) est suffisante. Loki est conçu pour fonctionner léger.
Pourquoi pas Fluentd ? Fluentd est un bon outil mais sa configuration est plus complexe que Promtail, et son intégration avec Grafana nécessite un plugin supplémentaire. Promtail est développé par la même équipe que Loki, la compatibilité est donc garantie.
2.3 Traces : Jaeger vs Zipkin vs OpenTelemetry
Nous avons utilisé Jaeger via le protocole OpenTracing (supporté nativement par Quarkus).
quarkus-smallrye-opentracing)all-in-one)Pourquoi pas Zipkin ? Zipkin est plus simple mais son interface est moins riche que Jaeger. Il ne supporte pas nativement le format Jaeger, ce qui aurait nécessité une conversion. Quarkus a un support intégré pour Jaeger via OpenTracing.
Une note sur OpenTracing vs OpenTelemetry : OpenTracing est le standard que nous utilisons ici car Quarkus 3.7.1 le supporte via
quarkus-smallrye-opentracing. OpenTelemetry (OTel) est le successeur et fusionne les standards OpenTracing et OpenCensus. Pour un nouveau projet, OTel serait le choix idéal, mais la migration depuis OpenTracing demande des ajustements que nous n'avons pas eu à faire ici.2.4 Visualisation : Grafana vs Kibana vs SkyWalking UI
Grafana est le tableau de bord central qui regroupe métriques (Prometheus), logs (Loki) et traces (Jaeger).
Pourquoi pas Kibana ? Kibana est lié à l'écosystème Elasticsearch. Il faudrait donc l'ELK Stack en plus, ce qui alourdit énormément le projet (voir section 2.2). Grafana peut se connecter à Prometheus ET Loki ET Jaeger simultanément en un seul outil.
2.5 Pourquoi pas Zuul ?
Zuul est une API Gateway développée par Netflix (intégrée à Spring Cloud). Son rôle est de router les requêtes entre plusieurs microservices, de gérer l'authentification et la limitation de débit. Dans notre architecture, nous n'avons qu'un seul service API (
doodle-api), donc une API Gateway est inutile. Zuul ne fait pas de l'observabilité — c'est un composant d'infrastructure pour les architectures microservices complexes.2.6 Pourquoi pas KuberHealthy ?
KuberHealthy est un framework de tests de santé spécifique à Kubernetes. Notre projet tourne sur Docker Compose, donc KuberHealthy est hors scope. En revanche, nous utilisons les health checks Docker (
/q/health) et les health checks Quarkus (SmallRye Health) qui remplissent ce rôle dans notre contexte.Résumé des choix
3. Prérequis
Avant de commencer, s'assurer que les outils suivants sont installés :
docker --versiondocker compose versionjava --versiongit --versioncurl --version4. Structure du projet
5. Démarrage rapide
Étape 1 — Cloner le dépôt
git clone https://github.com/selabs-ur1/doodle.git doodlestudent cd doodlestudentÉtape 2 — Lancer Docker Desktop
Sur Windows, on ouvre Docker Desktop depuis le menu Démarrer et attendre que l'icône passe au vert dans la barre des tâches.
Étape 3 — Construire et démarrer tous les services
Étape 4 — Vérifier que tout est démarré
Tous les services doivent afficher
running(healthypour la base de données), par exemple ce qu'on observait :Étape 5 — Vérifier que l'API répond
Réponse attendue :
{"status":"UP", ...}. Si l'API ne répond pas encore, attendre un instant puis réessayer.6. Accès aux interfaces
admin/doodle123Accéder au dashboard Grafana
admin/doodle123Le dashboard contient 7 panneaux :
http_server_requests_seconds_counthttp_server_requests_seconds_buckethttp_server_requests_seconds_countjvm_memory_used/max_bytesjvm_threads_live_threadshttp_server_requests...{uri=~"/api/polls.*"}{service="doodle-api"}Explorer les traces dans Jaeger
doodle-apiExplorer les métriques brutes dans Prometheus
http_server_requests_seconds_count7. Simulation de trafic
Pour générer du trafic réaliste et voir les panneaux Grafana s'animer, un script de test de charge est fourni.
Lancer le test
Ce que fait le script
Le script effectue 50 cycles d'opérations qui simulent un usage normal de l'API :
GET /api/pollsPOST /api/pollsGET /api/polls/{id}GET /q/healthGET /q/metricsGET /api/polls/99999Une pause de 0.5 s entre chaque cycle.
Observer dans Grafana pendant le test
/api/polls8. Comprendre le monitoring
8.1 Métriques — Prometheus scrape l'API
Quarkus expose automatiquement les métriques JVM, HTTP et système via Micrometer. L'histogramme HTTP est activé (
histogram: true) pour permettre le calcul du P95.8.2 Logs — Promtail → Loki
Promtail détecte automatiquement le container
doodle-apigrâce au label Dockerlogging=promtaildéfini dansdocker-compose.yml.8.3 Traces — Jaeger via OpenTracing
Chaque requête reçoit un
traceIdunique. Si une requête échoue ou est lente, Jaeger permet de voir exactement à quelle étape le problème s'est produit.9. Les problèmes que nous avons rencontrés et solutions
Docker Desktop non démarré
Erreur :
failed to connect to the docker API at npipe:////./pipe/dockerDesktopLinuxEngineSolution : On n'avait pas lancer Docker Desktop. Il faut lancer Docker Desktop depuis le menu Démarrer Windows et attendre que l'icône passe au vert.
Panneau "Latence P95" — No Data
Cause : L'histogramme HTTP n'était pas activé dans le container.
Solution : Vérifier dans
docker-compose.ymlla présence de :Puis reconstruire :
docker compose up --build -d apiPanneau "Logs en temps réel" — No Data
Cause 1 — Sur Linux/macOS : Promtail ne peut pas accéder au socket Docker.
Vérification :
Cause 2 — Sur Windows avec Git Bash : Le chemin
/var/run/docker.sockest converti par Git Bash en chemin Windows. Il faut Modifier le volume dansdocker-compose.yml:Vérifier que Loki reçoit les logs :
curl "http://localhost:3100/loki/api/v1/labels"Si
serviceapparaît dans la liste, les logs arrivent correctement.L'API ne démarre pas
Cause : MySQL n'est pas encore prêt.
Solution : Attendre quelques secondes puis :
Grafana n'affiche pas le dashboard
Cause : Le provisioning n'a pas fonctionné au premier démarrage.
Solution :
Attendre quelques secondes, puis recharger http://localhost:3000.
Erreur "port already in use"
Cause : Un service local utilisait déjà un port par exemple, MySQL local sur 3306.
Solution : Arrêter le service local, ou changer le port hôte dans
docker-compose.yml:Services Docker et leurs rôles
doodle-apidoodle-dbmysql:8.0doodle-frontdoodle-etherpadetherpad/etherpaddoodle-mailbytemark/smtpdoodle-prometheusprom/prometheus:v2.47.0doodle-lokigrafana/loki:2.9.0doodle-promtailgrafana/promtail:2.9.0doodle-jaegerjaegertracing/all-in-one:1.49doodle-grafanagrafana/grafana:10.1.010. Arrêt et nettoyage
Arrêter les services
Arrêter et supprimer toutes les données
Reconstruire l'API après modification du code source
Voir les logs d'un service en temps réel
Inspecter une métrique directement
Modifications apportées au dépôt original
Le dépôt cloné depuis https://github.com/selabs-ur1/doodle.git contenait uniquement l'application Doodle (API Quarkus + frontend Angular), sans aucun outillage d'observabilité. Voici l'ensemble des fichiers que nous avons ajoutés ou modifiés pour mettre en place la chaîne Logging + Tracing + Monitoring.
1.
api/src/main/resources/application.yml— Instrumentation de l'APIFichier modifié (existait dans le dépôt original, nous l'avons enrichi).
Le fichier de configuration Quarkus d'origine se limitait aux paramètres de base (datasource, Hibernate, mailer). Nous avons ajouté trois blocs de configuration qui transforment l'API en application observable :
Métriques (Micrometer + Prometheus) :
L'activation de l'histogramme HTTP (
histogram: true) est le point clé : sans lui, la métriquehttp_server_requests_seconds_bucketn'existe pas et le panneau Latence P95 de Grafana affiche "No data".Logs JSON structurés (pour Promtail/Loki) :
Quarkus écrit ses logs sur stdout. En activant le format JSON, chaque ligne de log devient un objet structuré que Promtail peut parser pour en extraire les champs
level,message,traceId.Tracing distribué (Jaeger via OpenTracing) :
Chaque requête HTTP reçoit un identifiant de trace unique (
traceId) visible dans Jaeger.2.
docker-compose.yml— Orchestration complèteFichier ajouté (n'existait pas dans le dépôt original, nous l'avons créé entièrement).
Le dépôt cloné ne contenait aucun
docker-compose.yml. Nous avons donc créé ce fichier de zéro en y intégrant à la fois les services applicatifs existants (api, front, db, etherpad, mail) et les cinq nouveaux services de monitoring.Services ajoutés :
prometheusprom/prometheus:v2.47.0lokigrafana/loki:2.9.0promtailgrafana/promtail:2.9.0jaegerjaegertracing/all-in-one:1.49grafanagrafana/grafana:10.1.0Modifications du service
api:Nous avons ajouté des variables d'environnement pour activer les métriques Agroal et l'histogramme HTTP, et deux labels Docker indispensables pour Promtail :
Sans ces labels, Promtail ignore le container
doodle-apiet le panneau Logs de Grafana reste vide.3.
monitoring/prometheus/prometheus.yml— Configuration du scrapeFichier ajouté (n'existait pas dans le dépôt original).
Ce fichier configure Prometheus pour qu'il collecte les métriques de l'API toutes les 10 secondes en interrogeant l'endpoint
/q/metricsexposé par Quarkus :Le label
job: doodle-apiest automatiquement ajouté par Prometheus et sert de filtre dans toutes les requêtes PromQL du dashboard Grafana.4.
monitoring/loki/loki-config.yml— Stockage des logsFichier ajouté (n'existait pas dans le dépôt original).
Configuration de Loki en mode single-node avec stockage sur le système de fichiers. Ce mode est adapté à un environnement de développement/démonstration. Le schéma de stockage
boltdb-shipperavecv11est le standard pour Loki 2.9.5.
monitoring/promtail/promtail-config.yml— Collecte des logs DockerFichier ajouté (n'existait pas dans le dépôt original).
Promtail est configuré pour utiliser la découverte automatique des containers Docker via le socket Docker (
/var/run/docker.sock). Il ne collecte que les containers ayant le labellogging=promtail, ce qui évite de remonter les logs de tous les containers (prometheus, grafana, etc.) dans Loki :6.
monitoring/grafana/provisioning/datasources/datasources.yml— Sources de données GrafanaFichier ajouté (n'existait pas dans le dépôt original).
Le provisioning Grafana permet de configurer les datasources automatiquement au démarrage, sans passer par l'interface graphique. Nous avons configuré les trois sources :
Les
uid(prometheus,loki,jaeger) sont référencés directement dans le fichier JSON du dashboard, ce qui garantit que les panneaux se connectent à la bonne datasource sans configuration manuelle.7.
monitoring/grafana/dashboards/doodle-api.json— Dashboard GrafanaFichier ajouté (n'existait pas dans le dépôt original).
Dashboard JSON défini en code, chargé automatiquement au démarrage de Grafana via le provisioning. Il contient 7 panneaux qui couvrent les quatre piliers de l'observabilité :
rate(http_server_requests_seconds_count[1m])histogram_quantile(0.95, ...)rate(...{status=~"4|5.."}[1m])jvm_memory_used_bytes{area="heap"}jvm_threads_live_threadsrate(...{uri=~"/api/polls.*"}[1m]){service="doodle-api"}(LogQL)8.
load-test.sh— Script de simulation de traficFichier ajouté (n'existait pas dans le dépôt original).
Script bash de test de charge effectuant 50 cycles de requêtes réalistes sur l'API. Il permet de générer du trafic visible dans Grafana et de valider que l'ensemble de la chaîne d'observabilité fonctionne de bout en bout.
Résumé des modifications
api/src/main/resources/application.ymldocker-compose.ymlmonitoring/prometheus/prometheus.ymlmonitoring/loki/loki-config.ymlmonitoring/promtail/promtail-config.ymlmonitoring/grafana/provisioning/datasources/datasources.ymlmonitoring/grafana/provisioning/dashboards/dashboards.ymlmonitoring/grafana/dashboards/doodle-api.jsonload-test.shREADME.mdAuteurs
Projet réalisé dans le cadre du cours de DevOps — ESIR 2 IOT
Année universitaire 2025–2026
Dépôt original : https://github.com/selabs-ur1/doodle.git