Structured Logs in Laravel

I’ve been following the likes of Charity Majors on the twitters and one of her big things around Observability is producing logs in a ‘structured’ format. (Loosely defined as ‘something that a machine can easily read and make decisions on.)

Out of the box, Laravel ships with a logging system that uses Monolog and its LineFormatter which is Apache-esque.

const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";

Which means regexes to parse, etc. but they are designed more for human consumption than machine consumption.

The hints of how to change the format to a structured (json) one is right in the docs but as the expression goes, ‘an example would be handy here’. So here you go.

/*
|--------------------------------------------------------------------------
| Logging Changes
|--------------------------------------------------------------------------
|
| Structured logs ftw
|
*/
$app->configureMonologUsing(function ($monolog) {
    $days = config('app.log_max_files', 5);
 
    // default 
    $path = storage_path() . '/logs/laravel.log';
    $handler = new RotatingFileHandler($path, $days);
    $handler->setFormatter(new LineFormatter(null, null, true, true));
    $monolog->pushHandler($handler);
 
    // structured
    $path = storage_path() . '/logs/laravel.json';
    $handler = new RotatingFileHandler($path, $days);
    $handler->setFormatter(new JsonFormatter());
    $monolog->pushHandler($handler);
});

Drop this right before the ‘return $app;’ in bootstrap/app.php and you’ll have two logs, one the default way, and one the new structured way. I’m including both at the moment because we have a bunch of log capture / manipulation stuff around the default structure I haven’t changed yet. Once thats all updated I’ll get rid of the default section.

There’s been a bunch of noise in the Laravel world around ‘supporting the enterprise’. Adding a ‘log format’ is one of those small enterprise support things that adds huge value.

(And yes, I know, pull requests are welcome, but until then, here is a blog post.)

Post a Comment

Your email is never published nor shared. Required fields are marked *