Skip to content

[Issue #11] Monitoring: Prometheus + Grafana + Loki on Doodle project#41

Open
yassminechiha-bot wants to merge 1 commit into
templep:mainfrom
yassminechiha-bot:issue-11-Rendu6devops
Open

[Issue #11] Monitoring: Prometheus + Grafana + Loki on Doodle project#41
yassminechiha-bot wants to merge 1 commit into
templep:mainfrom
yassminechiha-bot:issue-11-Rendu6devops

Conversation

@yassminechiha-bot
Copy link
Copy Markdown

Issue #11 — Cloud-native applications and microservice architecture

Présentation du groupe

Cours : DevOps — ESIR2 S8
Sujet : Issue #11 — Cloud-native applications and microservice architecture
Référence : mfornos/awesome-microservices
Repo du projet : yassminechiha-bot/DoodleProjetDevops

Groupe : Yassmine CHIHA, Mariem Zeineb DHOUIB, Aymen SAHOURI et Ouiam ZEROUAL


Ce que nous avons mis en place

1. GitHub Actions — Pipeline CI/CD

Fichier : .github/workflows/ci.yml

Nous avons créé un pipeline CI/CD qui s'exécute automatiquement à chaque push ou pull request sur main/master. Il enchaîne les étapes suivantes :

  1. Checkout du code
  2. Installation de Java 17 (Temurin)
  3. Build Maven avec ./mvnw clean package -DskipTests
  4. Build + démarrage de Docker Compose
  5. Vérification de l'état des services
  6. Teardown propre
name: CI Pipeline - Doodle Quarkus
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Build with Maven
        run: ./mvnw clean package -DskipTests
        working-directory: ./api
      - name: Build Docker Compose
        run: docker compose -f api/docker-compose.yaml up -d --build
      - name: Check services
        run: docker compose -f api/docker-compose.yaml ps
      - name: Teardown
        run: docker compose -f api/docker-compose.yaml down

Pipeline opérationnel et passant au vert sur GitHub Actions.

Capture 1 — Pipeline GitHub Actions

01-github-actions

On observe ici l'exécution du pipeline CI/CD sur GitHub Actions.
Un premier run échoue à cause d'une erreur de configuration (docker-compose mal nommé), puis une correction est appliquée.
Le second run passe avec succès, ce qui valide le bon fonctionnement du pipeline : build Maven, lancement des services Docker et vérification.


2. Docker Compose — Ajout des services manquants

Fichier : api/docker-compose.yaml

Le docker-compose existant contenait uniquement db, etherpad et mail. Nous avons ajouté :

  • Le service frontend (Angular) pour lancer l'interface utilisateur
  • Les services d'observabilité : Prometheus, Grafana, Loki, Promtail

Nous avons également mis à jour application.yml pour pointer les URLs vers les bons services locaux :

doodle:
  internalPadUrl: "http://localhost:9001/"
  externalPadUrl: "http://localhost:9001/"
quarkus:
  mailer:
    host: localhost
    port: 2525
  smallrye-metrics:
    path: /q/metrics

Le backend Quarkus est lancé sur la machine hôte avec ./mvnw quarkus:dev et expose ses métriques sur http://localhost:8080/q/metrics.

Capture 2 — docker compose : services en cours d'exécution

02-docker

Cette capture montre les conteneurs Docker en cours d'exécution.
Tous les services sont démarrés correctement : MySQL, Etherpad, SMTP, frontend Angular, ainsi que les outils d'observabilité (Prometheus, Grafana, Loki, Promtail).
L'environnement applicatif est donc entièrement opérationnel.


3. Prometheus — Collecte de métriques

Fichier : api/prometheus.yml

Référencé dans mfornos/awesome-microservices → section Monitoring & Debugging.

Prometheus scrape toutes les 10 secondes l'endpoint /q/metrics de Quarkus via host.docker.internal.

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'quarkus'
    static_configs:
      - targets: ['host.docker.internal:8080']
    metrics_path: '/q/metrics'
    scrape_interval: 10s

  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

Les métriques exposées par Quarkus sont au format MicroProfile :

  • base_memory_committedHeap_bytes
  • base_cpu_processCpuLoad_percent
  • base_jvm_uptime_seconds
  • base_gc_total

Capture 3 — Prometheus : état des targets

03-prometheus

On observe ici les targets configurés dans Prometheus.
Les deux services (Prometheus lui-même et l'application Quarkus) sont en état UP.
Cela confirme que Prometheus collecte correctement les métriques via l'endpoint /q/metrics.


4. Grafana — Visualisation des métriques

Fichier : api/grafana/provisioning/datasources/datasources.yaml

Référencé dans mfornos/awesome-microservices → section Monitoring & Debugging.

Grafana est configuré avec provisioning automatique : les datasources Prometheus et Loki sont déclarées via des fichiers YAML versionnés dans Git, sans configuration manuelle.

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    isDefault: true
  - name: Loki
    type: loki
    url: http://loki:3100

Capture 4 — Grafana : sources de données

04-grafana-datasources

Cette capture montre que Grafana est correctement configuré avec deux sources de données : Prometheus pour les métriques et Loki pour les logs.
Ces sources sont automatiquement provisionnées via des fichiers YAML versionnés dans le projet.
Cela permet d'éviter toute configuration manuelle et garantit la reproductibilité.

Capture 5 — Grafana Explore : mémoire JVM

05-memory

On observe ici la métrique base_memory_committedHeap_bytes, qui représente la mémoire heap utilisée par la JVM.
Le graphique permet de suivre l'évolution de la consommation mémoire dans le temps.
Cela est utile pour détecter d'éventuelles fuites mémoire ou une surcharge.

Capture 5 bis — Grafana Explore : utilisation CPU

06-cpu

Cette capture montre la métrique base_cpu_processCpuLoad_percent, qui représente la charge CPU du processus Quarkus.
On peut observer les variations de charge et identifier d'éventuels pics liés à certaines requêtes.

Capture 5 ter — Grafana Explore : uptime JVM

07-uptime Cette capture montre la métrique `base_jvm_uptime_seconds`, qui représente le temps de fonctionnement de l'application depuis son démarrage. Cela permet de vérifier la stabilité du service et de détecter d'éventuels redémarrages.

5. Loki + Promtail — Centralisation des logs

Fichiers : api/loki-config.yaml, api/promtail-config.yaml

Référencé dans mfornos/awesome-microservices → section Logging : "Like Prometheus, but for logs."

Loki stocke les logs de tous les conteneurs Docker. Promtail est l'agent qui les collecte et les envoie à Loki. Les logs sont consultables directement dans Grafana via {job="docker-logs"}.

Capture 6 — Grafana Explore Loki : logs globaux

08-logs On observe ici les logs collectés par Loki via Promtail. La requête `{job="docker-logs"}` permet de récupérer les logs de tous les conteneurs Docker. Cela fournit une vue centralisée de l'activité de l'ensemble des services.

Capture 6 bis — Grafana Explore Loki : détail des logs

09-logs-details Cette vue détaillée montre les messages de logs avec leur niveau (INFO, etc.), les timestamps et les informations internes des services. Cela permet d'analyser précisément le comportement de l'application et facilite le debugging.

Analyse des métriques après utilisation de l'application

Afin de générer des métriques exploitables, nous avons simulé une activité utilisateur via le frontend (création de plusieurs sondages, ajout de participants, interactions et commentaires).

Cette activité permet d’observer le comportement réel de l’application à travers les métriques et les logs.


Charge CPU

Capture — Grafana : utilisation CPU

processuscpuapresutilisationdeapp

On observe ici la métrique base_cpu_processCpuLoad_percent.

Après une phase initiale sans activité, des pics apparaissent suite aux interactions réalisées sur l’application (création de sondages, ajout de participants, commentaires).

Ces variations confirment que le système de monitoring capte correctement l’activité réelle de l’application.


Mémoire JVM

Capture — Grafana : mémoire JVM

basememoryapresutilisationdeapp

On observe ici la métrique base_memory_committedHeap_bytes, représentant la mémoire heap utilisée par la JVM.

La mémoire reste globalement stable, avec de légères variations liées à l’activité de l’application. Ce comportement est normal, la JVM allouant une quantité de mémoire relativement constante tout en ajustant dynamiquement son utilisation.


Uptime de l'application

Capture — Grafana : uptime JVM

uptimeapresutilisation

Cette capture montre la métrique base_jvm_uptime_seconds, qui représente le temps de fonctionnement de l’application depuis son démarrage.

Son évolution linéaire confirme que l’application reste stable et qu’aucun redémarrage n’a eu lieu pendant la période observée.


Analyse des logs

Capture — Grafana Loki : volume des logs

logsapresutilisation1

On observe ici une augmentation du volume de logs lors de l’utilisation de l’application.

Les pics correspondent aux interactions effectuées via le frontend, ce qui montre que les événements applicatifs sont bien enregistrés.


Capture — Grafana Loki : logs détaillés

logsapresutilisation2

Les logs détaillés contiennent des informations telles que les timestamps, les niveaux de log (INFO) et les messages internes des services.

Ils permettent de suivre précisément l’activité du système et facilitent le debugging.


Corrélation métriques / logs

On observe une corrélation entre les pics de logs et les variations de la charge CPU.

Cela confirme la cohérence du système d’observabilité mis en place : les actions utilisateur génèrent à la fois des logs et une augmentation de la charge système.


Conclusion sur l'observabilité

Ces différentes métriques (CPU, mémoire, uptime) combinées aux logs permettent d’avoir une vision complète du comportement de l’application.

L’utilisation conjointe de Prometheus, Grafana et Loki permet :

  • de surveiller les performances
  • d’analyser les événements applicatifs
  • de faciliter le debugging

Le système d’observabilité mis en place est donc pleinement fonctionnel et adapté à une architecture cloud-native.

Architecture finale

Machine hôte
│
├── Quarkus :8080 (./mvnw quarkus:dev)
│        │
│        └── /q/metrics ─────────────────────┐
│                                             │
└── Docker Compose                            │
        │                                     │
        ├── MySQL :3307                       │
        ├── Etherpad :9001                    │
        ├── SMTP :2525                        │
        ├── Angular :4200                     │
        │                                     │
        ├── Prometheus :9090 ◄────────────────┘
        │        │
        ├── Grafana :3000 ◄── Loki :3100 ◄── Promtail
        │                                (logs Docker)
        └── GitHub Actions CI/CD
            (push → build Maven → docker compose → check)

Étapes de lancement

# 1. Cloner le projet
git clone https://github.com/yassminechiha-bot/DoodleProjetDevops.git
cd DoodleProjetDevops

# 2. Démarrer tous les services Docker
docker compose -f api/docker-compose.yaml up -d

# 3. Lancer le backend Quarkus
cd api
./mvnw quarkus:dev
Service URL
Frontend Doodle http://localhost:4200
Métriques Quarkus http://localhost:8080/q/metrics
Prometheus http://localhost:9090
Grafana http://localhost:3000
Etherpad http://localhost:9001

Difficultés rencontrées

host.docker.internal sous WSL2

Sous Linux/WSL2, Docker ne résout pas automatiquement host.docker.internal. Sans ça, Prometheus ne peut pas joindre Quarkus sur l'hôte.

Solution :

extra_hosts:
  - "host.docker.internal:host-gateway"

Format MicroProfile des métriques

Quarkus expose les métriques au format MicroProfile et non Prometheus standard. Les métriques sont préfixées par base_ :

  • process_cpu_usage → n'existe pas
  • base_cpu_processCpuLoad_percent → format réel

Fichiers de config créés comme dossiers (WSL2)

Docker Compose sous WSL2 crée parfois les fichiers montés en volume comme des dossiers s'ils n'existent pas. Cela a bloqué le démarrage de Loki et Promtail.

Solution : supprimer le dossier et recréer le fichier manuellement avant de relancer le conteneur.


Fichiers ajoutés/modifiés

api/
├── docker-compose.yaml           ← modifié : + frontend, prometheus, grafana, loki, promtail
├── prometheus.yml                ← ajouté
├── loki-config.yaml              ← ajouté
├── promtail-config.yaml          ← ajouté
├── grafana/
│   └── provisioning/
│       └── datasources/
│           └── datasources.yaml  ← ajouté
└── src/main/resources/
    └── application.yml           ← modifié : URLs localhost

.github/
└── workflows/
    └── ci.yml                    ← ajouté

docs/
└── screenshots/                  ← captures d'écran
    ├── 01-github-actions-success.png
    ├── 02-docker-compose-ps.png
    ├── 03-prometheus-targets-up.png
    ├── 04-grafana-datasources.png
    ├── 05-grafana-metrics-quarkus.png
    └── 06-grafana-loki-logs.png

L'ensemble des captures démontre que l'architecture mise en place offre une observabilité complète du système, en combinant métriques et logs dans un environnement cloud-native, tout en intégrant une chaîne d’intégration continue automatisée via GitHub Actions.

Cette architecture met en œuvre les principes fondamentaux du cloud-native :

  • découplage des services (approche microservices)
  • conteneurisation avec Docker
  • observabilité complète (métriques et logs)
  • automatisation des processus via CI/CD

Elle permet ainsi de faciliter le déploiement, la supervision et le debugging d'une application distribuée.

Conclusion

Nous avons mis en place une architecture cloud-native complète intégrant les pratiques DevOps essentielles : intégration continue, conteneurisation et observabilité.

Grâce à l’utilisation conjointe de Prometheus, Grafana et Loki, nous sommes en mesure de superviser l’application en temps réel, tant au niveau des performances que des logs applicatifs.

L’analyse des métriques et des logs après utilisation réelle de l’application confirme la pertinence de cette architecture et démontre l’efficacité des outils mis en place.

Ce projet illustre concrètement les bonnes pratiques DevOps modernes pour le déploiement, le monitoring et la gestion d’une architecture distribuée basée sur des microservices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant