📍 Article principal du programme : Linux fondamentaux 2026 — commandes, services, dépannage
Ce tutoriel fait partie du programme « Linux fondamentaux ». Pour la vue d’ensemble, lisez d’abord le guide principal.
Introduction
Avant systemd, lire les logs Linux signifiait jongler entre une demi-douzaine de fichiers texte dans /var/log/ dont les noms et formats différaient d’une distribution à l’autre. Depuis l’adoption généralisée de systemd, le journal est centralisé, structuré, indexé, et s’interroge avec une seule commande : journalctl. Maîtriser cet outil est l’un des leviers les plus rentables d’un administrateur. Dans 80 % des incidents en production, la cause exacte de la panne est inscrite quelque part dans le journal — encore faut-il savoir filtrer pour la trouver. Ce tutoriel vous fait passer de zéro à des requêtes journalctl chirurgicales en huit étapes appliquées.
Prérequis
- Une machine Linux avec systemd (toute distribution récente : Ubuntu 24.04/26.04 LTS, Debian 13, AlmaLinux 9, Rocky Linux 9).
- Un compte avec accès
sudo(la lecture du journal complet exige des privilèges). - Connaissance de base des services systemd — voir le tutoriel systemd du programme si nécessaire.
- Niveau attendu : intermédiaire débutant.
- Temps estimé : 75 minutes.
Étape 1 — Comprendre où vit le journal
Le service systemd-journald capture trois flux : la sortie standard et l’erreur standard de tous les services systemd, les messages du noyau (dmesg), et les messages syslog historiques. Tout est stocké dans des fichiers binaires sous /var/log/journal/ (persistant) ou /run/log/journal/ (volatil, perdu au reboot).
# Vérifier où est stocké le journal
sudo ls -la /var/log/journal/ 2>/dev/null && echo "Journal persistant" || echo "Journal volatil"
# Espace utilisé
journalctl --disk-usage
# Configuration en vigueur
cat /etc/systemd/journald.conf
Si /var/log/journal/ n’existe pas, le journal est volatil — il disparaît à chaque redémarrage, ce qui rend les diagnostics post-mortem impossibles. Pour rendre le journal persistant, créez le répertoire avec sudo mkdir -p /var/log/journal && sudo systemd-tmpfiles --create --prefix /var/log/journal puis sudo systemctl restart systemd-journald. Sur les VPS minuscules (1 Go de RAM, 25 Go de disque), pensez à plafonner la taille avec SystemMaxUse=200M dans /etc/systemd/journald.conf — sans cela, le journal peut grossir jusqu’à occuper 10 % de la partition racine et causer des pannes par disque plein.
Étape 2 — Les requêtes essentielles
Cinq commandes couvrent 90 % des usages quotidiens. Apprenez-les comme on apprend les sept péchés capitaux : par cœur.
journalctl -u nginx # tout le journal du service nginx
journalctl -u nginx -n 50 --no-pager # les 50 dernières lignes, sans pager
journalctl -u nginx -f # suivre en direct (Ctrl-C pour quitter)
journalctl -u nginx --since "1 hour ago" # depuis une heure
journalctl -u nginx -p err # uniquement les erreurs (priorité ≤ err)
Le drapeau -u filtre par unité systemd ; -n N limite aux N dernières lignes ; -f suit le journal en direct (équivalent de tail -f) ; --since et --until bornent la fenêtre temporelle ; -p filtre par priorité (de emerg à debug). L’option --no-pager envoie la sortie directement sur le terminal au lieu d’ouvrir less, indispensable dans les scripts. Si vous n’avez pas de filtre -n, journalctl commence par afficher les entrées les plus anciennes ; pour voir d’abord les plus récentes, ajoutez -r (reverse).
Étape 3 — Filtrer par fenêtre temporelle
Quand un incident survient à une heure précise, vous voulez circonscrire la lecture à cette fenêtre, pas avaler le journal des trois derniers jours. journalctl accepte des dates en format ISO ou des expressions naturelles en anglais.
journalctl --since "2026-05-04 14:00:00" --until "2026-05-04 15:00:00"
journalctl --since today
journalctl --since yesterday --until today
journalctl --since "30 min ago"
journalctl --since "2 days ago" -p warning..err
L’expression "30 min ago" est interprétée par systemd selon la même grammaire que OnCalendar= dans les minuteurs. -p warning..err est une plage de priorités, équivalente à « warning, err et tout entre les deux ». Pour lister les niveaux disponibles : emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6), debug (7). La règle pratique : sur un serveur en production, partir d’-p err pour repérer les vraies urgences, descendre à -p warning si nécessaire, et n’afficher tout (-p info) qu’en dernier recours pour les diagnostics fins.
Étape 4 — Filtrer par démarrage et corrélation
Quand un serveur a redémarré dans la journée, le journal couvre plusieurs « boots » consécutifs. journalctl les distingue avec un identifiant unique appelé boot ID.
journalctl --list-boots # liste les démarrages indexés
# 0 9b3a7c8d... May 5 09:00 — May 5 14:30
# -1 4e2f1a5b... May 4 22:15 — May 5 08:55
journalctl -b # journal du boot courant
journalctl -b -1 # journal du boot précédent
journalctl -b 9b3a7c8d... -p err # erreurs d'un boot précis
journalctl -k # uniquement les messages noyau du boot courant
journalctl -k -b -1 # messages noyau du précédent boot
Le drapeau -k est l’équivalent moderne de la commande dmesg : il extrait du journal uniquement les lignes émises par le noyau — celles qui parlent de pilotes, de matériel, du OOM Killer ou d’erreurs disque. Pour comprendre pourquoi le serveur a tué votre processus à 3 h du matin, journalctl -k -b | grep -i "out of memory" donne souvent la réponse en une ligne, avec le PID, le nom du processus, et la quantité de mémoire qu’il consommait au moment fatal.
Étape 5 — Les filtres de champ pour la précision
Chaque entrée du journal porte une vingtaine de champs structurés. journalctl permet de les utiliser comme filtres directs sous la forme CHAMP=valeur.
# Filtrer par PID
journalctl _PID=1234
# Filtrer par utilisateur
journalctl _UID=1000
# Filtrer par exécutable
journalctl _EXE=/usr/bin/python3
# Filtrer par identifiant de transaction systemd
journalctl _SYSTEMD_INVOCATION_ID=abc123...
# Combiner (les filtres sur le même champ font un OU, sur des champs différents un ET)
journalctl _SYSTEMD_UNIT=nginx.service _SYSTEMD_UNIT=php-fpm.service
journalctl _SYSTEMD_UNIT=nginx.service _PID=1234
# Voir tous les champs disponibles d'une entrée
journalctl -u nginx -n 1 --output=verbose
Le mode --output=verbose affiche pour chaque entrée la totalité des champs — c’est l’équivalent de l’autopsie d’un message. Sur un système d’exploitation moderne, on y trouve l’horodatage en microsecondes (__REALTIME_TIMESTAMP), la hiérarchie cgroup (_SYSTEMD_CGROUP), l’identifiant unique du boot (_BOOT_ID), le nom de l’hôte (_HOSTNAME) et bien d’autres. Cette structure rend le journal exploitable par des agrégateurs comme Loki, Vector ou Elasticsearch sans avoir à parser des chaînes de caractères fragiles.
Étape 6 — Sortie structurée et chaînage
Pour intégrer le journal à un pipeline d’observabilité, journalctl peut émettre du JSON ligne par ligne, format directement consommable par jq, Loki ou n’importe quel collecteur moderne.
# JSON brut, une ligne par entrée
journalctl -u nginx --since "1 hour ago" -o json
# JSON avec mise en forme lisible
journalctl -u nginx -n 5 -o json-pretty
# Compter les erreurs par message
journalctl -p err --since today -o json | jq -r .MESSAGE | sort | uniq -c | sort -rn | head
# Extraire les IP qui ont causé une erreur 5xx
journalctl -u nginx --since "10 min ago" -o json | jq -r 'select(.MESSAGE | test("HTTP/1.1\" 5[0-9][0-9]")) | .MESSAGE'
L’avantage du format JSON sur la sortie texte traditionnelle : pas de cassure si un message contient des espaces, des sauts de ligne ou des caractères non ASCII, et chaque champ reste accessible séparément. Pour une intégration à Loki, l’agent promtail sait lire directement le journal systemd ; pour une intégration à Elasticsearch, un Filebeat configuré sur le module journald fait le travail. Les deux montent en charge à plusieurs milliers de messages par seconde sans difficulté.
Étape 7 — Rotation et politique de rétention
Le journal grossit. Sans politique de rétention explicite, il finit par saturer le disque — incident classique sur les VPS modestes. Trois leviers permettent de plafonner sa taille.
# Voir l'usage courant
journalctl --disk-usage
# Garder uniquement les 7 derniers jours
sudo journalctl --vacuum-time=7d
# Garder uniquement les 500 derniers Mo
sudo journalctl --vacuum-size=500M
# Garder uniquement les 5 derniers fichiers
sudo journalctl --vacuum-files=5
Pour un plafond permanent, éditez /etc/systemd/journald.conf et activez les directives suivantes : SystemMaxUse=500M (taille totale maximale), SystemKeepFree=1G (espace minimal à laisser libre sur la partition), SystemMaxFileSize=50M (taille de chaque fichier individuel avant rotation), MaxRetentionSec=30day (durée maximale de conservation). Après modification, sudo systemctl restart systemd-journald applique les nouvelles règles. Pour les fichiers texte hors-systemd qui restent dans /var/log/ (par exemple auth.log sur Debian), la rotation est gérée par logrotate, configuré dans /etc/logrotate.d/ et exécuté quotidiennement par un timer systemd.
Étape 8 — Vérification et bonnes habitudes
Pour valider votre maîtrise, lancez la séquence de diagnostic ci-dessous sur un serveur de test. Elle reproduit ce qu’un administrateur expérimenté tape par réflexe à l’arrivée sur une machine inconnue.
# 1. Vue d'ensemble : services en échec et erreurs récentes
systemctl --failed
journalctl -p err -b --no-pager | tail -30
# 2. Pression mémoire : OOM killer a-t-il frappé ?
journalctl -k -b | grep -i "out of memory" | tail -10
# 3. Connexions SSH suspectes
journalctl -u ssh --since "24 hours ago" | grep -i "Failed\|Accepted" | tail -20
# 4. Audit de l'usage disque du journal
journalctl --disk-usage
# 5. Vérification de la configuration de rétention
grep -E "^(SystemMaxUse|MaxRetention|SystemKeepFree)" /etc/systemd/journald.conf
Les sorties attendues ressemblent à : zéro service en échec, quelques erreurs récurrentes mais maîtrisées (à corriger), aucun OOM récent, des connexions SSH conformes à votre activité, un journal entre 100 Mo et 1 Go selon la machine, et au moins une directive de plafonnement active. Cette routine de cinq minutes vous donne en arrivant sur un serveur une photographie fidèle de sa santé — souvent plus utile que la vue d’ensemble offerte par les outils de monitoring orientés métriques.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
journalctl ne montre que le boot courant |
Journal volatil (pas de /var/log/journal/) |
Créer le répertoire et redémarrer journald, voir étape 1 |
| Sortie tronquée par défaut | Pager less qui coupe les lignes longues |
Ajouter --no-pager ou taper -S dans less pour désactiver le retour à la ligne |
| Permission denied sur certains messages | Lecture des journaux d’autres services exige sudo ou groupe systemd-journal |
sudo usermod -aG systemd-journal $USER puis nouvelle session |
| Disque plein à cause du journal | Aucune limite définie | Configurer SystemMaxUse= dans journald.conf |
| Logs applicatifs manquants alors que le service tourne | L’appli écrit dans son propre fichier au lieu de stdout | Configurer StandardOutput=journal dans le fichier .service |
| Recherche par texte lente | journalctl n’a pas d’index plein-texte |
Filtrer par champ structuré (_SYSTEMD_UNIT, _PID) avant le grep |
Tutoriels associés
Lectures complémentaires
- 🔝 Retour au guide principal : Linux fondamentaux 2026
- Pages de manuel :
man journalctl,man systemd.journal-fields,man journald.conf. - Documentation freedesktop systemd-journald — freedesktop.org
- Grafana Loki, agrégateur de logs compatible journald — grafana.com/oss/loki
- How to find and interpret system log files on Linux (Red Hat) — redhat.com/sysadmin
FAQ
Faut-il garder syslog en plus de journald ?
Sur la plupart des serveurs en 2026, journald seul suffit. rsyslog reste pertinent dans deux cas : si vous expédiez les logs vers un serveur central via le protocole syslog (port 514), ou si une application tierce écrit explicitement via logger ou la fonction C syslog(). Sinon, désactiver rsyslog allège le système d’un démon redondant.
Comment expédier le journal vers un serveur central ?
Trois options selon le contexte. systemd-journal-remote envoie en HTTPS vers un autre journald distant — natif, sans dépendance, mais peu de filtrage. promtail de Grafana lit le journal et l’envoie vers Loki — léger, multi-tenant, requêtable en LogQL. Filebeat ou Vector lisent le journal et l’envoient vers Elasticsearch ou n’importe quelle destination — plus lourd mais très flexible. Pour un parc inférieur à 50 machines, Loki est en général le meilleur compromis.
Comment voir les logs d’une session SSH passée ?
Les sessions SSH apparaissent dans le journal du service ssh.service (Debian/Ubuntu) ou sshd.service (Alma/Rocky). journalctl -u ssh --since "yesterday" | grep -E "Accepted|Failed" liste les tentatives de connexion. Pour la trace shell détaillée d’une session interactive, il faut activer auditd avec des règles spécifiques ; le journal systemd ne capture pas ce qui se passe à l’intérieur d’un shell.
Comment diagnostiquer un service qui n’apparaît pas dans le journal ?
Trois causes possibles. La plus fréquente : le service écrit dans son propre fichier (/var/log/mon-app/app.log) parce que sa configuration applicative redirige stdout. La solution est de modifier la config applicative pour écrire sur stdout, et de laisser systemd capturer. Deuxième cause : le fichier .service contient StandardOutput=null ou StandardOutput=file:, à corriger en StandardOutput=journal. Troisième cause : le service plante avant d’écrire quoi que ce soit ; systemctl status mon-app affiche alors le code de retour et les premiers signaux.
Quelle priorité utiliser quand mon application logue elle-même ?
La convention est : error pour ce qui interrompt une opération que l’utilisateur attendait, warning pour ce qui est anormal mais récupéré, notice pour les événements importants normaux (démarrage, arrêt, déploiement), info pour le suivi métier, debug pour le détail interne. En production, info est la limite saine ; debug doit être activable temporairement à la demande mais jamais permanent, sous peine de saturer le disque.
Comment marquer manuellement un événement pour le retrouver plus tard ?
La commande logger -t deploy "Déploiement v2.4 démarré" insère une entrée dans le journal avec le tag deploy. Vous la retrouvez ensuite avec journalctl -t deploy. C’est la pratique standard pour annoter une intervention manuelle, un déploiement ou un incident — la trace reste corrélée au reste du journal et permet de reconstruire la chronologie.
Comment savoir quels services écrivent le plus dans le journal ?
La commande journalctl --since today -o json | jq -r ._SYSTEMD_UNIT | sort | uniq -c | sort -rn | head compte les entrées de la journée par unité et affiche le top. Sur un serveur sain, les premiers de la liste sont systemd lui-même, le service réseau et l’éventuel agent de monitoring. Si une application métier figure en tête avec des dizaines de milliers d’entrées par jour, c’est en général le signe d’un niveau de log applicatif trop bavard à corriger.
Comment vérifier l’intégrité du journal ?
Le format binaire de journald inclut des sommes de contrôle internes. sudo journalctl --verify parcourt l’ensemble des fichiers et signale toute corruption — utile après une coupure électrique brutale ou si le système de fichiers a connu des erreurs. En cas de corruption détectée, la pratique recommandée est de mettre les fichiers concernés de côté pour analyse, plutôt que d’essayer de les réparer en place.
Comment intégrer journalctl à un script de déploiement ?
Trois patterns reviennent. Premièrement, capturer les N dernières lignes d’un service après redémarrage et les inclure dans le rapport de déploiement : journalctl -u mon-app -n 50 --no-pager --since "1 minute ago". Deuxièmement, attendre qu’un service signale qu’il est prêt avant de continuer : journalctl -u mon-app -f -o cat | grep -m 1 "ready to accept connections". Troisièmement, vérifier qu’aucune erreur n’est apparue depuis le démarrage avec journalctl -u mon-app -p err --since "$(systemctl show -p ActiveEnterTimestamp mon-app | cut -d= -f2)". Ces trois snippets, intégrés à un pipeline CI/CD, transforment des déploiements aveugles en déploiements observés.