Posted on in #development #laravel

The Monolog logging library that Laravel uses is really quite powerful, like most things in the framework it works flawlessly out of the box and unless you want to do something specific you may not need to investigate how it works.

I previously wrote an article for old versions of Laravel detailing using multiple log files which kind of worked, but I wanted to revisit and see if things have changed in newer versions.

Say you wanted to split out log levels into their own files e.g. debug.log, info.log etc - Looking at the docs it's possible to use a many number of different handlers that Monolog provide. Delving into this I discovered the FilterHandler which can be used to only log specific levels. Just want we want!

So we create a new channel, set the driver to monolog and the handler to Monolog\Handler\FilterHandler::class, we can then pass in the constructor arguments using handler_with. As the first param is the handler we need to instantiate it at the top as we're currently in an array. Next specify the level(s) we want to log with minLevelOrList. If you wanted a range of levels you can provide a min level here and also pass a maxLevel as the 3rd param. Finally add the channel name to the list of channels in the stack channel so that it will be used.

config/logging.php

<?php

use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;

$infoStreamHander = new StreamHandler(storage_path('logs/info.log'));
$errorStreamHander = new StreamHandler(storage_path('logs/error.log'));

...

return [
    'channels' => [ 
        'stack' => [
            'driver' => 'stack',
            'channels' => ['daily', 'info', 'error'],
        ],

        ...

        'info' => [
            'driver'  => 'monolog',
            'handler' => Monolog\Handler\FilterHandler::class,
            'handler_with' => [
                'handler' => $infoStreamHander,
                'minLevelOrList' => [Monolog\Logger::INFO],
            ],
        ],

        'error' => [
            'driver'  => 'monolog',
            'handler' => Monolog\Handler\FilterHandler::class,
            'handler_with' => [
                'handler' => $infoStreamHander,
                'minLevelOrList' => [Monolog\Logger::ERROR],
            ],
        ],

        ...
    ]
];

Test by using the various Log methods to output the full range of error messages you're likely to see and behold, only the levels you specified will come through to the different log files.

Illuminate\Support\Facades\Log::debug('debug');
Illuminate\Support\Facades\Log::info('info');
Illuminate\Support\Facades\Log::notice('notice');
Illuminate\Support\Facades\Log::warning('warning');
Illuminate\Support\Facades\Log::error('error');
Illuminate\Support\Facades\Log::critical('critical');
Illuminate\Support\Facades\Log::alert('alert');
Illuminate\Support\Facades\Log::emergency('emergency');