Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > обработка огромного лога


Автор: afybc 7.11.2008, 17:39
Syslog пишет лог в файл. Этот файл имеет огромный размер. Мне нужно написать скрипт который будет висеть в кроне, парсить этот лог и добавлять новые записи в базу. Как мне сделать так, чтобы не модифицировать лог и при этом не парсить его с самого начала?

Автор: ginnie 7.11.2008, 17:54
afybc, надо сохранять позицию (полученную вызовом tell()), до которой скрипт дошел при очередной обработке, в "удобном месте". При старте скрипта считывать это значение и перемещать текущий указатель для файлового дескриптора лога при помощи seek().

Автор: afybc 7.11.2008, 20:12
Спасибо, думал об этом, но кроме базы больше нигде не могу сохранять. А использовать БД для переменной как-то не особо хочется. Если не ошибаюсь в perl'e есть возможность сохранять переменные в теле скрипта? Если я прав, то подскажите как.

Автор: ginnie 7.11.2008, 20:29
afybc, а в файл никак нельзя?

Автор: afybc 7.11.2008, 20:51
Можно, но хочется узнать именно про возможность сохранения в теле скрипта, если она конечно же существует.

Автор: afybc 8.11.2008, 11:12
Нашел как.

Use the __DATA__ or __END__ tokens after your program code to mark the start of a data block, which can be read inside your program or module from the DATA filehandle.

Код

# Use __DATA__ within a module:

while (<DATA>) {
    # process the line
}
__DATA__
# your data goes here

# Similarly, use __END__ within the main program file:

while (<main::DATA>) {
    # process the line
}
__END__
# your data goes here


Автор: sir_nuf_nuf 8.11.2008, 13:26
afybc, ну и что вы этим добьетесь ?
вы можете оттуда прочитать переменную.
но записать туда что - то вы не сможите. точнее это не сохранится.

Так что - пишите в файл! назовите мне причину по которой вы не сможете писать в файл ? 

Автор: amg 8.11.2008, 13:47
Цитата(sir_nuf_nuf @  8.11.2008,  13:26 Найти цитируемый пост)
назовите мне причину по которой вы не сможете писать в файл ?
Я тоже не вижу веских причин. Хранение в отдельном файле лучше со всех точек зрения. Но технически не сложно организовать хранение и в теле скрипта, причем где именно -- особой роли не играет. Но пусть будет в блоке __DATA__:
Код
use Fcntl ':flock';

my $log = './file.log';

open LOG, '<', $log or die "Can't open $log: $!\n";
flock(LOG,LOCK_EX);

my $pos = 0;

$pos = do {chomp; $_} while <DATA>;

seek LOG, $pos, 0 if $pos <= -s $log;

while (<LOG>) {
  print;
}

$pos = tell LOG;
flock(LOG,LOCK_UN);
close LOG;

exec qw(perl -0777 -i -pe), 's/$/\n'.$pos.'/', $0;

__DATA__
0
Этот скрипт после каждого вызова дописывает себе в конец строку с последней позицией лог-файла, и чтение его начинает с этой позиции. Как быть, если сторонняя программа (например, logrotate) изменит лог-файл -- другой вопрос. Минимальная защита в предлагаемом скрипте предусмотрена -- если сохраненная позиция оказывается больше размера лога, то чтение начнется с начала.

Автор: afybc 28.11.2008, 11:45
Спасибо, amg. Воспользовался Вашим решением.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)