Skip to content

Instantly share code, notes, and snippets.

@kgoess
Created August 20, 2013 19:42
Show Gist options
  • Save kgoess/6286211 to your computer and use it in GitHub Desktop.
Save kgoess/6286211 to your computer and use it in GitHub Desktop.
--- cpanlib/lib/perl5/Plack/Middleware/AccessLog.pm 2012-12-18 12:51:36.678259555 -0800
+++ cpanlib/lib/perl5/Plack/Middleware/PreAccessLog.pm 2013-08-20 12:41:27.072938490 -0700
@@ -1,57 +1,55 @@
-package Plack::Middleware::AccessLog;
+package Plack::Middleware::PreAccessLog;
use strict;
use warnings;
use parent qw( Plack::Middleware );
use Plack::Util::Accessor qw( logger format );
use Carp ();
use Plack::Util;
my %formats = (
- common => '%h %l %u %t "%r" %>s %b',
- combined => '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"',
+ common => '%h %l %u %t "%r" TBD TBD ',
+ combined => '%h %l %u %t "%r" TBD TBD "%{Referer}i" "%{User-agent}i"',
);
use POSIX ();
my $tzoffset = POSIX::strftime("%z", localtime) !~ /^[+-]\d{4}$/ && do {
require Time::Local;
my @t = localtime;
my $seconds = Time::Local::timegm(@t) - Time::Local::timelocal(@t);
my $min_offset = int($seconds / 60);
sprintf '%+03d%02u', $min_offset / 60, $min_offset % 60;
};
sub call {
my $self = shift;
my($env) = @_;
- my $res = $self->app->($env);
+ # Log the incoming request *before* we call the next app.
+ my $req = Plack::Request->new($env);
+ my $logger = $self->logger || sub { $env->{'psgi.errors'}->print(@_) };
+ $logger->( $self->log_line( 000, $req->headers(), $env ) );
- return $self->response_cb($res, sub {
- my $res = shift;
- my $logger = $self->logger || sub { $env->{'psgi.errors'}->print(@_) };
-
- my $content_length = Plack::Util::content_length($res->[2]);
- $logger->( $self->log_line($res->[0], $res->[1], $env, { content_length => $content_length }) );
- });
+ my $res = $self->app->($env);
+ return $res;
}
sub log_line {
my($self, $status, $headers, $env, $opts) = @_;
my $h = Plack::Util::headers($headers);
my $strftime = sub {
my ($fmt, @time) = @_;
$fmt =~ s/%z/$tzoffset/g if $tzoffset;
my $old_locale = POSIX::setlocale(&POSIX::LC_ALL);
POSIX::setlocale(&POSIX::LC_ALL, 'C');
my $out = POSIX::strftime($fmt, @time);
POSIX::setlocale(&POSIX::LC_ALL, $old_locale);
return $out;
};
my $block_handler = sub {
my($block, $type) = @_;
if ($type eq 'i') {
@@ -157,48 +155,50 @@
=head1 CONFIGURATION
=over 4
=item format
enable "Plack::Middleware::AccessLog",
format => '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"';
Takes a format string (or a preset template C<combined> or C<custom>)
to specify the log format. This middleware implements a subset of
L<Apache's LogFormat templates|http://httpd.apache.org/docs/2.0/mod/mod_log_config.html>:
%% a percent sign
%h REMOTE_ADDR from the PSGI environment, or -
%l remote logname not implemented (currently always -)
%u REMOTE_USER from the PSGI environment, or -
%t [local timestamp, in default format]
%r REQUEST_METHOD, REQUEST_URI and SERVER_PROTOCOL from the PSGI environment
- %s the HTTP status code of the response
- %b content length
%T custom field for handling times in subclasses
%D custom field for handling sub-second times in subclasses
%v SERVER_NAME from the PSGI environment, or -
%V HTTP_HOST or SERVER_NAME from the PSGI environment, or -
-Some of these format fields are only supported by middleware that subclasses C<AccessLog>.
+These two are NOT supported:
+
+ %s the HTTP status code of the response
+ %b content length
+
In addition, custom values can be referenced, using C<%{name}>,
with one of the mandatory modifier flags C<i>, C<o> or C<t>:
%{variable-name}i HTTP_VARIABLE_NAME value from the PSGI environment
%{header-name}o header-name header
%{time-format]t localtime in the specified strftime format
=item logger
my $logger = Log::Dispatch->new(...);
enable "Plack::Middleware::AccessLog",
logger => sub { $logger->log(level => 'debug', message => @_) };
Sets a callback to print log message to. It prints to the C<psgi.errors>
output stream by default.
=back
=head1 SEE ALSO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment