This repository has been archived on 2026-05-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
netutils/logger

199 lines
5.4 KiB
Plaintext
Raw Permalink Normal View History

2026-05-18 12:43:29 -04:00
#!/usr/bin/perl -w
#extract lines in a given date range from an xchat logfile
#is a bit too hardcoded to be translated to other clients (gaim, etc)
#sorry! Future update will see this more modular.
use Getopt::Std;
use strict;
#extractDate(\%hash, $line)
#extract the contents of the date in line and put it in a hash
#(hash is keyed by month, day, hour, minute, second)
sub extractDate;
#buildRegex($line)
#build a regex from an input string of the form MM HH MM:SS:DD and return it
sub buildRegex;
my %args;
my $buffer;
#regexes for quick and easy pattern matching
my $startregex;
my $endregex;
#start and end date hashes for more complex range matching
my %startdate;
my %enddate;
# additional regex to check for in lines of output
my $addlRegex = ".*";
#Yeah this is a bit hackish. Whaddya want from me? This is, like, my second perl script.
my %monthvals = (
Jan => 0,
Feb => 1,
Mar => 2,
Apr => 3,
May => 4,
Jun => 5,
Jul => 6,
Aug => 7,
Sep => 8,
Oct => 9,
Nov => 10,
Dec => 11,
jan => 0,
feb => 1,
mar => 2,
apr => 3,
may => 4,
jun => 5,
jul => 6,
aug => 7,
sep => 8,
oct => 9,
nov => 10,
dec => 11,
);
my $help;
$help = <<EOT;
logger: filter X-Chat 2 log files by date
logger <options> inputfile
-h : this help
-s : Starting date
-e : Ending date
-r : Further restrict the search to lines matching this regex (search, not replace)
inputfile defaults to stdin if no file provided
Dates are expected in "Month Day Hour:Minute:Second" format. Months
are abbreviated to 3 letters, non-case sensitive. You must provide
AT LEAST one regex. (If one is missing, then it is assumed that both -s
and -e are equal.)
To search for all lines on the 13th of May:
logger -s "May 13 *:*:*" xchatlogfile
To search for all lines between the 13th of May and the 20th of June:
logger -s "May 13 *:*:*" -e "Jun 20 *:*:*" xchatlogfile
To search for all lines written between 5 and 10 pm in the entire log:
logger -s "* * 17:*:*" -e "* * 22:*:*" xchatlogfile
As above, but only match lines containing "somenick"
logger -s "* * 17:*:*" -e "* * 22:*:*" -r somenick xchatlogfile
EOT
getopt ( "hxs:e:f:r:", \%args );
# there's quite a bit of redundancy in the argument checking. Sue me.
if ( $args{h} ) {
print $help;
exit;
}
if ( $args{r} ) {
$addlRegex = $args{r};
}
if ( $args{s} ) {
$startregex = buildRegex($args{s});
extractDate(\%startdate, $args{s});
}
if ( $args{e} ) {
$endregex = buildRegex($args{e});
extractDate(\%enddate, $args{e});
}
if ( !$args{e} && !$args{s} ) {
print $help;
exit;
}
elsif ( !$args{e} || !$args{s} ) {
if ( $args{s} ) {
$endregex = $startregex;
extractDate(\%enddate, $args{s});
}
elsif ( $args{e} ) {
$startregex = $endregex;
extractDate(\%startdate, $args{e});
}
}
while ( <> ) {
my $toPrint;
if ( $_ =~ m/^\*\*\*\*/i || $_ =~ m/^\s*\n/i ) {
# this is a xchat log status line (effectively a comment for our purpose)
next;
}
if ( $_ =~ m/$startregex/i ||
$_ =~ m/$endregex/i ) {
$toPrint = $_;
}
else {
# not lucky enough for an exact match ... check the date
my %linedate;
extractDate(\%linedate, $_);
# check the dates to see if the date in the line is between startdate
# and end date
if ( !($enddate{month} eq "*") &&
$monthvals{$linedate{month}} <= $monthvals{$enddate{month}} &&
$monthvals{$linedate{month}} >= $monthvals{$startdate{month}} ) {
if ( !($enddate{day} eq "*") &&
$linedate{day} <= $enddate{day} &&
$linedate{day} >= $startdate{day} ) {
if ( !($enddate{hour} eq "*") &&
$linedate{hour} <= $enddate{hour} &&
$linedate{hour} >= $startdate{hour} ) {
if (!($enddate{minute} eq "*") &&
$linedate{minute} <= $enddate{minute} &&
$linedate{minute} >= $startdate{minute} ) {
if (!($enddate{second} eq "*") &&
$linedate{second} <= $enddate{second} &&
$linedate{second} >= $enddate{second} ) {
$toPrint = $_;
}
}
}
}
}
}
if ( $toPrint && ($toPrint =~ m/$addlRegex/) ) {
print $toPrint;
}
}
sub buildRegex {
my $orig = shift;
# make sure to not muck up the original
my $regex = $orig;
$regex =~ s/\s/\\s/g;
$regex =~ s/\*/\.\*/g;
return $regex;
}
sub extractDate {
my $finalDate = shift; #expects a reference to a hash
my $buff = shift; #expects a line of text from the logfile
#expects buff in the form MM DD HH:MM:SS
my @date = split " ", $buff;
my @time = split ":", $buff;
$time[0] =~ s/$date[0]\s$date[1]\s//;
$finalDate->{month} = $date[0];
$finalDate->{day} = $date[1];
$finalDate->{hour} = $time[0];
$finalDate->{minute} = $time[1];
my @splitline = split " ", $time[2];
$finalDate->{second} = $splitline[0];
}