Ma Publicité

Soutenez la Création

Aidez-moi à partager du contenu exclusif.

Soutenir

Comments

Nouveau Drop

Boutique Officielle

Soutenez le blog monblog-sa-abasse et découvrez nos vêtements & accessoires exclusifs en édition limitée.

Découvrir la collection
Paiement Sécurisé
Livraison Monde

Systemd sans douleur : diagnostiquer un service qui plante

Systemd sans douleur : diagnostiquer un service qui plante

Il y a deux types de journées Linux.

Celles où tout tourne. Et celles où tu déploies un service, il démarre, puis il meurt. Ou pire, il redémarre en boucle. Et toi tu regardes l’écran en te disant « mais pourtant, ça marchait en manuel ».

Systemd, au début, peut donner cette sensation bizarre : tout est structuré, propre, mais quand ça casse, tu ne sais pas par quel bout prendre. Bonne nouvelle : on peut rendre ça très mécanique. Une checklist. Des commandes. Un peu de méthode, et tu passes de « je subis » à « je diagnostique ».

Dans cet article, on va faire exactement ça. Et je vais rester dans un cadre réaliste : services qui crash, services qui restent en « activating », services qui bouclent en restart, variables d’environnement pas prises, droits foireux, dépendances réseau, etc.

Terminal Linux avec journaux systemd

Ce que systemd essaie de te dire (et pourquoi tu ne l’entends pas)

Quand un service plante, systemd sait souvent très bien pourquoi. Le souci, c’est qu’il te le dit dans plusieurs endroits.

Tu as au moins 3 sources d’info :

  • l’état du service via systemctl status
  • les logs via journalctl
  • et parfois les logs applicatifs, si ton service écrit ailleurs

L’erreur classique, c’est de faire seulement :

bash systemctl status monservice

De voir 4 lignes rouges. Et de repartir bidouiller le fichier .service au hasard.

On va plutôt faire ça proprement.

Étape 1 : lire l’état, mais vraiment

La commande de base :

bash systemctl status monservice --no-pager -l

  • --no-pager : pas de less, pas de scroll qui te cache des trucs
  • -l : lignes complètes, sinon systemd tronque et tu rates l’info utile

Ce que tu cherches dans la sortie :

  • Active : failed, activating, inactive, active (running)… logique
  • Main PID : est ce que le process existe vraiment
  • ExecStart : la commande exacte lancée
  • Exit code : status=1/FAILURE, status=203/EXEC, etc.
  • les dernières lignes de logs juste en dessous

Exemples de codes qui parlent beaucoup :

  • status=203/EXEC : binaire introuvable, droit d’exécution manquant, ou chemin faux
  • status=217/USER : utilisateur déclaré dans User= invalide ou inaccessible
  • status=1/FAILURE : erreur applicative, souvent à creuser dans les logs

Étape 2 : aller au journal, côté systemd

Ensuite, logs complets du service :

bash journalctl -u monservice --no-pager -b

  • -u : unité
  • -b : depuis le dernier boot, sinon tu mélanges avec des logs d’il y a 3 jours

Astuce simple mais puissante : afficher les logs en temps réel.

bash journalctl -u monservice -f

Tu relances ton service dans un autre terminal, et tu vois instantanément ce qui se passe :

bash systemctl restart monservice

Si le service crashe immédiatement, tu auras la trace au même moment.

Exemple de journaux dans un terminal

Bonus : filtrer les logs d’erreur seulement

Pour couper le bruit :

bash journalctl -u monservice -p err..alert --no-pager -b

Ça remonte souvent pile l’exception ou le message qui manque.

Étape 3 : repérer une boucle de redémarrage

Le scénario typique : ton service démarre, plante, systemd redémarre, replante… et ainsi de suite.

Dans systemctl status, tu verras souvent un truc comme :

  • Scheduled restart job, restart counter is at 5.

Regarde aussi ces paramètres dans ton unité :

  • Restart=
  • RestartSec=
  • StartLimitIntervalSec=
  • StartLimitBurst=

Si tu veux temporairement arrêter la boucle pour respirer :

bash systemctl stop monservice systemctl reset-failed monservice

Le reset-failed est très utile, sinon systemd garde l’état « failed » en mémoire.

Étape 4 : valider le fichier service sans se mentir

Tu as modifié /etc/systemd/system/monservice.service ? Tu dois faire :

bash systemctl daemon-reload

Sinon, systemd ne recharge pas la définition. Et tu crois tester un fix, alors que tu testes l’ancienne config. Classique.

Ensuite :

bash systemctl restart monservice systemctl status monservice --no-pager -l

Vérifier ce que systemd a réellement compris

bash systemctl cat monservice

Tu vois le fichier final, y compris les overrides.

Et encore mieux :

bash systemctl show monservice | head -n 80

Ou ciblé :

bash systemctl show monservice -p ExecStart -p User -p Group -p WorkingDirectory -p Environment

Ça évite les surprises.

Étape 5 : les erreurs les plus fréquentes (et comment les attraper vite)

1) Chemin binaire faux ou non exécutable

Erreur typique : status=203/EXEC.

Vérifie :

bash ls -l /chemin/vers/ton/binaire file /chemin/vers/ton/binaire

Si c’est un script, check le shebang :

bash head -n 1 /chemin/script.sh

Et teste manuellement la commande ExecStart en copiant collant, mais attention : pas dans ton shell habituel avec ton environnement perso. J’y reviens.

2) Variables d’environnement absentes

Un service lancé à la main dans ton terminal marche. En systemd, ça plante. Souvent parce que ton .bashrc n’existe pas ici.

Solutions :

  • définir des variables avec Environment=
  • ou charger un fichier avec EnvironmentFile=

Exemple :

ini [Service] Environment="NODE_ENV=production" EnvironmentFile=/etc/monservice.env

Puis dans /etc/monservice.env :

bash API_KEY=xxxx PORT=8080

Vérifie ensuite que systemd les a bien :

bash systemctl show monservice -p Environment

3) Mauvais répertoire de travail

Si ton app suppose un cwd, mets :

ini WorkingDirectory=/opt/monservice

Sans ça, l’app peut chercher des fichiers relatifs et exploser.

4) Droits utilisateur, permissions, fichiers non accessibles

Si tu as :

ini User=monuser Group=monuser

Vérifie :

bash id monuser sudo -u monuser ls -la /opt/monservice sudo -u monuser /opt/monservice/ton-binaire --version

Beaucoup de crash « silencieux » viennent d’un accès refusé sur un fichier de config, un socket, un dossier de logs.

5) Port déjà utilisé

Si ton service écoute un port, vérifie :

bash ss -lntp | grep :8080

Ou :

bash lsof -i :8080

Si tu vois un autre process, ton service peut mourir direct.

Étape 6 : simuler le contexte systemd (le truc qui change tout)

Ton terminal a ton PATH, tes variables, ton user, ton home. Systemd, non.

Deux outils très pratiques :

1) Exécuter comme l’utilisateur du service

bash sudo -u monuser -H bash -lc '/opt/monservice/start.sh'

  • -l simule un shell login (selon les cas)
  • tu vois déjà si ça plante hors de ton compte

2) systemd-run pour tester rapidement

Tu peux lancer une commande dans un scope systemd :

bash systemd-run --unit=test-monservice --same-dir /opt/monservice/ton-binaire

Puis voir ses logs :

bash journalctl -u test-monservice --no-pager

Ça te rapproche du comportement réel.

Serveur en datacenter

Étape 7 : comprendre les services « qui ne sont pas vraiment des services »

Parfois ton unité est de type oneshot ou ton programme se fork en arrière plan. Et systemd croit que c’est fini, ou au contraire croit que ça n’a jamais démarré.

Regarde :

  • Type=simple (par défaut)
  • Type=forking
  • Type=oneshot
  • Type=notify

Si ton programme se met en arrière plan tout seul, Type=simple peut poser souci. Tu peux aussi avoir besoin de :

ini RemainAfterExit=yes

Ou de corriger le comportement du programme (idéalement).

Étape 8 : les timeouts et dépendances (réseau, DB, etc.)

Tu as un service qui plante au boot mais marche ensuite. Souvent, c’est juste trop tôt. Le réseau n’est pas prêt. La base n’est pas prête.

Tu peux :

  • ajouter After=network-online.target
  • et Wants=network-online.target

Exemple :

ini [Unit] Wants=network-online.target After=network-online.target

Pour les DB, parfois un simple retry applicatif est mieux qu’une dépendance systemd rigide.

Si c’est un problème de timeout, tu peux ajuster :

ini [Service] TimeoutStartSec=60

Mais attention : rallonger un timeout peut masquer un vrai bug.

Étape 9 : quand ça sent le crash natif (segfault)

Si dans les logs tu vois segfault ou core dumped, là on passe en mode debug plus bas niveau.

Déjà, check :

bash coredumpctl list monservice coredumpctl info monservice

Et pour extraire :

bash coredumpctl dump monservice > core.dump

Selon le langage, tu auras tes outils (gdb, etc.). Mais au moins, tu sais que ce n’est pas un simple souci de config systemd.

Petit modèle de service propre (à adapter)

ini [Unit] Description=monservice After=network-online.target Wants=network-online.target

[Service] Type=simple User=monuser Group=monuser WorkingDirectory=/opt/monservice EnvironmentFile=/etc/monservice.env ExecStart=/opt/monservice/monservice Restart=on-failure RestartSec=2 TimeoutStartSec=30

[Install] WantedBy=multi-user.target

Puis :

bash systemctl daemon-reload systemctl enable --now monservice

Checklist express quand ça plante

Quand je veux aller vite, je fais ça, dans cet ordre :

  1. systemctl status monservice --no-pager -l
  2. journalctl -u monservice --no-pager -b
  3. journalctl -u monservice -f puis systemctl restart monservice
  4. systemctl cat monservice
  5. systemctl show monservice -p ExecStart -p User -p WorkingDirectory -p Environment
  6. test manuel en conditions proches : sudo -u monuser -H bash -lc '...'

Et seulement après, je modifie.

Conclusion : systemd est strict, mais il est cohérent

Une fois que tu acceptes que systemd est un orchestrateur qui aime les choses explicites, ça devient plus simple. Tu lui dis exactement quoi lancer, avec quel user, dans quel dossier, avec quelles variables, et comment réagir si ça tombe.

Et quand ça plante, tu ne devines pas. Tu lis. Tu reproduis. Tu corriges. C’est presque reposant, en fait.

Si tu veux d’autres guides dans ce style, côté Linux et sysadmin pratique, j’en publie régulièrement sur « Le Blog Tech Pro de Samyn-Antoy ABASSE » : https://monblog-sa-abasse.blogspot.com/
Je garde le même angle que ici, du concret, des commandes, et pas trop de blabla.

Questions fréquemment posées

Pourquoi mon service systemd démarre puis plante immédiatement ?

Un service systemd qui démarre puis plante peut être dû à plusieurs causes : binaire introuvable ou sans droit d'exécution (status=203/EXEC), utilisateur invalide (status=217/USER), ou erreur applicative (status=1/FAILURE). Il est essentiel de consulter l'état complet via 'systemctl status monservice --no-pager -l' et les logs avec 'journalctl -u monservice --no-pager -b' pour identifier précisément la cause.

Comment lire correctement l'état d'un service avec systemctl ?

Utilisez la commande 'systemctl status monservice --no-pager -l' pour afficher l'état complet sans pagination ni troncature. Vérifiez les champs importants comme Active, Main PID, ExecStart et Exit code. Cette méthode évite de manquer des informations cruciales souvent tronquées ou cachées par le pager.

Comment suivre les logs en temps réel d'un service systemd ?

Pour suivre les logs en temps réel, utilisez la commande 'journalctl -u monservice -f'. Lancez cette commande dans un terminal, puis redémarrez votre service dans un autre terminal avec 'systemctl restart monservice'. Vous verrez immédiatement les messages générés lors du démarrage ou du plantage du service.

Que faire si mon service boucle en redémarrage continu ?

Une boucle de redémarrage peut être identifiée par un message comme 'Scheduled restart job, restart counter is at X.' dans 'systemctl status'. Pour stopper temporairement la boucle, exécutez 'systemctl stop monservice' suivi de 'systemctl reset-failed monservice'. Vérifiez aussi les paramètres Restart=, RestartSec=, StartLimitIntervalSec= et StartLimitBurst= dans le fichier .service.

Comment s'assurer que systemd prend en compte mes modifications dans le fichier .service ?

Après avoir modifié '/etc/systemd/system/monservice.service', il faut impérativement exécuter 'systemctl daemon-reload' pour recharger la configuration. Sans cela, systemd continue d'utiliser l'ancienne définition et vos changements ne seront pas pris en compte. Ensuite, redémarrez le service avec 'systemctl restart monservice'.

Où trouver toutes les informations utiles lors du diagnostic d'un service systemd ?

Il existe au moins trois sources d'information : 1) L'état détaillé du service via 'systemctl status monservice --no-pager -l', 2) Les logs système liés au service avec 'journalctl -u monservice --no-pager -b', 3) Les logs applicatifs spécifiques si le service écrit ailleurs. Combiner ces sources permet un diagnostic précis et efficace.

Enregistrer un commentaire

0 Commentaires

Comments

Nouveau Drop

Boutique Officielle

Soutenez le blog monblog-sa-abasse et découvrez nos vêtements & accessoires exclusifs en édition limitée.

Découvrir la collection
Paiement Sécurisé
Livraison Monde