Saturday, January 24, 2009

Perl - simple log-filter script

Lets say we are having a log file in the following format (/var/log/messages format):
Jan 25 00:08:33 localhost kernel: imklog 3.21.9, log source = /proc/kmsg started.
Jan 25 00:08:33 localhost rsyslogd: [origin software="rsyslogd" swVersion="3.21.9" ] restart

Here how to write a simple perl script which will print the log file using a filter (in this sample I will filter the file by its modules : kernel, rsyslogd).

Script start:

#!/usr/bin/perl

# Log file name
$FILE_NAME="messages.txt";

sub read_from_file()
{
# The first (and only) parameter in the module filter string
$MODULE_FILTER=$_[0];

# Open the file for reading, if cannot - exit
open (FHANDLE, "< ${FILE_NAME} ") || die "couldn't open the ${FILE_NAME} file!";

# Reading the file
while ()
{
# Parse the line into its parts using regular expressions
($date,$hostname,$module,$msg) = /^(.+?\s.+?\s.+?\s)(.+?\s)(.+?:\s)(.*)/;
# If ((the filter is not "ANY") and ( current line do not match the filter, in this sample - ignore case)) skip current line
unless (( ${MODULE_FILTER} eq "ANY" ) || ( ${module} =~ /${MODULE_FILTER}/i ))
{
next;
}
# print current line
print $_;
}
# close file handle
close ${FHANDLE}
}

##########################################################
## Main
#&read_from_file("ANY");
#&read_from_file("KERNEL");
Script End;

If I'm calling the subroutine with the "ALL" filter, I will see all the file.
If I will call with the "KERNEL" filter, I will only see the first line.


No comments: