← Retour aux articles
28 September 2025 4 min de lecture GrafanaPrometheusLokiGoMonitoringDocker

L'art de la traçabilité

Comment mettre en place une traçabilité complète avec Grafana, Prometheus et Loki sur une stack Go/Vue.js/Docker. Retour d'expérience chez Butterfly Therapeutics.

Chez Butterfly Therapeutics, on avait une stack un peu particulière : du Go/PostgreSQL et Vue 3 pour le web, des apps dans des casques de réalité virtuelle sous Android, des apps Android et iOS classiques. Le tout dockerisé, déployé sur un serveur dédié. Quand un patient signalait un bug dans son casque VR en pleine séance de traitement de l’endométriose, il fallait être capable de remonter la chaîne — du casque au backend — en quelques minutes. Pas le lendemain.

C’est dans ce contexte que j’ai mis en place une stack Prometheus, Loki et Grafana. Et que j’ai compris à quel point la traçabilité, ce n’est pas un “nice to have” qu’on rajoute après coup. C’est un truc qu’on regrette de ne pas avoir mis dès le début.

Le vrai problème : on découvre les bugs par les utilisateurs

Avant d’avoir une stack de monitoring en place, on fonctionnait comme tout le monde. Un utilisateur signale un problème, on se connecte en SSH, on fouille dans les logs avec grep, on essaie de reconstituer ce qui s’est passé. Avec de la chance, on trouve. Sans chance, on demande au patient de “réessayer”.

Dans un contexte medtech, ce n’est pas acceptable. Mais honnêtement, ça ne devrait l’être nulle part.

Logs, métriques, traces : trois trucs différents

On mélange souvent les trois. C’est pourtant assez simple.

Les logs, c’est le journal de bord. Qu’est-ce qui s’est passé, quand, et dans quel contexte. Chez Butterfly, on envoyait tout dans Loki en JSON structuré — requêtes HTTP, erreurs, événements métier. L’avantage de Loki par rapport à une stack ELK : c’est conçu pour Docker, ça se branche sur Grafana sans configuration, et ça ne bouffe pas la moitié de votre RAM.

Les métriques, c’est l’état de santé en temps réel. Prometheus collecte le temps de réponse des API, le taux d’erreurs HTTP, la consommation mémoire. On avait aussi des métriques front — temps de chargement des composants Vue 3, nombre de sessions actives. Quand un chiffre dérape, vous le voyez avant que les utilisateurs ne s’en plaignent.

Les traces, c’est le parcours d’une requête à travers vos services. Une action utilisateur dans le casque VR passait par l’app Android, puis l’API Go, puis PostgreSQL. OpenTelemetry nous permettait de suivre ce chemin de bout en bout et de trouver où ça coinçait.

En pratique avec Go

L’instrumentation du backend Go est directe avec prometheus/client_golang :

var (
    httpRequests = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total HTTP requests",
        },
        []string{"method", "path", "status"},
    )
    httpDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "HTTP request duration",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "path"},
    )
)

func metricsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        sw := &statusWriter{ResponseWriter: w}
        next.ServeHTTP(sw, r)
        
        httpRequests.WithLabelValues(r.Method, r.URL.Path, strconv.Itoa(sw.status)).Inc()
        httpDuration.WithLabelValues(r.Method, r.URL.Path).Observe(time.Since(start).Seconds())
    })
}

Ces métriques sont collectées par Prometheus et affichées dans des tableaux de bord Grafana.

Ce que j’aurais aimé savoir avant

Tout dans Grafana. Logs, métriques, traces — un seul dashboard. Quand une alerte se déclenche, vous voulez passer des métriques aux logs en un clic, pas jongler entre trois outils.

Les alertes, c’est du code. Si vous configurez une alerte “taux d’erreurs > 5%”, testez-la. Déclenchez-la volontairement. J’ai vu trop d’alertes Prometheus qui n’avaient jamais fonctionné parce que personne n’avait vérifié que le webhook Discord était bien configuré.

Attention aux données sensibles dans les logs. En medtech, on manipule des données de santé. Un log.Info("user data", userData) qui balance un dossier patient dans Loki, c’est un incident RGPD. On a mis en place un middleware de sanitization assez tôt — je vous le recommande quel que soit votre secteur.

Le résultat

Après mise en place, on est passé de “quelqu’un a signalé un bug, on cherche” à “on a vu l’anomalie ce matin, c’est déjà corrigé”. Le temps de diagnostic moyen est passé de plusieurs heures à quelques minutes. Et surtout, on a gagné en confiance — quand vous savez exactement ce qui se passe sur votre infra, vous dormez mieux.

Besoin d'aide sur ce sujet ?

Réserver un créneau