Plack::...cessLog(3)

πŸ’– Plack::Middleware::AccessLog πŸ’–

okay so bestie, this is a page from the User Contributed Perl Documentation for the module Plack::Middleware::AccessLog β€” it's the thing that goes in the Plack world. let's get into it, no cap 🫢


✨ NAME ✨

Plack::Middleware::AccessLog β€” logs requests like Apache's log format πŸ‘‘


🌸 SYNOPSIS 🌸

# in app.psgi
use Plack::Builder;

builder {
    enable "Plack::Middleware::AccessLog", format => "combined";
    $app;
};

πŸ¦‹ DESCRIPTION πŸ¦‹

Plack::Middleware::AccessLog takes the request, hands it off to the app you gave it, and then writes the request-and-response deets out to the logger callback. the format is whatever Apache-style format string you want β€” or you can just say combined or common for the preset default formats. and if you don't say anything at all? combined it is, periodt.

this middleware figures out a calculable Content-Length by peeking at the body type, and ngl it cannot log how long serving the request took. it also logs the request before the response has actually been sent to the client. so if you want the details logged after the response is transmitted to the client (aka more like a real web server does it), go use Plack::Middleware::AccessLog::Timed instead πŸ’…

oh and heads up: this middleware is enabled by default when you run plackup as a default development environment. it's just there, being iconic. ⭐


πŸŽ€ CONFIGURATION πŸŽ€

πŸ’œ format

enable "Plack::Middleware::AccessLog",
    format => '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"';

gives you a format string (or one of the preset templates combined or custom) to say what the log format should look like. under the hood this middleware uses Apache::LogFormat::Compiler to generate the access_log lines, so if you want the full lore, go check perldoc Apache::LogFormat::Compiler πŸ“š

here's every format field, copy them exactly bestie:

  • %% β€” 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 of the response
  • %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 -
  • %p β€” SERVER_PORT from the PSGI environment
  • %P β€” the worker's process id
  • %m β€” REQUEST_METHOD from the PSGI environment
  • %U β€” PATH_INFO from the PSGI environment
  • %q β€” QUERY_STRING from the PSGI environment
  • %H β€” SERVER_PROTOCOL from the PSGI environment

some of these format fields are only supported by middleware that subclasses AccessLog. so, yk, read the room πŸ™ˆ

in addition, you can reference custom values using %{name}, with one of the mandatory modifier flags i, o or t:

  • %{variable-name}i β€” HTTP_VARIABLE_NAME value from the PSGI environment
  • %{header-name}o β€” header-name header in the response
  • %{time-format]t β€” localtime in the specified strftime format

🧚 logger

my $logger = Log::Dispatch->new(...);
enable "Plack::Middleware::AccessLog",
    logger => sub { $logger->log(level => 'debug', message => @_) };

sets a callback to print the log message to. by default it prints to the psgi.errors output stream. 🌈

πŸ“ char_handlers

my $handlers = {
    'z' => sub {
        my ($env,$req) = @_;
        return $env->{HTTP_X_FORWARDED_FOR};
    }
};

enable "Plack::Middleware::AccessLog",
    format => '%z %{HTTP_X_FORWARDED_FOR|REMOTE_ADDR}Z',
    char_handlers => $handlers;

takes a hash reference and passes it to the underlying Apache::LogFormat::Compiler's char_handlers. for more details see "ADD CUSTOM FORMAT STRING" in Apache::LogFormat::Compiler. πŸ’–

🫢 block_handlers

my $handlers = {
    'Z' => sub {
        my ($block,$env,$req) = @_;
        # block eq 'HTTP_X_FORWARDED_FOR|REMOTE_ADDR'
        my ($main, $alt) = split('\|', $args);
        return exists $env->{$main} ? $env->{$main} : $env->{$alt};
    }
};

enable "Plack::Middleware::AccessLog",
    format => '%z %{HTTP_X_FORWARDED_FOR|REMOTE_ADDR}Z',
    block_handlers => $handlers;

takes a hash reference and passes it to the underlying Apache::LogFormat::Compiler's block_handlers. for more details see "ADD CUSTOM FORMAT STRING" in Apache::LogFormat::Compiler. ✨


πŸ‘‘ AUTHORS πŸ‘‘

  • Tatsuhiko Miyagawa
  • Masahiro Nagano

the way they built this and just handed it to us?? legends, fr fr 🫑


πŸ”₯ SEE ALSO πŸ”₯


okay that's the whole page, bestie!! πŸ’– this one ships with perl v5.42.3 and it's dated 2026-10-18 β€” the manual itself is Plack::...cessLog(3). go log something, slay, and drink some water. mwah πŸ’…πŸŒΈ

πŸ“¦ where this page comes from