$ hypnotoad myapp.pl $ prove tracking.t #### # tracking.t use strict; use warnings; use Test::More; use Parallel::ForkManager; use HTTP::Tiny; use List::Util qw( all ); use Path::Tiny; my $log_file = '/tmp/test.log'; path( $log_file )->append( { truncate => 1 }, '' ); my $url = 'http://localhost:8080/hello'; my $pm = new Parallel::ForkManager(50); my $ua = HTTP::Tiny->new; for ( 1 .. 10_000 ) { $pm->start and next; my $res = $ua->get( $url ); $pm->finish; } $pm->wait_all_children; my %ids; my $count = 0; for ( path( $log_file )->lines({ chomp => 1 }) ) { $count++; (my $id) = /"([^"]*)/; $ids{ $id }++; } is( $count, 20_000, '20,000 lines in the log file' ); is( scalar keys %ids, 10_000, '10,000 IDs' ); ok( (all { $_ == 2 } values( %ids )), 'each key was seen twice' ); done_testing; __END__ #### # myapp.pl use strict; use warnings; $|++; use Log::Any::Adapter 'File', '/tmp/test.log'; use Mojolicious::Commands; use MyApp; Mojolicious::Commands->start_app('MyApp'); __END__ #### # MyApp.pm package MyApp { use Mojo::Base 'Mojolicious'; sub startup { my $self = shift; $self->config( hypnotoad => { workers => 12, clients => 100, accepts => 100, }, ); $self->routes->get('/hello')->to('foo#hello'); } }; package MyApp::Controller::Foo { use Mojo::Base 'Mojolicious::Controller'; use Digest::MD5 qw( md5_hex ); use Time::HiRes qw( time ); use MyLib; sub hello { my $self = shift; my $obj = MyLib->new; $obj->log->context->{id} = md5_hex(time . $$); $obj->log->debug('Hello from the route'); my $txt = $obj->other_class_action(42); $self->render(text => $txt); } }; 1; #### # MyLib.pm use strict; use warnings; package MyLib { use Log::Any; use OtherLib; use Moo; has log => ( is => 'ro', default => sub { Log::Any->get_logger }, ); sub other_class_action { my ( $self, $val ) = @_; OtherLib::do_action( $val ); } }; 1; #### # OtherLib.pm use strict; use warnings; package OtherLib { use Log::Any '$log'; sub do_action { my $val = shift; my $data = { value => $val }; $log->debugf( 'Acting with %s', $data ); return sprintf 'The answer is %s', $val; } }; 1;