Эффективный способ непрерывного чтения данных из текстового файла - PullRequest
2 голосов
/ 29 июля 2010

У нас есть сценарий на конечной точке FTP, который отслеживает журналы FTP, израсходованные нашим демоном FTP.В настоящее время у нас есть сценарий perl, который по существу запускает хвост -F для файла и отправляет каждую строку в удаленную базу данных MySQL с немного отличающимся содержимым столбца в зависимости от типа записи.

В этой базе данных есть таблицыдля содержимого как имен / содержимого тарбола, так и действий пользователя FTP с указанными пакетами;Загрузка, удаление и все остальное в журналах VSFTPd.

Я считаю, что это особенно плохо, но я не уверен, что лучше.

Цель замены - по-прежнему получать содержимое файла журнала.в базу данных как можно быстрее.Я думаю сделать что-то вроде создания файла FIFO / pipe вместо того, где находится файл журнала FTP, поэтому я могу периодически читать его один раз, гарантируя, что я никогда не прочту одно и то же дважды.Предполагая, что VSFTPd хорошо с этим справится (я думаю, что это не так, понимание приветствуется!).

Демон FTP - VSFTPd, я, по крайней мере, достаточно уверен, что его возможности регистрации: xferжурнал стилей, журнал стилей vsftpd, и то, и другое, или вообще не ведение журнала.

Вопрос в том, что лучше того, что мы уже делаем, если что-нибудь?

Ответы [ 4 ]

3 голосов
/ 29 июля 2010

Честно говоря, я не вижу ничего плохого в том, что вы делаете сейчас.tail -f очень эффективно.Единственная реальная проблема заключается в том, что он теряет состояние, если ваш скрипт-наблюдатель когда-либо умирает (что является полужесткой проблемой, которую нужно решить с помощью ротационных лог-файлов).В CPAN также есть замечательный File :: Tail модуль, который избавляет вас от оболочки и имеет некоторые приятные настройки.

Использование FIFO в качестве журнала может работать(до тех пор, пока vsftpd не пытается отсоединить и воссоздать файл журнала в любой момент, что возможно), но я вижу в этом одну серьезную проблему.Если никто не читает с другого конца FIFO (например, если ваш скрипт вылетает или никогда не запускался), то через некоторое время все записи в FIFO начнут блокироваться.И я не проверял это, но вполне вероятно, что наличие блока записи в лог-файл приведет к зависанию всего сервера .Не очень красивый сценарий.

2 голосов
/ 21 марта 2011

Ваша проблема с чтением постоянно обновляемого файла заключается в том, что вы хотите продолжать чтение даже после достижения конца файла.Решением этой проблемы является повторный поиск вашей текущей позиции в файле:

поиск FILEHANDLE, 0, 1;

Вот мой код для выполнения таких действий:

open(FILEHANDLE,'<', '/var/log/file') || die 'Could not open log file';
seek(FILEHANDLE, 0, 2) || die 'Could not seek to end of log file';
for (;;) {
while (<FILEHANDLE>) {
    if ( $_ =~ /monitor status down/ ) {
            print "Gone down\n";
        }
    }
    sleep 1;
    seek FILEHANDLE, 0, 1;      # clear eof
}  
1 голос
/ 29 июля 2010

Вам следует изучить inotify (при условии, что вы работаете в хорошей ОС на основе posix), чтобы вы могли запускать свой Perl-скрипт всякий раз, когда обновляется файл журнала.Если этот уровень ввода-вывода вызывает проблемы, вы всегда можете сохранить файл журнала на RAM-диске, поэтому ввод-вывод очень быстрый.

Это должно помочь вам настроить это: http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/

0 голосов
/ 29 июля 2010

Вы можете открыть файл как в трубе.

open(my $file, '-|', '/ftp/file/path');

while (<$file>) {
    # you know the rest
}

File :: Tail делает это, плюс эвристический сон и хорошая обработка ошибок и восстановление.

Редактировать: Если подумать, реальный системный канал лучше, если вы можете им управлять.Если нет, вам нужно найти последнее, что вы положили в базу данных, и прокручивать файл, пока не дойдете до последнего, что вы положили в базу данных при каждом запуске процесса.Это не так просто сделать, и потенциально невозможно, если у вас нет возможности определить, где вы остановились.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...