ITSkillsCenter
Développement Web

Monitoring applicatif : observabilité moderne

11 min de lecture
Monitoring applicatif : observabilité moderne

Ce que vous saurez faire à la fin

  1. Distinguer les 3 guide général de l’observabilité (logs, metrics, traces) et choisir la stack adaptée à votre PME entre Datadog, Grafana et la stack open-source Loki/Prometheus/Tempo.
  2. Instrumenter une application Node.js, Python ou PHP avec OpenTelemetry pour collecter automatiquement traces, métriques et logs structurés.
  3. Configurer des alertes intelligentes vers Slack et PagerDuty qui ne réveillent l’astreinte qu’en cas de vraie urgence client.
  4. Définir des SLI et SLO mesurables pour chaque service critique, et calculer un error budget pour arbitrer features vs fiabilité.
  5. Appliquer la méthode RED (Rate, Errors, Duration) pour diagnostiquer en 3 minutes pourquoi votre site e-commerce sénégalais ralentit.

Durée : 4h. Pré-requis : Linux/Mac, Docker installé, application web existante, compte gratuit Grafana Cloud (10k séries) ou Datadog (essai 14 jours), budget 0 à 30 000 FCFA/mois selon la stack.

Étape 1 — Comprendre les 3 guide général de l’observabilité

Le monitoring traditionnel répondait à « le service est-il en ligne ? ». L’observabilité moderne répond à « pourquoi tel utilisateur à Saint-Louis subit 8 secondes de latence sur le checkout ? ». La nuance est énorme : on passe de surveillance binaire à diagnostic contextuel.

Logs : événements horodatés détaillés, parfaits pour comprendre le contexte d’une erreur. Metrics : valeurs numériques agrégées dans le temps (CPU, requêtes/seconde, latence p99), idéales pour les dashboards et alertes. Traces : suivi d’une requête à travers tous les microservices, indispensable pour debug en architecture distribuée. Une PME avec 5 services backend a besoin des 3.

Étape 2 — Choisir entre stack managée et auto-hébergée

Solution Coût mensuel Setup Maintenance Quand choisir
Datadog 15 USD/host puis variable 30 minutes Aucune Equipe sans ops dédié
New Relic 0 jusqu’à 100 Go/mois 30 minutes Aucune Petits volumes, gratuit généreux
Grafana Cloud Free 0 (10k metrics, 50 Go logs) 1 heure Faible PME < 500 req/s
Self-hosted LGTM VPS 4 EUR/mois 4 heures 2h/mois Souveraineté données
Honeycomb 0 jusqu’à 20M events 1 heure Aucune Focus sur traces
SigNoz self-hosted VPS 4 EUR/mois 2 heures 1h/mois Alternative Datadog gratuite

Étape 3 — Installer la stack LGTM avec Docker Compose

version: "3.9"

services:
  prometheus:
    image: prom/prometheus:v2.54.0
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prom_data:/prometheus
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.retention.time=30d"
    ports:
      - "9090:9090"

  loki:
    image: grafana/loki:3.1.0
    ports:
      - "3100:3100"
    volumes:
      - loki_data:/loki

  tempo:
    image: grafana/tempo:2.5.0
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
      - tempo_data:/var/tempo
    ports:
      - "3200:3200"
      - "4317:4317"
      - "4318:4318"

  grafana:
    image: grafana/grafana:11.1.4
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ChangeMe2026!
    volumes:
      - grafana_data:/var/lib/grafana
      - ./datasources:/etc/grafana/provisioning/datasources

volumes:
  prom_data:
  loki_data:
  tempo_data:
  grafana_data:

Lancez avec docker compose up -d. En 4 minutes, vous avez une stack complète d’observabilité sur votre VPS Hetzner à 4 EUR/mois. L’interface Grafana est accessible sur localhost:3000.

Étape 4 — Configurer Prometheus pour scraper vos services

global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

rule_files:
  - "/etc/prometheus/rules/*.yml"

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node-exporter"
    static_configs:
      - targets: ["node-exporter:9100"]

  - job_name: "api-pme"
    metrics_path: /metrics
    static_configs:
      - targets: ["api.pme-dakar.sn:8080"]

  - job_name: "blackbox-http"
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
          - https://pme-dakar.sn
          - https://api.pme-dakar.sn/health
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

Le job blackbox-http vérifie toutes les 15 secondes que vos endpoints publics répondent. Si une URL prend plus de 5 secondes ou retourne une 5xx, l’alerte se déclenche.

Étape 5 — Instrumenter une application Node.js avec OpenTelemetry

npm install --save \
  @opentelemetry/api \
  @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http \
  @opentelemetry/exporter-metrics-otlp-http \
  @opentelemetry/exporter-logs-otlp-http
# Créer instrumentation.js à la racine :
# const { NodeSDK } = require('@opentelemetry/sdk-node');
# const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
# const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
#
# const sdk = new NodeSDK({
#   serviceName: 'api-pme-dakar',
#   traceExporter: new OTLPTraceExporter({ url: 'http://tempo:4318/v1/traces' }),
#   instrumentations: [getNodeAutoInstrumentations()]
# });
# sdk.start();

# Lancer l'app avec :
node --require ./instrumentation.js server.js

Avec ces 15 lignes de code, votre API génère automatiquement des traces pour toutes les requêtes HTTP, les appels base, les requêtes Redis, etc. Visible immédiatement dans Tempo via Grafana.

Étape 6 — Logs structurés en JSON avec Pino

npm install pino pino-http
# Dans server.js :
# const pino = require('pino')({
#   level: process.env.LOG_LEVEL || 'info',
#   formatters: {
#     level: (label) => ({ level: label })
#   },
#   timestamp: pino.stdTimeFunctions.isoTime
# });
#
# const httpLogger = require('pino-http')({ logger: pino });
# app.use(httpLogger);

# Lancer en envoyant les logs vers Loki via Promtail :
node server.js | tee >(promtail --client.url=http://loki:3100/loki/api/v1/push)

Logs structurés JSON = logs queryables. Au lieu de grep dans des fichiers texte, vous filtrez dans Grafana : level=error AND service=checkout AND statusCode>=500. Réponse en moins d’une seconde même sur 50 millions de lignes.

Étape 7 — Implémenter la méthode RED

RED = Rate (requêtes par seconde), Errors (taux d’erreur), Duration (latence). C’est le triangle minimal pour comprendre la santé d’un service. Pour chaque endpoint critique, vous devez tracker ces 3 métriques en temps réel.

# Exemple métriques Prometheus à exposer dans votre app :
# http_requests_total{method="POST", route="/checkout", status="200"}
# http_requests_total{method="POST", route="/checkout", status="500"}
# http_request_duration_seconds_bucket{route="/checkout", le="0.5"}
# http_request_duration_seconds_bucket{route="/checkout", le="1.0"}

# Requêtes PromQL pour dashboard :
# Rate :
#   sum(rate(http_requests_total{route="/checkout"}[5m]))
# Error ratio :
#   sum(rate(http_requests_total{route="/checkout",status=~"5.."}[5m])) /
#   sum(rate(http_requests_total{route="/checkout"}[5m]))
# Latency p99 :
#   histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{route="/checkout"}[5m]))

Affichez ces 3 graphes côte à côte par service. En cas d’incident, un coup d’œil vous dit immédiatement si le problème vient d’une surcharge (Rate explose), de bugs (Errors monte) ou de lenteur (Duration grimpe).

Étape 8 — Définir SLI et SLO pour vos services

SLI (Service Level Indicator) : la mesure
SLO (Service Level Objective) : l'objectif sur cette mesure
SLA (Service Level Agreement) : engagement contractuel client

Exemple pour API checkout d'une boutique sénégalaise :

SLI 1 : Disponibilité
  Mesure : (requêtes 2xx + 3xx) / total requêtes
SLO 1 : 99,5% sur 30 jours glissants
  (Acceptable downtime : 3h36 par mois)

SLI 2 : Latence
  Mesure : 95e percentile de http_request_duration_seconds
SLO 2 : p95 < 800 ms sur 30 jours

SLI 3 : Qualité
  Mesure : (erreurs 5xx) / total requêtes
SLO 3 : taux d'erreur < 0,5% sur 30 jours

Error Budget = 100% - SLO
  Si SLO 99,5%, error budget = 0,5% = environ 3h36 de downtime/mois
  Tant qu'on ne dépasse pas, on peut prendre des risques (déploiement vendredi soir)
  Si on consomme 80% du budget en 10 jours, on freine

Les SLO transforment le débat émotionnel (« c’est lent ! ») en arbitrage objectif (« on a consommé 60% de notre error budget en 12 jours, donc on stoppe les nouvelles features cette semaine et on stabilise »).

Étape 9 — Alertes intelligentes avec Alertmanager

groups:
  - name: api-critical
    interval: 30s
    rules:
      - alert: CheckoutHighErrorRate
        expr: |
          (
            sum(rate(http_requests_total{route="/checkout",status=~"5.."}[5m]))
            /
            sum(rate(http_requests_total{route="/checkout"}[5m]))
          ) > 0.05
        for: 5m
        labels:
          severity: critical
          team: backend
        annotations:
          summary: "Checkout 5xx rate > 5% pendant 5 minutes"
          description: "Service checkout perd des commandes - investiguer urgemment"
          runbook: "https://wiki.pme-dakar.sn/runbooks/checkout-5xx"

      - alert: CheckoutSlowResponse
        expr: |
          histogram_quantile(0.95,
            rate(http_request_duration_seconds_bucket{route="/checkout"}[5m])
          ) > 2
        for: 10m
        labels:
          severity: warning
          team: backend
        annotations:
          summary: "Checkout p95 > 2 secondes"
          description: "Risque de chute des conversions - vérifier base et cache"

La directive « for: 5m » évite les alertes flashs sur des pics de 30 secondes. La directive « runbook » pointe vers un wiki avec les commandes de diagnostic, gain de temps énorme à 3h du matin.

Étape 10 — Notifications Slack et PagerDuty

route:
  receiver: default-slack
  group_by: ["alertname", "severity"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: pagerduty-oncall
      continue: true
    - match:
        severity: warning
      receiver: slack-warnings

receivers:
  - name: default-slack
    slack_configs:
      - api_url: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
        channel: "#alertes-monitoring"
        send_resolved: true

  - name: slack-warnings
    slack_configs:
      - api_url: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
        channel: "#alertes-warnings"
        title: "Alerte WARNING : {{ .GroupLabels.alertname }}"
        text: "{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}"

  - name: pagerduty-oncall
    pagerduty_configs:
      - service_key: "votre_integration_key_pagerduty"
        severity: "{{ .CommonLabels.severity }}"

PagerDuty (gratuit jusqu’à 5 utilisateurs depuis 2024) appelle l’astreinte au téléphone, escalade après 5 minutes sans accusé de réception. Slack reste pour les warnings non urgents.

Étape 11 — Dashboard Grafana pour la direction

Dashboard "Vision Métier" à afficher en TV au bureau :

Panel 1 : Commandes par minute (last 24h)
  PromQL : sum(rate(orders_created_total[1m])) * 60

Panel 2 : Chiffre d'affaires cumulé du jour
  PromQL : sum(increase(orders_revenue_fcfa_total[24h]))

Panel 3 : Disponibilité globale (gauge 0-100%)
  PromQL : avg(up{job=~"api.+"}) * 100

Panel 4 : Latence checkout p95 (graph 1h)
  PromQL : histogram_quantile(0.95, rate(checkout_duration_seconds_bucket[5m])) * 1000

Panel 5 : Top 5 erreurs des dernières 15 minutes (table)
  Source Loki : {service="api"} | json | level="error"
  | line_format "{{.message}}"

Panel 6 : Carte géographique des visiteurs actifs
  PromQL : sum by (country) (active_users_total)
  Visualization : Geomap

Pour le directeur d’une PME sénégalaise, voir en temps réel les commandes Wave passer crée un sentiment de pilotage tangible. Bonus : aligne tech et business sur les mêmes métriques.

Étape 12 — Tracer une transaction de bout en bout

# Dans Grafana > Explore > Tempo
# Coller un trace_id, ou rechercher par service :

# Service : api-pme-dakar
# Operation : POST /checkout
# Tags : http.status_code=500
# Min Duration : 1s

# Le résultat affiche le waterfall :
# api-pme-dakar  POST /checkout      [800ms total]
#   ├── postgres  SELECT cart_items   [120ms]
#   ├── redis     GET stock:item:42   [3ms]
#   ├── http      POST wave-pay/api   [620ms ! lent]
#   └── postgres  INSERT order        [45ms]

# Vous identifiez en 10 secondes que le problème vient de l'API Wave externe

Sans tracing, ce diagnostic prendrait 2 heures de log-grepping. Avec, 10 secondes. Sur une PME qui perd 50 000 FCFA par minute d’incident, le ROI de l’observabilité dépasse 100x dès le premier incident bien diagnostiqué.

Étape 13 — Tableau des outils par cas d’usage

Besoin Outil OSS Outil SaaS Coût mensuel typique
Logs centralisés Loki + Promtail Datadog Logs 0 ou 0,10 USD/Go
Metrics serveur Prometheus + Node Exporter New Relic Infra 0 ou 0,20 USD/host
Traces distribuées Tempo + OpenTelemetry Honeycomb, Lightstep 0 ou 0,30 USD/M spans
Uptime externe Blackbox Exporter UptimeRobot, Better Uptime 0 ou 7 USD/mois
RUM (Real User Monitoring) OpenTelemetry JS Sentry, FullStory 0 ou 26 USD/mois
Erreurs applicatives GlitchTip (Sentry OSS) Sentry SaaS 0 ou 26 USD/mois
Astreinte OnCall Grafana PagerDuty, Opsgenie 0 ou 19 USD/user

Étape 14 — Préparer un runbook pour chaque alerte

Runbook : CheckoutHighErrorRate

1. Vérifier statut services externes :
   - Wave Pay : https://status.wave.com
   - Orange Money : appeler hotline support
   - Stripe : https://status.stripe.com

2. Regarder logs récents :
   {service="checkout", level="error"} dernière 15 min
   Chercher patterns : timeout, connection refused, validation

3. Vérifier saturation base :
   pg_stat_activity : connections actives
   pg_stat_statements : requêtes lentes en cours

4. Vérifier cache Redis :
   redis-cli info stats : keyspace_hits/misses ratio
   redis-cli info memory : used_memory vs maxmemory

5. Si Wave/Orange Money down :
   - Activer feature flag "FALLBACK_PAYMENT" pour proposer virement
   - Communication client via banner site

6. Si problème base :
   - Restart pgbouncer : systemctl restart pgbouncer
   - Si pas de mieux : failover vers replica

Un bon runbook permet à un dev junior d’appliquer la procédure correcte à 4h du matin sans réveiller le sénior. Documentez chaque alerte critique en 5 à 10 étapes maximum.

Erreurs classiques à éviter

  • Alert fatigue : 50 alertes par jour rendent l’équipe sourde. Maximum 3 alertes critiques par semaine sinon vos seuils sont mal calibrés.
  • Logguer tout en plain text : impossible à requêter efficacement. Toujours JSON structuré avec champs typés.
  • Pas de SLO documentés : chaque incident relance le débat émotionnel. Sans objectif chiffré, pas d’arbitrage rationnel.
  • Conserver les traces 90 jours : votre stockage explose, votre facture aussi. 7 jours de traces et 30 jours de metrics suffisent à 95% des besoins.
  • Monitorer uniquement l’infrastructure : CPU à 30% mais checkout cassé = vous ne voyez rien. Toujours instrumenter le code applicatif.
  • Pas de runbook : le savoir reste dans la tête du sénior. S’il quitte la boîte, l’équipe est paralysée 2 semaines lors d’incidents.

Checklist observabilité production

✓ Stack choisie (LGTM self-hosted ou Datadog managé)
✓ OpenTelemetry installé sur tous les services backend
✓ Logs structurés JSON avec champs : service, level, trace_id, user_id
✓ Métriques RED exposées par chaque endpoint critique
✓ Traces distribuées propagées entre services (W3C trace-context)
✓ Dashboard Grafana "Métier" affiché au bureau
✓ Dashboard "Tech" pour l'équipe dev avec drill-down
✓ SLO documentés pour chaque service critique
✓ Error budget tracké et publié hebdomadairement
✓ Alertmanager configuré avec routes par sévérité
✓ Notifications Slack pour warnings, PagerDuty pour critical
✓ Runbook lié à chaque alerte critique
✓ Rétention adaptée : 7j traces, 30j metrics, 90j logs
✓ Backup config Grafana et règles Prometheus en Git
✓ Postmortem rédigé après chaque incident majeur

À lire aussi : VictoriaMetrics pour le monitoring à grande échelle.

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité