—package
HTTP::Engine::Middleware::AccessLog;
use
Carp ();
use
DateTime;
has
format
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
default
=>
'%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"'
,
);
after_handle {
my
(
$c
,
$self
,
$req
,
$res
) =
@_
;
if
(
$res
) {
my
$msg
=
$self
->
format
;
$msg
=~ s/\%\{([\w-]+)\}i/
$req
->header($1) ||
'-'
/ge;
# %{User-Agent}
$msg
=~ s/\%(?:[><])?([a-z])/handle_char(
$req
,
$res
, $1) ||
'-'
/ge;
# %r
$msg
=~ s/\%\%/%/g;
# %%
$self
->
log
(
$msg
);
}
return
$res
;
};
sub
handle_char {
my
(
$req
,
$res
,
$char
) =
@_
;
my
$code
= +{
'h'
=>
sub
{
$req
->address,
# remote host
},
'l'
=>
sub
{
'-'
,
# remote log name
},
'u'
=>
sub
{
$req
->user;
# user name
},
't'
=>
sub
{
my
$dt
= DateTime->now;
$dt
->strftime(
"[%d/%b/%y:%H:%M:%S %z]"
);
},
'r'
=>
sub
{
join
' '
,
$req
->method,
$req
->uri->path_query, (
$req
->protocol||
'HTTP/1.0'
);
# ?
},
'b'
=>
sub
{
$res
->content_length ||
'-'
;
# size of response in bytes, excluding HTTP headers
},
's'
=>
sub
{
$res
->status
},
}->{
$char
};
if
(
$code
) {
return
$code
->();
}
else
{
Carp::croak
"unknown log char '$char'"
;
}
}
__MIDDLEWARE__
__END__
=head1 NAME
HTTP::Engine::Middleware::AccessLog - write access log
=head1 SYNOPSIS
my $mw = HTTP::Engine::Middleware->new;
$mw->install( 'HTTP::Engine::Middleware::AccessLog' => {
logger => sub {
warn @_; # your own callback routine
},
format => '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"',
});
HTTP::Engine->new(
interface => {
module => 'YourFavoriteInterfaceHere',
request_handler => $mw->handler( \&handler ),
}
)->run();
=head1 DESCRIPTION
This middleware prints access log like apache.
This module's log format string is a subset of Apache.
If you want to use more syntax, patches welcome :)
=head1 BUG
%r should contains query string.
=head1 AUTHOR
Tokuhiro Matsuno
=head1 SEE ALSO
L<HTTP::Engine::Middleware>