1nickt has asked for the wisdom of the Perl Monks concerning the following question:

Learned friends,

I am attempting to convert my Starman log to structured JSON to match the app logs, and to add a request ID to all the log entries starting with the Starman log.

I have both of these things working separately but they are not playing nicely with each other. I used Plack::Middleware::AccessLog::Structured for the log, and as advertised I get nice single-line JSON in my access_log. I also used Plack::Middleware::RequestId to generate the request ID, and this too is working, in the sense that in the application code, the value is present in the Plack env.

However, the initial log entry from Starman cannot read the request ID from the env, and I suspect it's because it's in the same builder block. I have tried pushing the value to an HTTP header and the regular ENV as well as the Plack env, and all attempts have the same outcome: the value is null in the log for the Starman entry and present for the app log entries. Here's my app.psgi:

use Meta::Portal; use Plack::Builder; use Plack::Middleware::AccessLog::Structured; use Plack::Middleware::RequestId; use Data::GUID; my $app = Meta::Portal->to_app; builder { enable 'RequestId', id_generator => sub { Data::GUID->new->as_string; }; enable 'AccessLog::Structured', callback => sub { my ($env, $message) = @_; #use Data::Dumper; #warn Dumper $env; $message->{date} = Time::Moment->from_epoch( delete $message-> +{epochtime} )->strftime('%F %T%6f'); $message->{tracking_id} //= $env{'psgix.request_id'}; return $message; }; $app; };

Thanks for any help!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re: Plack middleware sets Plack env value but it's not consumable in the same builder
by haj (Vicar) on Apr 18, 2021 at 15:16 UTC

    That's a simple mistake: $env{'psgix.request_id'}; should read $env->{'psgix.request_id'};.

    I can't resist: You'd have easily caught this with use strict.

      Thank you! I am suitably chastened.


      The way forward always starts with a minimal test.
Re: Plack middleware sets Plack env value but it's not consumable in the same builder
by 1nickt (Canon) on Apr 18, 2021 at 15:13 UTC

    I was able to get the results I needed with the following code using an in-line middleware:

    builder { #enable 'RequestId', id_generator => sub { # Data::GUID->new->as_string; #}; enable sub { my $app = shift; sub { my $env = shift; $env->{'psgix.request_id'} = Data::GUID->new->as_string; my $res = $app->($env); # do postprocessing return $res; }; }; ...

    Thanks for looking!


    The way forward always starts with a minimal test.