Comment écrire un script qui fonctionne uniquement avec de nouvelles entrées de journal

Je pense que ça devrait être simple, mais c'est difficile pour moi de le comprendre.

J'essaie d'écrire un script qui suivra l'un des fichiers journaux apache et prendre certaines actions. Mais comment devrais-je suivre le fichier journal?

Chaque fois qu'une nouvelle ligne est écrite dans le journal, je souhaite que cette entrée soit vérifiée pour voir s'il correspond au fait que je cherche, et si oui, alors arrive. x. Quand je le fais manuellement, j'ai utilisé cat ou tail -f. Je ne veux pas courir le script tous les 30 Secondes à travers cron et parcourir tout le magazine (ou même le dernier 5 Rangée), Pour savoir laquelle de ces lignes est nouvelle depuis le dernier script de démarrage, puis certaines choses.

Y a-t-il un moyen de ne vérifier qu'un nouveau disque dans le journal?
Invité:

Christine

Confirmation de:

Vous pouvez utiliser des outils déjà disponibles. Linux, comme le

tail

,

grep

, et

named pipes

. D'abord créer un canal nommé (fifo), Utilisant:

$ mkfifo /tmp/myfifo

Deuxièmement, créez un script simple qui lira dans ce fichier. fifo. Voici un exemple simple:

#!/bin/bash
pipe=/tmp/myfifo

while true
do
if read line <$pipe; then
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line
fi
done
echo "Reader exiting"

Ce script lit à partir d'un canal nommé et affiche une chaîne à une sortie standard jusqu'à ce que le mot "EXIT" ne soit pas reçu. Ceci est juste un exemple qui peut être configuré.

Troisièmement, utilisez

tail

Pour lire de nouvelles lignes ajoutées au fichier journal apache, et redirige la sortie sur le canal nommé.

$ tail -n0 -F /var/log/apache2/access.log | grep some_text > /tmp/myfifo

DANS

-F

option signifie suivre le fichier nommé, que devrait le rendre immunisé pour logrotate. Ainsi, il suivra toujours le même nom de fichier. DANS

-n0

signifie ne pas avoir une ancienne chaîne. DANS

grep

Il est utile d'envoyer uniquement les lignes correspondantes.

Utilisation de cette solution, vous n'aurez besoin d'aucune tâche cron. Il suffit d'exécuter le script et la commande ci-dessus. tail.

Dominique

Confirmation de:

Exécutez votre script à travers cron, Mais en utilisant

logtail

ou
http://linux.die.net/man/8/logtail2
La lecture du fichier évitera de lire tout le fichier chaque minute. Logtail Des pistes où il a lu la dernière lecture et procède à ce point dans la prochaine utilisation.

Si vous voulez travailler avec de nouvelles lignes du magazine immédiatement, n'attendez pas 59 Secondes entre les appels cron, Vous devrez utiliser

tail -f

ou similaire.

Les deux réponses Janne et Halad résolvent bien ce problème.

Christine

Confirmation de:

si tu as

syslog-ng

(Probablement

rsyslogd

aussi approprié) comme syslog-daemon, Tu peux l'utiliser.

Il suffit de la configurer pour suivre le fichier journal. Apache, ou, comme alternative, configurez Apache Envoyer des magazines à l'outil syslog par

CustomLog

Directive I.

logger

.

Puis Syslog-daemon utilisera un exemple de mappage et effectuera $ foo, Si une coïncidence est trouvée. Par exemple, dans syslog-ng Vous pouvez configurer l'interception du fichier journal et le filtrer comme suit:

source apache_log { file("/var/log/apache2/access.log"); };
filter apache_match { match("GET /evilscript.php"); };

Puis syslog-ng Provoque un script externe

destination apache_logmatch_script { program("/usr/local/bin/apachematch.pl"); };

Enfin, rassemblez tout cela ensemble:

log { source(apache_log); filter(apache_match); destination apache_logmatch_script); };

Si vous utilisez cette technique, syslog-ng Créez le fond de votre script, en attente de l'apparition d'un nouveau matériau. Pour cette raison, vous devez modifier vos scénarios pour vous attendre à l'entrée de STDIN; Voici un petit exemple Perl:

#!/usr/bin/perl -w

$|=1;
while (<>) {
printf "Stuff happened, I got this entry: %s!\n", $_;
}

Je ne vais pas approfondir dans ma réponse avant de savoir ce que vous voulez essayer cette technique.

Alice

Confirmation de:

Vous pouvez enregistrer la dernière chaîne de lecture. Chaque nouveau départ à lire depuis le dernier + 1 Rangées jusqu'à la fin du fichier et mettre à jour l'enregistrement.

Mais gardez à l'esprit que le fichier journal peut être tourné. Donc, vous devez enregistrer, tels que des chiffres inode.

http://www.fail2ban.org/wiki/index.php/Main_Page
Surveille les fichiers journaux comme vous le pensez. Peut jeter un coup d'oeil à ça? Vous pouvez emprunter des idées ou les utiliser.

Catherine

Confirmation de:

vous pouvez utiliser diff. Copiez le fichier journal dans un fichier temporaire.

Faites la différence entre le fichier journal en direct et le fichier temporaire.

Exécuter le mappage d'échantillon pour le fichier reçu diff.

L'idée est prise du plugin nagios check_log. Voir
http://www.kilala.nl/Sysadmin/index.php?id=715
Plus de détails.

Blanche

Confirmation de:

Si un fail2ban Ne convient pas à vos besoins, vous pouvez essayer de changer
http://pastebin.com/8hxSmTCE
Qui a écrit Marcus J. Ranum:

"Ce petit utilitaire effectue l'analogue" tail -f », Mais suffisamment intelligemment pour traiter le changement de fichiers, si le Rotateur de magazine déplace le fichier sous l'utilisateur pendant le fonctionnement. De plus, contrairement à " tail -f »Ce programme suffit à sortir lorsque l'utilisateur sort du système (!), et ne va pas éruption de magazines sur pty pour toujours et à jamais. Aucun effort n'est attaché pour l'élégance ou la performance ".

Vous pouvez modifier pour vérifier si une nouvelle chaîne correspond au modèle souhaité et agissez en conséquence.

Christine

Confirmation de:

Si vous avez besoin d'une solution pour Python, Essayer Pygtail:
https://github.com/bgreenlee/pygtail
C'est basé sur

logcheck

de

logtail2

outil

Giselle

Confirmation de:

#!/bin/bash

while read line;
do
echo $line > /tmp/output.log
mail -s 'Event Msg.' 'email@gmail.com' < /tmp/output.log
done < <(tail -n0 -F /var/adm/messages)

Pour répondre aux questions, connectez-vous ou registre