8 votes

Loger à travers un FIFO, puis rediriger vers un fichier ?

J'ai une application qui doit enregistrer chaque transaction. Chaque message d'enregistrement est supprimé parce que nous devons avoir un enregistrement de ce qui s'est passé jusqu'à un crash. Mes collègues et moi étions curieux de savoir comment obtenir les effets de performance de la mise en mémoire tampon tout en garantissant que le message d'enregistrement avait quitté le processus.

Ce que nous avons trouvé est :

  • créer une FIFO dans laquelle l'application peut écrire, et
  • rediriger le contenu de cette FIFO vers un fichier ordinaire via cat .

C'est-à-dire, ce qui était ordinairement :

app --logfile logfile.txt

est maintenant :

mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo

Cette approche comporte-t-elle des inconvénients ? Cela a fonctionné lorsque nous l'avons testé, mais nous voulons être absolument sûrs que les messages trouveront leur chemin vers le fichier de redirection même si l'application originale se plante.

(Nous n'avons pas le code source de l'application, donc les solutions de programmation sont hors de question. De plus, l'application n'écrira pas sur stdout Il n'est donc pas question de passer directement à une autre commande. Donc syslog n'est pas une possibilité).


Mise à jour : J'ai ajouté une prime. La réponse acceptée sera no impliquer logger pour la simple raison que logger es no ce que j'ai demandé. Comme l'indique la question initiale, je ne cherche que des problèmes liés à l'utilisation d'une FIFO.

6voto

Matthew Ife Points 22370

Notez qu'un fifo est généralement nécessaire dans les programmes où la quantité écrite peut dépasser la quantité lue.

En tant que tel, un fifo ne fonctionnera pas tout à fait comme vous le prévoyez, mais il résoudra votre principal problème tout en en introduisant un autre.

Il y a trois mises en garde possibles.

  1. L'écriture dans le fifo est bloquée indéfiniment si rien n'est lu à l'autre extrémité lors de l'initialisation.
  2. Le fifo a une largeur fixe de 64K, ce qui signifie que si la mémoire tampon est remplie à ce moment-là, les autres écritures seront bloquées jusqu'à ce que le lecteur ait rattrapé son retard.
  3. L'auteur du pipe sera tué par SIGPIPE si le lecteur meurt ou sort.

Cela signifie que votre problème (émuler des E/S tamponnées sur une écriture non tamponnée) sera résolu. En effet, la nouvelle "limite" de votre FIFO deviendra en fait la vitesse de l'utilitaire qui écrit ce qui se trouve dans le tube sur le disque (ce qui sera vraisemblablement une entrée/sortie en mémoire tampon).

Néanmoins, le rédacteur devient dépendant de votre lecteur de journaux pour fonctionner. Si le lecteur cesse soudainement de lire, le rédacteur se bloque. Si le lecteur s'arrête soudainement (disons que vous n'avez plus d'espace disque sur votre cible), le scripteur sera SIGPIPE et probablement sortira.

Un autre point à mentionner est que si le serveur panique et que le noyau cesse de répondre, vous pouvez perdre jusqu'à 64k de données qui étaient dans cette mémoire tampon.

Une autre façon de résoudre ce problème est d'écrire les journaux dans tmpfs (/dev/shm sous linux) et d'envoyer la sortie vers un emplacement fixe sur le disque. Il y a des limites moins restrictives sur l'allocation de mémoire en faisant cela (pas 64K, typiquement 2G !) mais cela pourrait ne pas fonctionner pour vous si le rédacteur n'a pas de moyen dynamique de rouvrir les fichiers journaux (vous devriez nettoyer les journaux de tmpfs périodiquement). Si le serveur panique avec cette méthode, vous risquez de perdre BEAUCOUP plus de données.

4voto

Stefan Lasiewski Points 22459
mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo

Que se passe-t-il lorsque votre cat logfifo le processus meurt, quelqu'un le tue par accident, ou quelqu'un le dirige accidentellement vers le mauvais endroit ?

D'après mon expérience, le app sera rapidement bloqué et suspendu. J'ai essayé cela avec Tomcat, Apache et quelques petites applications maison, et j'ai rencontré le même problème. Je n'ai jamais cherché très loin, car logger ou une simple redirection des E/S a fait ce que je voulais. Je n'ai généralement pas besoin de l'exhaustivité de la journalisation, qui est ce que vous essayez de poursuivre. Et comme vous le dites, vous ne voulez pas de logger.

Ce problème fait l'objet d'une discussion à l'adresse suivante fifo Linux non bloquant (enregistrement à la demande) .

2voto

Mei Points 4515

L'environnement est CentOS et l'application écrit dans un fichier...

Au lieu d'envoyer la sortie vers un fichier ordinaire, je l'enverrais vers syslog et je m'assurerais que les messages syslog sont envoyés à un serveur central ainsi qu'en local.

Vous devriez pouvoir utiliser un Shell Shell comme ceci :

logger -p daemon.notice -t app < fifo

Vous pourriez également prendre des contributions (à logger ) de cat ou de tail -f dans un tuyau :

tail -f fifo | logger ...
cat fifo | logger ...

Le seul problème est qu'il ne fait pas de différence en fonction de l'importance du message du journal (tout est AVIS ) mais au moins, il est enregistré et envoyé hors de l'hôte vers un serveur central.

La configuration de syslog dépend du serveur que vous utilisez. Il existe rsyslog y syslog-ng (les deux très capable).

EDIT : Révisé après avoir obtenu plus d'informations de l'affiche.

2voto

Pontus Points 730

Vos options sont assez limitées par l'application, mais ce que vous avez testé fonctionnera.

Nous faisons quelque chose de similaire avec varnish et varnishncsa pour obtenir les logs dans un endroit qui nous est utile. Nous avons un fifo et nous le lisons simplement avec syslog-ng et l'envoyons là où nous en avons besoin. Nous gérons environ 50 Go et n'avons pas rencontré de problème avec cette approche jusqu'à présent.

1voto

nickgrim Points 4236

Vous écrivez :

De plus, l'application n'écrira pas sur stdout ...

Avez-vous essayé de vous connecter au "fichier" ? /dev/stdout ? Cela pourrait vous permettre de faire quelque chose comme :

app --logfile /dev/stdout | logger -t app

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X