Laravel Logging System Overview and Configuration Guide
This article explains Laravel's powerful logging facilities built on Monolog, describes the configuration file location, details available channel drivers, shows how to set up single, daily, stack, Slack, Papertrail and custom channels, and provides code examples for writing log messages and customizing Monolog handlers.
Log System Overview
To help you understand what happens inside an application, Laravel provides a robust logging service that can write log messages and system errors to files, or even notify your team via Slack.
Laravel uses the Monolog library, which powers many advanced log handlers. Laravel makes configuring these handlers simple, allowing you to mix and match them for custom log processing.
Configuration
All application log settings live in the config/logging.php file. This file defines the log channels available to your application; the most common options are reviewed below.
By default Laravel uses the stack channel to record log messages. The stack driver aggregates multiple channels into a single channel. See the Laravel documentation for more details about stacks.
Channel Name Configuration
Monolog instantiates a channel based on the current environment name, such as production or local . To change this, add a name option to the channel configuration:
'stack' => [
'driver' => 'stack',
'name' => 'channel-name',
'channels' => ['single', 'slack'],
],Available Channel Drivers
Name
Description
stackA wrapper that makes it easy to create a "multi‑channel" stack.
singleA single file (uses
StreamHandler).
dailyA daily rotating file (uses
RotatingFileHandler).
slackUses
SlackWebhookHandlerto send messages to Slack.
papertrailUses
SyslogUdpHandlerfor Papertrail.
syslogUses
SyslogHandler.
errorlogUses
ErrorLogHandler.
monologFactory driver that can use any Monolog handler.
customCalls a specified factory to create the channel.
Tip: For the monolog and custom drivers, see the "Advanced Channel Customization" documentation.
Configuring Single and Daily Channels
The single and daily drivers support three optional settings: bubble , permission and locking .
Name
Description
Default
bubbleWhether the message should bubble to other channels after handling.
true permissionFile permission for the log file.
0644 lockingWhether to lock the file before writing.
falsePapertrail Channel
The papertrail driver requires url and port options. You can obtain these values from Papertrail.
Slack Channel
The slack driver needs a url that matches an incoming webhook you have configured for your Slack workspace.
Building a Log Stack
The stack driver lets you combine multiple channels into a single log channel. Below is a production‑level example that stacks syslog and slack :
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['syslog', 'slack'],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],In this configuration, the stack aggregates the syslog and slack channels. When a log entry is written, both channels have a chance to handle it.
Log Levels
Both syslog and slack channels can define a level option that determines the minimum severity required for a message to be sent. Monolog supports all RFC 5424 levels: emergency, alert, critical, error, warning, notice, info, debug .
For example, a debug call will be recorded by syslog but not sent to Slack because Slack's level is set to critical . An emergency call will be sent to both.
Log::debug('An informational message.'); Log::emergency('The system is down!');Writing Log Messages
You can use the Log facade to write messages at any of the RFC 5424 levels:
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);By default the messages are written to the default channel defined in config/logging.php :
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for a given user.
*/
public function showProfile($id)
{
Log::info('Showing user profile for user: ' . $id);
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}Context Information
You may pass an array of context data to a log method; the data will be formatted and displayed with the message:
Log::info('User failed to login.', ['id' => $user->id]);Writing to a Specific Channel
Sometimes you want to write to a channel other than the default. Use the channel method on the Log facade:
Log::channel('slack')->info('Something happened!');For on‑demand stacks you can call stack with an array of channel names:
Log::stack(['single', 'slack'])->info('Something happened!');Highly Customising Monolog Channels
Customising a Channel's Monolog Instance
You can fully control an existing channel's Monolog instance by adding a tap array to the channel configuration. The tap array lists classes that receive the Monolog instance after it is created:
'single' => [
'driver' => 'single',
'tap' => [App\Logging\CustomizeFormatter::class],
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],The tap class must implement an __invoke method that receives an Illuminate\Log\Logger instance:
<?php
namespace App\Logging;
class CustomizeFormatter
{
/**
* Customize the given logger instance.
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(/* your formatter */);
}
}
}Tip: All "tap" classes are resolved by the service container, so any dependencies will be injected automatically.
Creating a Monolog Handler Channel
When using the monolog driver, the handler option specifies which Monolog handler to instantiate. If the handler's constructor needs arguments, provide them via the optional with option:
'logentries' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\SyslogUdpHandler::class,
'with' => [
'host' => 'my.logentries.internal.datahubhost.company.com',
'port' => '10000',
],
],Monolog Formatting
The monolog driver uses LineFormatter by default, but you can customise it with the formatter and formatter_with options:
'browser' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\BrowserConsoleHandler::class,
'formatter' => Monolog\Formatter\HtmlFormatter::class,
'formatter_with' => [
'dateFormat' => 'Y-m-d',
],
],If the handler provides its own formatter, set formatter to default :
'newrelic' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\NewRelicHandler::class,
'formatter' => 'default',
],Creating Channels via a Factory
For a completely custom channel, define a custom driver in config/logging.php with a via option that points to a factory class:
'custom' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
],The factory class must implement an __invoke method that receives the channel configuration array and returns a Monolog\Logger instance:
<?php
namespace App\Logging;
use Monolog\Logger;
class CreateCustomLogger
{
/**
* Create a Monolog instance.
*/
public function __invoke(array $config)
{
return new Logger(/* ... */);
}
}Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.