parse-Protokolldatei mit schwerer Ausgabe

Ich möchte meine vsftpd-Protokolle überwachen und Informationen aus den Protokollen abrufen, um die hochgeladenen Dateien zu verarbeiten. Bis jetzt war alles großartig und hat gut funktioniert:

tail -n0 -F /var/log/vsftpd.log | while read line; do
    if echo "$line" | grep -q 'OK UPLOAD:'; then
        #do a bunch of processing stuff - this takes some time
    fi
done

Ich habe angefangen, Skalentests durchzuführen und 500 Dateien gleichzeitig hochgeladen. Aus irgendeinem Grund fehlen die Protokollzeilen oder sie werden abgeschnitten, wenn Sie so viele Dinge hochladen. Zum Beispiel sieht eine typische Zeile wie folgt aus:

Sun Apr 7 09:08:51 2013 [pid 25409] [cam02430] OK UPLOAD: Client "206.132.183.201", "/20130407/09/20130407_090842D.avi", 531792 bytes, 426.14Kbyte/sec

Aber manchmal sieht die Zeile so aus (wenn sie nicht fehlt vollständig):

:08:51 2013 [pid 25409] [cam02430] OK UPLOAD: Client "206.132.183.201", "/20130407/09/20130407_090842D.avi", 531792 bytes, 426.14Kbyte/sec

Es schneidet die ersten Zeichen des Protokolls ab. Es tut es nicht für jede Zeile, aber die meisten. Auch viele Zeilen fehlen einfach. Ich denke, ich habe einen Rennzustand meiner Verarbeitung, der nicht rechtzeitig beendet wird. Wie kann ich das umgehen?

BEARBEITEN Ich denke, ich habe 3 Optionen:

  1. Verwenden Sie tail nicht und versuchen Sie, eine Kombination von Dingen wie einen Cron-Job/grep zu verwenden, um das Protokoll auf einen neuen Eintrag zu überprüfen. Ich stelle mir vor, das könnte schwierig sein. Wie mache ich sagen Sie, was in diesem Protokoll neu ist?

  2. Überwachen Sie die Dateiänderung mit monit oder gleichwertig. Ich glaube nicht, dass dies eine Option ist. Die Dateien werden in etwas zufälligen Verzeichnissen mit Dateinamen gespeichert, die zeitstempelt sind.

  3. Logstash oder gleichwertig. Ich glaube nicht, dass diese Programme meinen Bedürfnissen entsprechen. Aber vielleicht weiß jemand anders.

Im Moment konzentriere ich mich auf #1 ohne gute Hinweise. Also alle Gedanken zu irgendetwas davon wären dankbar.

Author: Tom, 2013-04-12

4 answers

Sie können verhindern, dass ein "Grep" - Prozess für jede Zeile im Protokoll gegabelt wird, indem Sie Ihren Code wie folgt umschreiben:

tail -n0 -F /var/log/vsftpd.log | grep 'OK UPLOAD:' | while read line ; do
        #do a bunch of processing stuff - this takes some time
done

Aber ich stimme anderen Postern zu, Shell ist nicht wirklich für schwere Text - /Zeichenfolgenmanipulationen geeignet. Sie sollten in Betracht ziehen, eine andere Skriptengine zu verwenden (zumindest awk oder besser Perl oder Python)

 1
Author: Gilles Pion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2013-04-16 15:46:29

Ich hatte gute Erfahrungen mit Perl mit den Optionen file open'

Z. B.https://stackoverflow.com/questions/1425223/how-do-i-read-a-file-which-is-constantly-updating

 1
Author: epoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2017-05-23 12:41:38

Wie @epoon schlug, Perl könnte eine gute Wahl:

#!/usr/bin/env perl

open(FH,'<',$ARGV[0]) || die("Could not open file $ARGV[0]\n");
for (;;) {
    while (<FH>) {
    if (/OK UPLOAD/) { ## this is where you do your processing. As an example, 
                       ## I am collecting the file's info
        /^(.+?)\s*\[pid\s*(\d+).+?\"([\d\.]+).+?\"(.+?)\".+?(\d+).+?\s([^\s]+)/;
        my ($date,$pid,$client,$filename,$size,$rate) = ($1,$2,$3,$4,$5,$6);
        print "On $date, process $pid uploaded file \"$filename\" of $size bytes from $client at $rate\n"

    }
    }
    # eof reached on FH, but wait a second and maybe there will be more output
    sleep 1;
    seek FH, 0, 1;      # this clears the eof flag on FH
}

Das Ausführen dieses Skripts auf /var/log/vsftpd.log sollte eine Ausgabe wie

On Sat Apr 20 16:30:05 CEST 2013, process 25409 uploaded file "/20130407/09/20130407_090842D.avi" of 531792 bytes from 206.132.183.201 at 426.14Kbyte/sec

Ich würde dies gerne aktualisieren, wenn Sie angeben, was genau Sie mit den Protokollinformationen tun möchten.

 1
Author: terdon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2017-03-20 10:17:32

Haben Sie versucht, die Option --line-buffered für grep zu verwenden?

tail -f /var/log/vsftpd.log | grep --line-buffered 'OK UPLOAD:' | while read line ; do
        #do a bunch of processing stuff - this takes some time
done
 0
Author: devnull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2013-04-18 14:59:11