файл журналу розбору з великим виходом


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

Це обрізання перших кількох символів журналу. Це не для кожного рядка, але більшість. Також багато рядків просто відсутні. Я здогадуюсь, я не передушив час перегону, коли обробка моєї обробки не закінчується. Як я можу обійти це?

EDIT Я думаю, у мене є 3 варіанти:

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

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

  3. logstash або ін. Я не думаю, що ці програми відповідають моїм потребам. Але, можливо, хтось знає інакше.

Зараз я зосереджуюсь на №1 без хороших результатів. Тож будь-які думки з цього приводу були б вдячні.


Я нічого не знаю про поведінку журналу vsftpd, але ви могли б (якщо жодного нового підкаталогу не створюється регулярно в дереві каталогів, яке ви заповнюєте за допомогою ftp-процесу), використовуйте inotifywait за допомогою циклу for-петлі, щоб перейти на закінчені файли (ну, писати / colse events_.
Дзинь

Інтенсивна обробка журналу не повинна здійснюватися за допомогою скриптів оболонки, я б пішов на формат журналу JSON + logstash / elastsearch / kibana / statsd / graphite
dawud

@tink Я вважав, що коли я розпочав цей проект, але не було зрозуміло, наскільки добре він буде обробляти близькі події (успішне завантаження), а файли зберігаються в нових підкаталогах, які завжди змінюються відповідно до дати. Ця частина поза моїм контролем.
Том

@Tom Коли персонаж відрізається, чи можете ви переконатись, що він відрізає лише символи конкретного рядка або у вас фактично відсутні декілька рядків між ними.
Джон Сіу

@JohnSiu Насправді також відсутні рядки.
Том

Відповіді:


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

Як запропонував @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

Я б радий оновити це, якщо ви вкажете, що саме ви хочете зробити з інформацією журналу.


Я думаю, це може спрацювати, але я в будь-якому випадку пішов іншим маршрутом. Я написав api-повідомлення у vsftpd. Це гарантує завершення. +1 для деталей. Дякую.
Том

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

Так, я дякую. Але не везіння, та сама проблема.
Том
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.