Backend Development 14 min read

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.

Laravel Tech Community
Laravel Tech Community
Laravel Tech Community
Laravel Logging System Overview and Configuration Guide

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

stack

A wrapper that makes it easy to create a "multi‑channel" stack.

single

A single file (uses

StreamHandler

).

daily

A daily rotating file (uses

RotatingFileHandler

).

slack

Uses

SlackWebhookHandler

to send messages to Slack.

papertrail

Uses

SyslogUdpHandler

for Papertrail.

syslog

Uses

SyslogHandler

.

errorlog

Uses

ErrorLogHandler

.

monolog

Factory driver that can use any Monolog handler.

custom

Calls 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

bubble

Whether the message should bubble to other channels after handling.

true
permission

File permission for the log file.

0644
locking

Whether to lock the file before writing.

false

Papertrail 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(/* ... */);
    }
}
backendConfigurationLoggingPHPLaravelmonolog
Laravel Tech Community
Written by

Laravel Tech Community

Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.