summaryrefslogtreecommitdiff
path: root/parselog
diff options
context:
space:
mode:
Diffstat (limited to 'parselog')
-rwxr-xr-xparselog217
1 files changed, 217 insertions, 0 deletions
diff --git a/parselog b/parselog
new file mode 100755
index 0000000..9a7f00e
--- /dev/null
+++ b/parselog
@@ -0,0 +1,217 @@
+#!/usr/bin/perl -w
+#
+# parselog.pl v1.0.1
+#
+# Copyright (C)2000 Mark A. Bentley <bentlema@cs.umn.edu>
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+###############################################################################
+#
+# This file was last modified: July 26, 2000
+#
+# You can download the latest distribution from my web site:
+#
+# http://www.cs.umn.edu/~bentlema/projects
+#
+# For comments, suggestions, bug reports, or whatever, you may contact me
+# via email:
+#
+# Mark A. Bentley <bentlema@cs.umn.edu>
+#
+###############################################################################
+#
+#
+# DESCRIPTION
+#
+# This script is designed to accept log output from the Apache web server via
+# the CustomLog directive. It will create a directory for each virtual host's
+# logs, and will create a log file within this directory with the name based on
+# the year, month and day. When the day changes, yesturday's log files will be
+# closed, and new ones opened for today.
+#
+#
+# USAGE
+#
+# You will need to create a CustomLog entry in your httpd.conf in the global
+# section (not within a virtual host definition) like this:
+#
+# CustomLog "|/usr/local/bin/parselog" "[ %v %{%Y %m %d}t ] %h %l %u %t \"%r\" %s %b"
+#
+# The log formats definied within the brackets are absolutely necessary.
+# The %v will expand to the virtualhost name, and the %t (with its internal
+# format) will expand to the year, month, and day seperated by spaces. If you
+# change any of the values within these brackes, you will have to modify the
+# perl regular expression within the code below. The code will strip off these
+# brackets and everything within and write the remaining common log to the
+# appropriate directory and filename.
+#
+# This script will be fork/exec'ed with root perms if you've started apache as
+# root. To be safe you should specify the absolute path to parselog in your
+# CustomLog directive.
+#
+# You will also have to set the LOG_DIR in the configuration section below.
+#
+# This script will run with root privileges, so be careful if you decide to
+# make changes or add functionality.
+#
+
+#
+# Configuration
+#
+
+$LOG_DIR = "/var/log/apache";
+
+$INPUT_SRC = STDIN; # you shouldn't need to change this.
+
+$LOG_FILE_PERMS = 0664;
+$LOG_FILE_OWNER = "www-data";
+$LOG_FILE_GROUP = "www-data";
+$LOG_DIR_PERMS = 0775;
+$LOG_DIR_OWNER = "www-data";
+$LOG_DIR_GROUP = "www-data";
+
+$LOG_FILE_UID = ( getpwnam( $LOG_FILE_OWNER ))[2];
+$LOG_FILE_GID = ( getgrnam( $LOG_FILE_GROUP ))[2];
+$LOG_DIR_UID = ( getpwnam( $LOG_DIR_OWNER ))[2];
+$LOG_DIR_GID = ( getgrnam( $LOG_DIR_GROUP ))[2];
+
+#
+# Initialization
+#
+
+my %HOSTNAME = (); # hash of hostnames we've seen already
+my @OPEN_FH = (); # array of open filehandles for each hostname
+
+#
+# Support routines
+#
+
+sub flush { # Takes a filehandle
+ local($old) = select(shift);
+ $| = 1; print ""; $| = 0;
+ select($old);
+}
+
+sub makenote { # Takes a string;
+ $note = shift;
+ $mylocaltime = localtime(time());
+ print STDERR "[$mylocaltime] $0: ", $note, "\n";
+}
+
+#
+# Main loop
+#
+
+makenote("Starting up... PID: $$");
+makenote("INPUT_SRC = $INPUT_SRC");
+
+if ( -d $LOG_DIR ) {
+ makenote("LOG_DIR = $LOG_DIR");
+} else {
+ makenote("Fatal Error: $LOG_DIR does not exist!");
+ exit( 1 );
+}
+
+
+makenote("Log Directory: " .
+ "$LOG_DIR_OWNER($LOG_DIR_UID) " .
+ "$LOG_DIR_GROUP($LOG_DIR_GID) $LOG_DIR_PERMS");
+
+makenote("Log Files: " .
+ "$LOG_FILE_OWNER($LOG_FILE_UID) " .
+ "$LOG_FILE_GROUP($LOG_FILE_GID) $LOG_FILE_PERMS");
+
+$previous_day = "0";
+
+while( <$INPUT_SRC> ) {
+ m/^\[ (\S+) (\d+) (\d+) (\d+) \] (.*)/; # parse the log input here
+
+ $log_hostname = $1;
+ $log_year = $2;
+ $log_month = $3;
+ $log_day = $4;
+ $log_common = $5;
+
+ $log_pathname = "$LOG_DIR/$log_hostname";
+
+ #
+ # Did the day change?
+ #
+
+ if ( $log_day ne $previous_day ) {
+ makenote("Day change.");
+ %HOSTNAME = ();
+ makenote("HOSTNAME hash reset.");
+ makenote("OPEN_FH: $#OPEN_FH");
+ if ( $#OPEN_FH > 0 ) {
+ foreach $fh ( @OPEN_FH ) {
+ makenote("Closing $fh filehandle.");
+ close( $fh );
+ }
+ }
+ @OPEN_FH = ();
+ makenote("OPEN_FH array reset.");
+ }
+
+ #
+ # Have we seen this virtual host today?
+ #
+
+ if ( ! $HOSTNAME{$log_hostname} ) {
+
+ $HOSTNAME{$log_hostname} = 1; # mark host as seen
+
+ #
+ # create hostname directory within LOG_DIR
+ #
+
+ if ( ! -e $log_pathname ) {
+ makenote("mkdir: $log_pathname");
+ mkdir( $log_pathname, $LOG_DIR_PERMS );
+ chown( $LOG_DIR_UID, $LOG_DIR_GID, $log_pathname );
+ chmod( $LOG_DIR_PERMS, $log_pathname );
+ }
+
+ #
+ # open logfile named year.month.day for appending
+ # using $log_hostname as the filehandle name
+ #
+
+ my $current_log = "$log_pathname/$log_year.$log_month.$log_day";
+
+ makenote("open: $current_log");
+ open( $log_hostname, ">> $current_log");
+ chown( $LOG_FILE_UID, $LOG_FILE_GID, "$current_log" );
+ chmod( $LOG_FILE_PERMS, "$current_log" );
+
+ #
+ # maintain a list of open filehandles
+ #
+
+ push @OPEN_FH, $log_hostname;
+
+ }
+
+ #
+ # Write the log line to the appropriate log file. (Remember that
+ # the file handle name is the same as the hostname.)
+ #
+
+ print $log_hostname $log_common, "\n";
+ flush( $log_hostname );
+ $previous_day = $log_day;
+}
+