Skip to content

Instantly share code, notes, and snippets.

@bjdean
Last active December 18, 2015 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjdean/5726807 to your computer and use it in GitHub Desktop.
Save bjdean/5726807 to your computer and use it in GitHub Desktop.
quick filter of apache logs to show specific fields
#!/usr/bin/perl
# filter_apache_log.pl - quick filter of apache logs to show specific fields
# Copyright (C) 2008 Bradley Dean <bjdean@bjdean.id.au>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# A simple script - only combined log format implemented at this point
# allows specific fields from an apache log (or any log with extension
# of the code) to be viewed.
#
# The script filters out some lines (eg blank lines), passes through some
# lines (eg the filename lines from a multi-file tail) and will abort
# with any unknown line (so that you know to handle/skip/pass-through those
# lines)
#
# Example usage: Look at IPs and User-Agents
#
# $ tail -f /var/log/apache/*access*log | filter_apache_log.pl -ip -useragent
#
# Also here: http://bjdean.id.au/wiki/Programming_Notes/PerlProgramming/ApacheLogFilter
#
use strict;
use warnings;
use Getopt::Long;
use IO::Handle;
# No buffering output
autoflush STDOUT 1;
# commmand line arguments
my $show_all;
my (
$show_ip, $show_ident, $show_user, $show_date, $show_path, $show_response,
$show_size, $show_referrer, $show_useragent
);
my $result = GetOptions(
"ip" => \$show_ip,
"ident" => \$show_ident,
"user" => \$show_user,
"date" => \$show_date,
"path" => \$show_path,
"response" => \$show_response,
"size" => \$show_size,
"referrer" => \$show_referrer,
"useragent" => \$show_useragent,
"all" => \$show_all,
) or die;
# Read and filter
LINE:
while ( my $line = <STDIN> ) {
# Special lines - pass through
if (
# tail -f file names
$line =~ /^==>.*<==$/
) {
print $line;
next LINE;
}
# Special lines - skip
if (
# empty lines
$line =~ /^\s*$/
) {
next LINE;
}
# Apache line formats
my ($ip, $ident, $user, $date, $path, $response, $size, $referrer, $useragent);
if ( my @match = $line =~ /
^\s*
([0-9\.]+)\s # ip
(\S+)\s # ident
(\S+)\s # user
(\[.*?\])\s+ # date
(".*?")\s+ # path
(\S+)\s+ # response
(\S+)\s+ # size
(".*?")\s+ # referrer
(".*?") # user-agent
/x ) {
($ip, $ident, $user, $date, $path, $response, $size, $referrer, $useragent) = @match;
my $line = "";
$line .= fmt_val($ip) if ( $show_all || $show_ip );
$line .= fmt_val($ident) if ( $show_all || $show_ident );
$line .= fmt_val($user) if ( $show_all || $show_user );
$line .= fmt_val($date) if ( $show_all || $show_date );
$line .= fmt_val($path) if ( $show_all || $show_path );
$line .= fmt_val($response) if ( $show_all || $show_response );
$line .= fmt_val($size) if ( $show_all || $show_size );
$line .= fmt_val($referrer) if ( $referrer ne '"-"' ) && ( $show_all || $show_referrer );
$line .= fmt_val($useragent) if ( $show_all || $show_useragent );
print "${line}\n" if ( $line =~ /\S/ );
next LINE;
}
else {
die "Unmatched log line: ${line}";
}
}
sub fmt_val {
my ($val) = @_;
if ( $val ) {
return "${val} "
}
else {
return " ";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment