| Apache-DBILogConfig documentation | Contained in the Apache-DBILogConfig distribution. |
Apache::DBILogConfig - Logs access information in a DBI database
# In httpd.conf PerlLogHandler Apache::DBILogConfig PerlSetVar DBILogConfig_data_source DBI:Informix:log_data PerlSetVar DBILogConfig_username informix PerlSetVar DBILogConfig_password informix PerlSetVar DBILogConfig_table mysite_log PerlSetVar DBILogConfig_log_format "%b=bytes_sent %f=filename %h=remote_host %r=request %s=status"
This module replicates the functionality of the standard Apache module, mod_log_config, but logs information in a DBI-compliant database instead of a file. (Some documentation has been borrowed from the mod_log_config documentation.)
A DBI data source with a format of "DBI::driver:database"
Username passed to the database driver when connecting
Password passed to the database driver when connecting
Table in the database for logging
A string consisting of formats separated by white space that define the data to be logged (see FORMAT STRING below)
A format string consists of a string with the following syntax:
%[conditions][{parameter}]format=field
Formats specify the type of data to be logged. The following formats are accepted:
A database column to log the data to
For formats that take a parameter
Example: %{DOCUMENT_ROOT}e
Conditions are a comma-separated list of status codes. If the status of the request being logged equals one of the status codes in the condition the data specified by the format will be logged. By placing a '!' in front of the conditions, data will be logged if the request status does not match any of the conditions.
Example: %!200,304,302s=status will log the status of all requests that did not return some sort of normal status
Debugging statements will be written to the error log if LOGLEVEL is set to 'warn' or higher
To install this module, move into the directory where this file is located and type the following:
perl Makefile.PL
make
make test
make install
This will install the module into the Perl library directory.
Once installed, you will need to modify your web server's configuration as above.
After installing and configuring this module, Apache will continue to log to your regular access log file (if it was previously configured that way). To log accesses only to your database comment out CustomLog or TransferLog or set them to /dev/null.
Copyright (C) 1998, Jason Bodnar <jason@shakabuku.org>. All rights reserved.
This module is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
perl(1), mod_perl(3)
| Apache-DBILogConfig documentation | Contained in the Apache-DBILogConfig distribution. |
package Apache::DBILogConfig; require 5.004; use strict; # MODULES use mod_perl 1.11_01; use Apache::Constants qw( :common ); use DBI; use Date::Format; $Apache::DBILogConfig::VERSION = "0.02"; # List of allowed formats and their values my %Formats = ( 'a' => sub {return (shift)->connection->remote_ip}, # Remote IP Address 'A' => sub {}, # Local IP-address 'b' => sub {return (shift)->bytes_sent || '-'}, # Bytes sent, excluding heaers, in CLF format 'B' => sub {return (shift)->bytes_sent}, # Bytes sent, excluding heaers 'c' => sub {}, # Connection status when response is completed (X, +, -) 'e' => sub {return (shift)->subprocess_env(shift)}, # Any environment variable 'f' => sub {return (shift)->filename}, # Filename 'h' => sub {return (shift)->get_remote_host}, # Remote host 'H' => sub {return (shift)->protocol}, # The request protocol 'i' => sub {return (shift)->header_in(shift)}, # A header in the client request 'l' => sub {return (shift)->get_remote_logname}, # Remote log name (from identd) 'm' => sub {return (shift)->method}, # The request method 'n' => sub {return (shift)->notes(shift)}, # The contents of a note from another module 'o' => sub {return (shift)->header_out(shift)}, # A header from the reply 'p' => sub {return (shift)->get_server_port}, # Server port 'P' => sub {return $$}, # Apache child PID 'q' => sub {return $_[0]->args ? '?' . $_[0]->args : ''}, # The query string (prepended with a ? # if the query exists) 'r' => sub {return (shift)->the_request}, # First line of the request 's' => sub {return (shift)->status}, # Status 't' => sub {return time2str $_[1] || "%d/%b/%Y:%X %z", $_[0]->request_time}, # Time: CLF or strftime 'T' => sub {return time - (shift)->request_time}, # Time taken to serve the request 'u' => sub {return (shift)->connection->user}, # Remote user from auth 'U' => sub {return (shift)->uri}, # URL 'v' => sub {return (shift)->server->server_hostname}, # The canonical ServerName 'V' => sub {} # The UseCanonicalName server name ); # SUBS sub logger { my $r = shift; $r = $r->last; # Handle internal redirects $r->subprocess_env; # Setup the environment # Connect to the database my $source = $r->dir_config('DBILogConfig_data_source'); my $username = $r->dir_config('DBILogConfig_username'); my $password = $r->dir_config('DBILogConfig_password'); my $dbh = DBI->connect($source, $username, $password); unless ($dbh) { $r->log_error("Apache::DBILogConfig could not connect to $source - $DBI::errstr"); return DECLINED; } # End unless $r->warn("DBILogConfig: Connected to $source as $username"); # Parse the formats ( %[conditions]{param}format=field [...] ) my @format_list = (); # List of anon hashes {field, format, param, conditions} my $format_string = Apache->request->dir_config('DBILogConfig_log_format'); while ($format_string =~ /%(!)?([^\{[:alpha:]]*)(?:\{([^\}]+)\})?(\w)=(\S+)/g) { my ($op, $conditions, $param, $format, $field) = ($1, $2, $3, $4, $5); # Or conditions together my @conditions = map q($r->status == ) . $_, split /,/, $conditions; $conditions = join(' or ', @conditions); $conditions = qq{!($conditions)} if $op eq '!'; # Negate if necessary $conditions ||= 1; # If no conditions we want a guranteed true condition $r->warn("DBILogConfig: format=$format, field=$field, param=$param, conditions=$conditions"); push @format_list, {'field' => $field, 'format' => $format, 'param' => $param, 'conditions' => $conditions}; } # End foreach # Create the statement and insert data my $table = $r->dir_config('DBILogConfig_table'); @format_list = grep eval $_->{'conditions'}, @format_list; # Keep only ones whose conditions are true my $fields = join ', ', map $_->{'field'}, @format_list; # Create string of fields my $values = join ', ', map $dbh->quote($Formats{$_->{'format'}}->($r, $_->{'param'})), @format_list; # Create str of values my $statement = qq(INSERT INTO $table ($fields) VALUES ($values)); $r->warn("DBILogConfig: statement=$statement"); $dbh->do($statement); $dbh->disconnect; return OK; } # End logger sub handler {shift->post_connection(\&logger)} 1; __END__