J'ai une application qui doit enregistrer chaque transaction. Chaque message de journal est vidé car nous devons avoir un enregistrement de ce qui s'est produit avant un crash. Mes collègues et moi étions curieux de savoir comment obtenir les effets de mise en mémoire tampon sur les performances tout en garantissant que le message du journal avait quitté le processus.
Ce que nous avons trouvé est:
- créer un FIFO sur lequel l'application peut écrire, et
- rediriger le contenu de cette FIFO vers un fichier standard via
cat
.
Autrement dit, ce qui était ordinairement:
app --logfile logfile.txt
est maintenant:
mkfifo logfifo
cat logfifo &> logfile.txt &
app --logfile logfifo
Y a-t-il des pièges à cette approche? 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 d'origine se bloque.
(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 stdout
, donc il syslog
n'est pas possible de diriger directement vers une autre commande. Il n'est donc pas possible .)
Mise à jour: j'ai ajouté une prime. La réponse acceptée n'impliquera paslogger
pour la simple raison que ce logger
n'est pas ce que j'ai demandé. Comme l'indique la question d'origine, je ne cherche que des pièges en utilisant un FIFO.
Réponses:
Notez qu'un fifo est généralement nécessaire dans la programmation où le montant écrit peut dépasser le montant lu.
En tant que tel, le fifo ne fonctionnera pas de manière parfaitement fluide comme vous le prévoyez mais résoudrait votre problème principal tout en en introduisant un autre.
Il y a trois mises en garde possibles.
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 (qui sera vraisemblablement mis en mémoire tampon d'E / S).
Néanmoins, l'écrivain dépend de votre lecteur de journaux pour fonctionner. Si le lecteur arrête soudainement la lecture, l'écrivain se bloque. Si le lecteur se ferme soudainement (disons que vous manquez d'espace disque sur votre cible), le graveur SIGPIPE et probablement se fermera.
Un autre point à mentionner est que si le serveur panique et que le noyau cesse de répondre, vous risquez de perdre jusqu'à 64 Ko de données qui étaient dans ce tampon.
Une autre façon de résoudre ce problème sera d'écrire des journaux dans tmpfs (/ dev / shm sous linux) et de limiter la sortie à un emplacement de disque fixe. Il existe des limites moins restrictives sur l'allocation de mémoire pour ce faire (pas 64 Ko, généralement 2 G!), Mais pourrait ne pas fonctionner pour vous si le rédacteur n'a aucun moyen dynamique de rouvrir les fichiers journaux (vous devrez nettoyer régulièrement les journaux de tmpfs). Si le serveur panique dans cette méthode, vous pourriez perdre BEAUCOUP plus de données.
la source
/dev/shm
. Nous avions également envisagé cela, même si cela m'avait glissé l'esprittail -f
.Que se passe-t-il lorsque votre
cat logfifo
processus meurt, que quelqu'un le tue par accident ou que quelqu'un le pointe accidentellement au mauvais endroit?D'après mon expérience, la
app
volonté se bloque et se bloque rapidement. 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 enquêté très loin, carlogger
une simple redirection d'E / S a fait ce que je voulais. Je n'ai généralement pas besoin de l'exhaustivité de la journalisation, c'est ce que vous essayez de poursuivre. Et comme vous le dites, vous ne voulez pas d'enregistreur.Il y a une discussion sur ce problème à Linux non bloquant fifo (journalisation à la demande) .
la source
Vos options sont assez limitées par l'application, mais ce que vous avez testé fonctionnera.
Nous faisons quelque chose de similaire avec vernis et varnishncsa aux journaux get quelque part qui nous sont utiles. Nous avons un fifo et lisons-le avec syslog-ng et l'envoyons où nous en avons besoin. Nous gérons environ 50 Go et n'avons rencontré aucun problème avec cette approche jusqu'à présent.
la source
L'environnement est CentOS et l'application écrit dans un fichier ...
Au lieu d'envoyer dans un fichier normal, j'enverrais la sortie vers syslog et m'assurer que les messages syslog sont envoyés à un serveur central ainsi que localement.
Vous devriez pouvoir utiliser un script shell comme celui-ci:
Vous pouvez également prendre des entrées (vers
logger
) depuiscat
ou depuistail -f
un tuyau:Le seul problème est qu'il ne se différencie pas en fonction de l'importance du message de journal (tout est AVIS ) mais au moins il est enregistré et également envoyé hors hôte vers un serveur central.
La configuration de syslog dépend du serveur que vous utilisez. Il y a
rsyslog
etsyslog-ng
(tous deux très capables).EDIT : Révisé après avoir obtenu plus d'informations de l'affiche.
la source
stdout
. Le système d'exploitation est CentOS (j'avais marqué la question sous Linux , mais je suppose que c'est facile à manquer). Tous les messages sont d'égale importance, il n'y a donc pas de différence entre un avis et une erreur dans cette application.Slow query detected
etDatabase halted
?Vous écrivez:
Avez-vous essayé de vous connecter au "fichier"
/dev/stdout
? Cela pourrait vous permettre de faire quelque chose comme:la source
Il ne sert à rien d'écrire dans un fifo et de demander à un autre processus de l'écrire dans un fichier. Il suffit d'écrire directement dans le fichier normalement et une fois le
write()
retour effectué, il est entre les mains du noyau; il l'écrira toujours sur le disque si l'application plante.la source
fsync()
pour attendre que chaque écriture atteigne le disque, et vous NE VOULEZ PAS que cela se produise (risque de perte en cas de panne du système)?write()
est revenu, l'application peut planter tout ce qu'elle aime - les données arriveront sur le disque tant que le noyau ne plantera pas.