27 - Gerer les logs comme un adulte
Ce que tu vas apprendre
- Les logging drivers Docker et lequel choisir
- Comment configurer la rotation pour ne pas remplir ton disque
- Pourquoi les logs structures en JSON changent la donne
- Les bases de la centralisation (Loki, ELK)
- La philosophie 12-factor sur les logs
Prerequisites
- Savoir utiliser Docker Compose
- Avoir lu l'article sur les ressources pour comprendre pourquoi le disque se remplit
J'ai passe un dimanche entier a chercher pourquoi un serveur de 50 Go n'avait plus d'espace disque. Pas de donnees, pas de backups. Juste des logs Docker. 43 Go de fichiers JSON dans /var/lib/docker/containers/. Mon conteneur Nginx loggait chaque requête depuis six mois sans rotation. Six mois de GET /favicon.ico empiles dans un seul fichier.
Depuis ce jour, la rotation des logs est la première chose que je configure.
Logging drivers
Docker intercepte tout ce que ton application écrit sur stdout et stderr. Il envoie ca a un logging driver qui décidé comment stocker les logs.
Le driver par défaut est json-file. Il écrit chaque ligne de log dans un fichier JSON sur le disque du host. Simple, lisible, et dangereux sans rotation.
Les principaux drivers :
| Driver | Stockage | docker logs compatible |
|---|---|---|
| json-file | Fichier JSON local | Oui |
| local | Fichier binaire local | Oui |
| syslog | Daemon syslog | Non |
| journald | systemd journal | Oui |
| none | Rien | Non |
Le driver local est une alternative a json-file. Il compresse les logs et gere la rotation nativement. Docker le recommande pour la plupart des cas.
Le driver none désactivé complètement les logs. Utile pour les conteneurs qui gerent leurs propres fichiers de log, mais tu perds docker logs.
Pour changer le driver d'un conteneur :
bashdocker run --log-driver=local mon-app
En Compose :
yamlservices:
api:
image: mon-app:latest
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Rotation : ne fais pas comme moi
Sans rotation, les fichiers de logs grossissent indefiniment. Le driver json-file n'a aucune limite par défaut. Aucune.
Deux options a connaître :
max-size: taille maximale d'un fichier de log avant rotationmax-file: nombre de fichiers conserves
yamllogging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
Avec cette config, tu gardes au maximum 50 Mo de logs par conteneur (5 fichiers de 10 Mo). Quand le fichier courant atteint 10 Mo, Docker le renomme et en créé un nouveau. Quand il y a 5 fichiers, le plus ancien est supprime.
Tu peux aussi configurer ca globalement dans /etc/docker/daemon.json :
json{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
C'est la première chose que je mets sur chaque serveur. Avant meme de déployer quoi que ce soit.
Logs structures en JSON
Quand ton application écrit des logs en texte brut, c'est lisible par un humain. Quand elle écrit en JSON, c'est lisible par une machine.
// Texte brut - bon courage pour parser ca
2026-03-15 14:32:01 ERROR [UserService] Failed to create user john@test.com - duplicate email
// JSON structure - parsable automatiquement
{"timestamp":"2026-03-15T14:32:01Z","level":"error","service":"UserService","message":"Failed to create user","email":"john@test.com","reason":"duplicate email"}
L'avantage du JSON : tu peux filtrer par niveau, chercher par champ, agreger par service. Tous les outils de centralisation comprennent le JSON nativement.
En Node.js, des librairies comme pino ou winston produisent du JSON par défaut. En Python, le module logging avec un JSONFormatter. En Java, logback avec le LogstashEncoder.
Sur paltemps.fr, toutes mes applications loggent en JSON sur stdout. Docker capture le flux, et je peux le traiter comme je veux en aval.
docker compose logs
Les commandes de base :
bash# Tous les logs de tous les services
docker compose logs
# Logs d'un service specifique
docker compose logs api
# Suivre les logs en temps reel
docker compose logs -f api
# Les 100 dernieres lignes
docker compose logs --tail=100 api
# Logs depuis une date
docker compose logs --since="2026-03-15T10:00:00" api
Le flag -f (follow) est celui que j'utilise le plus en dev. En prod, je préféré --tail pour éviter de charger des mois de logs.
Tu peux aussi combiner les services :
bashdocker compose logs -f api worker db
Ca entrelace les logs des trois services avec des couleurs différentes. Pratique pour debugger une chaîne de traitement.
Niveaux de log
La plupart des frameworks supportent des niveaux : debug, info, warn, error, fatal. En dev, tu veux tout voir. En production, info et au-dessus suffisent généralement.
Passe le niveau de log via une variable d'environnement :
yamlservices:
api:
image: mon-app:latest
environment:
- LOG_LEVEL=info
Ne logue jamais de donnees sensibles. Pas de mots de passe, pas de tokens, pas de numeros de carte. Ca parait évident, mais j'ai vu des logs en prod avec des payloads complets de requêtes d'authentification.
Centralisation
Quand tu as un seul serveur, docker compose logs suffit. Quand tu en as cinq, tu as besoin d'un endroit central pour chercher dans tous les logs.
Deux approches populaires :
Grafana Loki : leger, conçu pour les logs. Il ne les indexé pas tous, il indexé les labels. Beaucoup moins gourmand que la stack ELK. C'est mon choix pour les petits et moyens projets.
yamlservices:
api:
image: mon-app:latest
logging:
driver: loki
options:
loki-url: "http://loki:3100/loki/api/v1/push"
loki-batch-size: "400"
ELK (Elasticsearch, Logstash, Kibana) : la référencé historique. Puissant mais gourmand. Elasticsearch seul demande 2 Go de RAM minimum. Reserve ca aux gros projets.
Pour la plupart des équipes, Loki + Grafana fait le job sans la complexité d'ELK.
La philosophie 12-factor
Le 12-Factor App a un principe clair sur les logs : une application ne devrait jamais se preoccuper du routage ou du stockage de ses logs. Elle écrit sur stdout. Point.
C'est exactement ce que Docker attend. Ton application écrit sur stdout et stderr. Docker capture le flux via le logging driver. Toi, tu decides quoi en faire : fichier local, syslog, Loki, ELK.
Si ton application écrit dans un fichier /var/log/app.log a l'intérieur du conteneur, tu perds tout l'avantage. Docker ne voit pas ces logs. Tu dois monter un volume, configurer la rotation toi-meme, et docker logs ne montre rien.
Ecris sur stdout. Laisse l'infrastructure gerer le reste.
Résumé
- Le driver
json-fileest le défaut mais n'a aucune rotation par défaut - Configure toujours
max-sizeetmax-filepour éviter de remplir ton disque - Les logs structures en JSON facilitent le filtrage et la centralisation
- Ecris sur stdout/stderr, pas dans des fichiers (12-factor)
- Loki est un bon choix pour centraliser sans se ruiner en ressources
Precedent : 26 - Ressources | Suivant : 28 - Healthchecks