Search code examples
perlmojolicious

`Mojo::Log` how to log to file and to stderr?


I have a small Mojolicious application that uses a Mojo::Log logger. Something like the following:

my $log = Mojo::Log->new(path => 'app.log', level => 'trace');
$log->color(1);

get '/' => sub ($c) {
  $c->log->warn('Foo');
  $c->render(text => 'foo', status => 200);
}

What I expected was that I would get logs in stderr and/or stdout as well as logs to the file. Unfortunately this isn't the case. How can I have these logs show up in the applications stderr as well as the app.log file?


Solution

  • I found that I can use something like this (date stuff extracted from the Mojo::Log source):

    my $log = Mojo::Log->new(path => 'app.log', level => 'trace');
    
    $log->on(message => sub ($l, $level, @lines) {
        my $time = time;
        my ($s, $m, $h, $day, $month, $year) = localtime time;
        $time = sprintf('%04d-%02d-%02d %02d:%02d:%08.5f', $year + 1900, $month + 1, $day, $h, $m,
                        "$s." . ((split '.', $time)[1] // 0));
        my $log_to_print = '[' . $time . '] ' . '[' . $level . '] ' . join(' ', @lines);
        if ($level eq 'trace' || $level eq 'info') {
            say $log_to_print;
        } else {
            print \*STDERR, $log_to_print . "\n";
        }
    });
    

    To forward a simplified log to STDERR or STDOUT, depending on the type. While it also writes logs to the file provided in path => when creating the logger.