By default, everything goes into one storage/logs/laravel.log file, which gets noisy fast. A custom log channel routes specific events — payments, webhooks, a third-party integration — into their own file, making them far easier to grep or monitor separately.
1. Define the channel
In config/logging.php, add a new entry to the channels array:
'channels' => [
// ...existing channels
'payments' => [
'driver' => 'daily',
'path' => storage_path('logs/payments.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
],
],
The daily driver rotates to a new dated file each day and prunes files older than days automatically — a plain single driver works too, but grows forever without rotation.
2. Log to it explicitly
use Illuminate\Support\Facades\Log;
Log::channel('payments')->info('Charge succeeded', [
'order_id' => $order->id,
'amount' => $order->total,
]);
Always pass structured context as the second array argument rather than interpolating values into the message string — it keeps the log machine-parseable if you ever pipe it into a log aggregator.
3. Optional: send the same entry to multiple channels
A stack channel fans a single log call out to several channels at once — useful for "log to file AND alert Slack on payment failures":
'payments_stack' => [
'driver' => 'stack',
'channels' => ['payments', 'slack'],
],
Common mistake
Forgetting to clear config cache after editing config/logging.php in a production environment where php artisan config:cache has been run — the app keeps using the cached (old) config until you run php artisan config:cache again, not just config:clear.