J'ai une application PHP qui peut générer beaucoup d'informations sur les journaux. Je voudrais utiliser logrotate
pour m'assurer que ces journaux ne deviennent pas incontrôlables au fil du temps .
Cependant, je suis préoccupé par les conditions de course. Pourrait-il y avoir une perte de messages de journal si PHP est en train d'écrire dans un journal lorsque logrotate
détermine qu'il doit faire tourner ce journal, comme dans la séquence d'événements ci-dessous Si non, pourquoi?
logrotate
décide que le fichier journal doit être tourné.Est-ce que l'utilisation de PHP file_put_contents
, par exemple, fait une différence? Qu'en est-il, plus généralement, de la sortie redirigée vers un fichier journal?
Spécificités de l'environnement:
J'utilise php5-fpm
(Version: 5.5.9+dfsg-1ubuntu4.6
) derrière un serveur nginx sur une autre machine.
Ma configuration logrotate proposée (je n'ai encore rien configuré) ressemblerait à ceci (en /etc/logrotate.d/my-app
):
/var/my-app-data/logs/*.log {
missingok
notifempty
weekly
size 20M
rotate 4
}
Quelques exemples de mon PHP:
$res = file_put_contents('/var/my-app-data/logs/general.log', date('[d/m/Y H:i:s]') . ' Something noteworthy has happened!' . "\n", FILE_APPEND);
Il est possible que nous souhaitions à l'avenir utiliser quelque chose comme le code ci-dessous:
$fp = fopen('/var/my-app-data/logs/general.log', 'a');
fwrite($fp, date('[d/m/Y H:i:s]') . ' Starting process...' . "\n");
// ...
fwrite($fp, date('[d/m/Y H:i:s]') . ' Something happened!' . "\n");
// ...
fwrite($fp, date('[d/m/Y H:i:s]') . ' Something happened!' . "\n");
// ...
fwrite($fp, date('[d/m/Y H:i:s]') . ' End of process.' . "\n");
fclose($fp);
Lorsqu'une application ouvre un fichier, continuez à l'écrire même s'il est déplacé. Par conséquent, si vous voulez être sûr de ne pas perdre d'informations, vous devez envoyer un signal à l'application afin qu'elle libère des ressources.
Vous pouvez essayer cette configuration:
/var/my-app-data/logs/general.log {
missingok
notifempty
size 20M
rotate 4
create mode owner group
sharedscripts
postrotate
nginx command to do graceful restart
endscript
}
Ce fichier general.log
Subit une rotation chaque fois qu'il atteint une taille supérieure à 20M
, Après avoir effectué 4
Rotations, le fichier est supprimé.
Le sharedscripts
signifie que le script postrotate
ne sera exécuté qu'une seule fois, pas une fois pour chaque journal qui est tourné.
Selon logrotate manuel:
create mode owner group
Immediately after rotation (before the postrotate script is run)
the log file is created (with the same name as the log file just
rotated). mode specifies the mode for the log file in octal
(the same as chmod(2)), owner specifies the user name who will
own the log file, and group specifies the group the log file
will belong to.
Donc dans votre cas:
Votre application continuera à écrire general.log.1 jusqu'à ce que le fichier soit fermé ou que postscript
soit exécuté et que nginx effectue un redémarrage régulier.
Si votre application ferme toujours le fichier journal via fclose($fp)
ou utilise file_put_contents
, Vous devez omettre nginx
grâce au redémarrage.