1

Я хотел бы отслеживать мои журналы vsftpd и извлекать информацию из журналов для обработки загруженных файлов. До сих пор все было отлично и работало нормально:

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

Я начал проводить масштабное тестирование и загрузил сразу 500 файлов. По какой-то причине строки журнала отсутствуют или они обрезаются, когда вы загружаете так много вещей. Например, типичная строка выглядит так:

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

Но иногда строка выглядит так (если не отсутствует полностью):

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

Это отрезает первые несколько символов журнала. Он делает это не для каждой строки, а для большинства. Также многие строки просто отсутствуют. Я предполагаю, что у меня есть состояние гонки, когда моя обработка не заканчивается вовремя. Как я могу обойти это?

РЕДАКТИРОВАТЬ Я думаю, у меня есть 3 варианта:

  1. Не используйте tail и попробуйте использовать сочетание таких вещей, как cron job/grep, чтобы проверить журнал на наличие новой записи. Я думаю, что это может быть сложно. Как мне узнать, что нового в этом журнале?

  2. Контролируйте изменение файла с помощью monit или эквивалентного. Я не верю, что это вариант. Файлы хранятся в несколько случайных каталогов с именами файлов с отметкой времени.

  3. logstash или эквивалентный Я не думаю, что эти программы соответствуют моим потребностям. Но, может быть, кто-то знает иначе.

Прямо сейчас я сосредотачиваюсь на # 1 без хороших потенциальных клиентов. Так что любые мысли по этому поводу будут оценены.

4 ответа4

1

Вы можете запретить разветвление процесса "grep" для каждой строки в журнале, переписав код следующим образом:

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

Но я согласен с другими постерами, оболочка не очень подходит для тяжелых текстовых / строковых манипуляций. Вы должны рассмотреть возможность использования другого скриптового движка (по крайней мере, awk или лучше perl или python)

1

У меня был хороший опыт работы с Perl с использованием параметров открытия файла «<», если вы хотите ограничить только сценарии оболочки.

например, https://stackoverflow.com/questions/1425223/how-do-i-read-a-file-which-is-constantly-updating

1

Как подсказал @epoon, Perl может быть хорошим выбором:

#!/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
}

Выполнение этого скрипта в /var/log/vsftpd.log должно привести к выводу

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

Я был бы рад обновить это, если вы укажете, что именно вы хотите сделать с информацией журнала.

0

Вы пытались использовать --line-buffered для grep?

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .