Модуль perl File ::Tail хорош для такого рода задач. Он может быть доступен предварительно -упакованным для вашего дистрибутива (, например. о Debian и его производных,sudo apt-get install libfile-tail-perl
)
напр.
#!/usr/bin/perl
use strict;
use File::Tail;
my $dir='/mnt/zandrologs';
# Get the list of logfiles in the target directory
my @logfiles = glob("$dir/*");
# Set up an array of File::Tail objects, one for each filename.
my @logs=();
foreach (@logfiles) {
push(@logs,File::Tail->new(name => $_));
}
# Now watch those logs and do stuff when the script sees matching patterns
while (1) {
my ($nfound,$timeleft,@pending)= File::Tail::select(undef,undef,undef,undef,@logs);
if ($nfound) {
foreach my $input (@pending) {
# read the line of data from the current File::Tail object into $_
$_ = $input->read;
chomp;
# Get the filename of the current File::Tail object.
# This script doesn't use it, so it's commented out.
# my $fn = $input->{'input'};
if (m/somestring/) {
# do stuff here
# any perl code, including executing external programs with system().
} elsif (m/somestring2/) {
# do different stuff here
} elsif (m/somestring3/) {
# and more different stuff
} elsif (m/somestring999/) {
# yet more different stuff
}
}
}
};
Это зациклит файлы журнала навсегда (или до тех пор, пока не будет уничтожено ). Если какой-либо из входных файлов повернут, File::Tail
автоматически закроется и повторно -откроет файл (, т.е. аналогично tail -F
).
При наличии новых данных в одном или нескольких журналах метод File::Tail::select()
возвращает:
$nfound
-количество найденных объектов File ::Tail с ожидающими обработки данными (, т. е. количество элементов в массиве @pending
). $timeleft
-время, оставшееся до истечения времени ожидания select()
, но этот скрипт не передал значение тайм-аута в select
(, он просто передал undef
для всего, кроме массива @logs
. @pending
-массив объектов File ::Tail с новыми непрочитанными данными Каждый элемент @pending
представляет собой объект File ::Tail с различными методами (, например. read()
, который возвращает строку текста, ожидающую для этого объекта ), и хеш-ключи (, например. {'input'}
с именем файла ).
Подробнее см. man File::Tail
и perldoc -f select
.
Как написано, сценарий будет игнорировать все строки в файле, существовавшие до запуска этого сценария. Вы можете изменить это, чтобы начать чтение либо последних n строк, либо даже всего файла с самого начала, изменив эту строку:
push(@logs,File::Tail->new(name => $_));
От
до (начните с чтения последних 10 строк в файлах журнала):
push(@logs,File::Tail->new(name => $_, tail => 10));
или (начните с чтения всех файлов журнала с начала):
push(@logs,File::Tail->new(name => $_, tail => -1));
Это эффективное, но простое использование модуля. См. man File::Tail
для получения более подробной информации и альтернативных способов его использования. Модуль также поставляется с несколькими хорошими примерами скриптов.
PS :Я много лет пользовался этим модулем. например.Раньше я поддерживал свой собственный скрипт, используя File::Tail
в 1990-х, чтобы вызывать ipchains
для автоматической блокировки IP-адресов, пытающихся делать плохие вещи. Затем появился fail2ban
, и я переключился на его использование. Я до сих пор использую его для сценариев мониторинга журнала -.