Nicolas Le Borgne

Développeur

La rotation des logs chez les démons

Le 24 janvier 2021

J’ai dû récemment travailler sur une rotation de fichier de logs. Donc forcement : logrotate. Si c’est plutôt simple pour les logs d’une application web, ça l’est un peu moins vis-à-vis des démons, genre consommateur ou serveur web.

En effet, suite à une rotation, un démon garde le descripteur de l’ancien fichier en mémoire. Le démon ne log donc pas dans le nouveau fichier créé par logrotate.

J'ai rencontré le problème pour Nginx et des services Supervisor.

Mais alors, comment le lui dire ?

En fouillant un peu, j’ai trouvé plusieurs solutions :

  • Utiliser la directive copytruncate.
  • Utiliser la directive postrotate pour redémarrer le démon en question.
  • Toujours avec postrotate, utiliser les signaux SIGUSR1 et SIGUSR2.

Copytruncate

Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost.

man logrotate

Pas grand-chose d’autre à ajouter, la potentielle perte de données me gêne.

Postrotate : redémarrer le démon

postrotate
    service nginx restart

C’est vrai que c’est tentant, mais là encore, me dire que l’on va accepter la coupure d’un nginx le temps de la rotation me gêne encore plus.

Postrotate : SIGUSR1 & SIGUSR2

Les signaux sont des moyens de communication interprocessus. Les usages les plus communs :

  • Le ctrl+c pour terminer un processus, envoi un SIGINT au processus
  • Quand vous voulez stopper un processus avec un kill <pid>, par défaut c’est un SIGTERM
  • Et quand vous en avez marre : kill -9 <pid>, c’est un SIGKILL que vous envoyez au processus

Il se trouve que la norme Posix définit 2 signaux, réservés à l’utilisateur. L’OS ne les enverra jamais. Certains outils déclenchent des comportements spécifiques à leur réception.

No Name Default Action Description 30 SIGUSR1 terminate process User defined signal 1 31 SIGUSR2 terminate process User defined signal 2

man signal

Je pense que vous me voyez venir, dans mon cas, Nginx et Supervisor, implémentent ces signaux :

SIGUSR2 supervisord will close and reopen the main activity log and all child log files.

Documentation de Supervisor

USR2 upgrading an executable file

Documentation de Nginx

Le tout, traduit dans un fichier logrotate :

/var/log/<app_name>/*.log {
    compress
    daily
    rotate 365
    missingok
    create
    sharedscripts
    postrotate
        [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`; \
        [ ! -f /var/run/supervisord.pid ] || kill -USR2 `cat /var/run/supervisord.pid`; \
    endscript
}

Je n’ai pas eu besoin de chercher pour d’autre outils, mais à priori la pratique est courante 🙂

Sources

© 2021 Nicolas Le Borgne