Write JSON logs in Laravel
Configure a Laravel daily log channel with Monolog JSON formatting, preserve exception traces explicitly, and validate one event per line before collection.
Laravel uses Monolog to format and write application logs. Add a dedicated channel, then apply Monolog's JsonFormatter through a tap class. Existing calls can use the new format once they are routed to that channel; historical files are not rewritten.
The examples use Laravel 12.x with Monolog 3. Check your installed versions before copying configuration into an older application.
Add a daily channel
Inside the channels array in config/logging.php:
'json' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.json'),
'level' => 'debug',
'days' => 14,
'tap' => [App\Logging\JsonFormatter::class],
],
This uses daily file rotation with a retention count. It is not a strict size cap: a busy day can still produce a large file, and cleanup occurs as the handler rotates.
Apply the JSON formatter
Create app/Logging/JsonFormatter.php:
<?php
namespace App\Logging;
use Illuminate\Log\Logger;
use Monolog\Formatter\JsonFormatter as MonologJsonFormatter;
class JsonFormatter
{
public function __invoke(Logger $logger): void
{
$formatter = new MonologJsonFormatter();
$formatter->includeStacktraces(true);
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter($formatter);
}
}
}
The daily channel's rotating-file handler supports formatting. If you adapt this tap for a mixed custom handler stack, verify each handler's formatter support.
Monolog's JSON formatter normalizes exceptions, but stack traces are not included by default in this version. includeStacktraces(true) requests them explicitly. Treat trace contents and context values as potentially sensitive.
Send records to the channel
use Illuminate\Support\Facades\Log;
Log::channel('json')->info('User signed in', [
'user_id' => 42,
'ip' => '192.0.2.10',
]);
To route ordinary Log::info() calls through it, set the intended default channel or include json in your configured stack. A stack containing both single and json writes both copies, which may be intentional but increases volume. Update or rebuild Laravel's configuration cache as part of applying the change, and restart long-lived workers when needed.
Validate the event shape
Generate one normal record and one exception record. Verify the timestamp, severity, context, and requested trace fields, and confirm that each event occupies one physical line. A valid JSON document alone does not guarantee that a downstream system indexes the expected fields.
For DataKit log collection, match the rotating filenames, configure parsing, and compare the collected event with the original sample.
Can I convert old text logs? Changing the channel affects future records only. Historical text needs a separate parser or transformation; a Pipeline can extract fields when its rules match the old format.
How do single and daily differ? single writes a fixed filename. daily rotates date-suffixed files, such as laravel-2026-10-19.json, and applies configured retention. Neither replaces disk-capacity monitoring.
See Laravel logging customization and Monolog's JSON formatter.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan