Comment créer un graveur de fichier logrotate friendly en Java ou sur une autre plate-forme?

Quelles sont les meilleures pratiques pour implémenter un graveur / enregistreur de fichier en Java compatible avec logrotate ? L’objective serait de permettre à logrotate d’être utilisé pour toute la gestion des journaux au lieu d’utiliser la gestion / rotation intégrée d’une API de journalisation (Log4J, etc.).

Je serais intéressé à entendre des commentaires / réponses pour d’autres plates-formes de développement, à part Java.

Il vous suffit simplement de fermer et de rouvrir périodiquement le fichier journal dans votre application. Vous avez besoin d’un gestionnaire qui conserve la dernière heure de fermeture. Le gestionnaire doit fermer et rouvrir le fichier si (par exemple) 20 secondes se sont écastings depuis la dernière fermeture et que l’entrée du journal est sur le point d’être écrite. Il devrait faire cette vérification juste avant d’écrire l’entrée du journal

Si vous ne le faites pas, les journaux seront écrits dans l’ancien fichier même s’il est renommé par logrotate (!) (Le descripteur de fichier rest le même), puis les entrées du journal disparaîtront lorsque le journal sera compressé et supprimé ( dans ce cas, Java supprimera silencieusement ces journaux).

La fermeture et la réouverture du journal (en utilisant le nom de fichier) garantira que si le fichier a été renommé, un nouveau fichier sera créé. La fermeture et la réouverture du fichier chaque fois que le journal est écrit est une perte de temps car ouvrir un fichier est une opération coûteuse.

J’ai regardé d’autres applications et apparemment, il existe une option postrotate et une option copytruncate . L’option copytruncate est plus facile mais je pense qu’elle est moins fiable car les tampons ne peuvent pas être vidés (c’est-à-dire suivre la réponse @Jarek Potuik) et même s’ils le sont, vous pouvez obtenir des entrées en double ou des entrées supprimées.

Supposons donc que vous souhaitiez l’option postrotate :

L’option postrotate vous permet d’exécuter une commande pour indiquer à votre application de rouvrir le fichier (fermer puis ouvrir). Lors de l’ouverture et de la fermeture du fichier en Java, vous utiliseriez un bloc synchronisé ou une sorte de verrou et, bien sûr, vider les mémoires tampons.

Supposons que votre application s’appelle myapp :

Vous auriez un fichier dans /etc/logrotate.d/myapp avec quelque chose comme:

 /var/log/myapp/*.log { weekly missingok rotate 20 compress delaycompress notifempty sharedscripts postrotate /etc/init.d/myapp rotate-logs > /dev/null endscript } 

La commande /etc/init.d/myapp rotate-logs devrait indiquer à l’application de fermer et de rouvrir les fichiers journaux.

La partie signalisation est assez délicate et dépend du type d’application que vous utilisez car Java ne prend pas aussi bien en charge le protocole IPC (signaux Unix); vous devrez donc peut-être ouvrir un port ou utiliser un port existant tel que 8080 (commande HTTP REST). dans le cas d’un conteneur de servlet) pour indiquer à votre application de fermer et de rouvrir les fichiers journaux.