diff options
author | Jonas Smedegaard <dr@jones.dk> | 2002-02-28 14:09:04 +0000 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2002-02-28 14:09:04 +0000 |
commit | cafcd5d4368e57f162a641ed3f4835ecb5a6d391 (patch) | |
tree | 56166fbf16289d8b388cf0f1f9b51e28c3c4bdf9 /parselog |
Initial revision
Diffstat (limited to 'parselog')
-rwxr-xr-x | parselog | 217 |
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; +} + |