#!/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 handlesobjects, 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
}
}
}
};
This will loop over the log files forever (or until killed). If any of the input files are rotated, File::Tail will automatically close and re-open the file (i.e. similar to tail -F). As
When there is new data in one or more of the logs, the File::Tail::select() method returns:
$nfound- the number of File::Tail objects found with data pending (i.e. the number of elements in the@pendingarray).$timeleft- the time remaining until theselect()timed out, but this script didn't pass a timeout value toselect(it just passedundeffor everything except the@logsarray.@pending- an array of File::Tail objects with new, unread data
Each element of @pending is a File::Tail object with various methods (e.g. read() which returns the line of text pending for that object) and hash keys (e.g. {'input'} containing the filename).
See man File::Tail and perldoc -f select for details.
As written, the script will ignore any lines in the file that existed before this script started. You can change that to start by reading either the last n lines or even the entire file from the start by changing this line: