NAME Apache2::ModLogConfig - a Perl interface to mod_log_config SYNOPSIS Call a Perl handler from a "CustomLog" format specification: use Apache2::ModLogConfig (); sub My::Format { my ($r)=@_; return $a_string; } CustomLog LOGFILE "... %{My::Format}^..." Use a Perl handler as logfile: PerlModule Apache2::ModLogConfig PerlModule My::LogReceiver CustomLog "@perl: My::LogReceiver" "format spec" Print to a logfile: use Apache2::ModLogConfig (); sub handler { my ($r)=@_; ... my $log=$r->server->custom_log_by_name('logs/access_log'); my $success=$log->print($r, qw/тут был вася/, "\n"); ... } INSTALLATION perl Makefile.PL make make test make install DESCRIPTION The reason to start this module was to monitor the number of incoming and outgoing bytes for each request. "mod_log_config" in combination with "mod_logio" can log these numbers. But in Perl they are really hard to get. "mod_logio" uses a network-level input filter as byte counter. The outgoing bytes are counted by the core output filter and reported back to "mod_logio" if loaded. Now, with the help of this module you can do 3 things: * call a Perl handler from a "CustomLog" format specification * use a Perl handler in place of a logfile * write out-of-bound messages to logfiles managed by "mod_log_config" For this to work, the module must be loaded before the "PerlOpenLogsHandler" phase. Calling a Perl handler from a format specification requires an early start of the interpreter and the module must be loaded at that stage. That means you need either a "..." section in your httpd.conf or the module must be loaded by "PerlLoadModule". Note, while developing this module I have found a bug in httpd that can lead to segfaults. It is present at least up to httpd 2.2.17. It occurs if "mod_log_config" is statically compiled into httpd and "BufferedLogs" are used. In this case avoid changing the "BufferedLogs" setting while restarting httpd via "SIGHUP" or "SIGUSR1". See Call a Perl handler from a "CustomLog" format specification To be used this way "Apache2::ModLogConfig" registers the "^" format with "mod_log_config". "^" was chosen because it resembles the "^" in a number of Perl variables like $^V for example. Now, a format specifier can receive an argument. The argument is given in braces between the "%" sign and the specifier. The "^" specifier's argument specifies the Perl handler to call. A fully qualified name is expected. Example: LogFormat "%{My::Handler::function}^" perllog The handler is called with an Apache2::RequestRec object as the only parameter. In a chain of internal redirects this is by default the final request. It can be modified according to the "mod_log_config" documentation: LogFormat "%<{My::Handler::function}^" perllog This way the initial request is passed to the handler. Other modifiers are also applicable as described by "mod_log_config". Use a Perl handler in place of a logfile Now Perl handler works as log drain. That means it will receive a log file. CustomLog "@perl: My::LogReceiver" FORMATSPEC The prefix @perl: is used to distinguish between a normal file name or pipe specification and the Perl handler. The actual handler name is resolved the usual modperl way. That means if there is no function named "My::LogReceiver", "My::LogReceiver::handler" is looked up. Auto-loading should work as well (although untested). Further, an anonymous function can be specified as: CustomLog "@perl: sub { my ($r, @strings)=@_; ... }" FORMATSPEC The handler is called with the final request of a chain of internal redirects as the first parameters. The other parameters are all strings where each one corresponds to either a the result of a format specifier or a constant string. Assuming the following format specification "input bytes=%I, output bytes=%O" the handler is called with 6 parameters: * the request object * the string "input bytes=" * a number according to %I * the string ", output bytes=" * a number according to %O * and a trailing "\n" to close the line Note, a possible "PerlLogHandler" runs before the "mod_log_config" handler. So, it's not possible to record a few values here and use them in a "PerlLogHandler". A "PerlCleanupHandler" or a request pool cleanup handler however should be fine. My original problem now can be solved as: package My::IO; sub handler { my ($r, $in, $out)=@_; $r->notes->{InBytes}=$in; $r->notes->{OutBytes}=$out; } sub cleanup { my ($r)=@_; my ($in, $out)=@{$r->notes}{qw/InBytes OutBytes/}; ... } in httpd.conf: CustomLog "@perl: My::IO" "%I%O" PerlCleanupHandler My::IO::cleanup Writing to a "CustomLog" logfile and introspection Have you ever wanted to write to the access_log directly? I haven't. But now it's feasible and perhaps someone finds a weird usage case. "Apache2::ModLogConfig" implements the following methods. @names=$s->custom_logs Assuming $s is a Apache2::ServerRec object this method returns the logfile names defined for this VHost. The elements of @names are literally the strings specified as first parameter to "CustomLog". $log=$s->custom_log_by_name($name) Assuming $s is a Apache2::ServerRec object this method returns an "Apache2::ModLogConfig" object for the given name. $status=$log->print($r, @strings) Assuming $log is an "Apache2::ModLogConfig" object and $r is an Apache2::RequestRec this method prints the strings in @strings to the file. No escaping is done. $status is an APR status code ("APR::Const::SUCCESS" if all is well). EXPORT None. SEE ALSO modperl, mod_log_config, apache httpd AUTHOR Torsten Förtsch, COPYRIGHT AND LICENSE Copyright (C) 2011 by Torsten Förtsch This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.12.3 or, at your option, any later version of Perl 5 you may have available.