Configuring Custom Logging in Laravel 5
I recently started working on a Laravel 5 project, and I’d like to share how I set up my custom file logging.
I pooled the information below from several sources (acknowledged at the bottom of the article).
I organize my log files per project, under a directory, e.g. /var/log/applications/app_name/app_name.log
, etc.
Below is a sample log that I’d like to accomplish:
The format is similar to:
date log_type channel message extra_params
Custom Logging in Laravel 5 can be achieved by overriding the Illuminate\Foundation\Bootstrap\ConfigureLogging
class.
To get started, create a file under the /bootstrap
folder and name it: ConfigureLogging.php
Add the code below to the file:
<?php namespace Bootstrap;
use Monolog\Logger as Monolog;
use Monolog\Formatter\LineFormatter;
use Illuminate\Log\Writer;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\ConfigureLogging as BaseConfigureLogging;
use Monolog\Handler\StreamHandler;
class ConfigureLogging extends BaseConfigureLogging
{
/**
* Configure the Monolog handlers for the application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Log\Writer $log
* @return void
*/
protected function configureSingleHandler(Application $app, Writer $log)
{
// Stream handlers
$logPath = '/var/log/applications/app_name/app.log';
$logLevel = Monolog::DEBUG;
$logStreamHandler = new StreamHandler($logPath, $logLevel);
// Formatting
// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
$logFormat = "%datetime% [%level_name%] (%channel%): %message% %context% %extra%\n";
$formatter = new LineFormatter($logFormat);
$logStreamHandler->setFormatter($formatter);
// push handlers
$logger = $log->getMonolog();
$logger->pushHandler($logStreamHandler);
}
}
The code above shows how you can override the 'single'
logging for Laravel. If you prefer another logging mode, e.g. daily
, then you can replace configureSingleHandler
with configureDailyHandler
. Check here for a full list of available logging modes.
If your app is using a different namespace, be sure to use that one on line 1
, I’ve just named mine Bootstrap
for demonstration purposes.
Next, in your composer.json
file, add namespace details to the autoload
object under psr-4
:
"autoload": {
...
"psr-4": {
"App\\": "app/",
"Bootstrap\\": "bootstrap/"
}
...
},
Then, we need to replace the ConfigureLogging
bootstrappers in Http/Kernel
and Console/Kernel
to use our custom one. We’ll do this by overriding their respective constructors and doing an array_walk
to the bootstrappers property.
Add the code below to /app/Http/Kernel.php
:
<?php
...
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\Router;
...
...
public function __construct(Application $app, Router $router)
{
parent::__construct($app, $router);
array_walk($this->bootstrappers, function(&$bootstrapper)
{
if($bootstrapper === 'Illuminate\Foundation\Bootstrap\ConfigureLogging')
{
$bootstrapper = 'Bootstrap\ConfigureLogging';
}
});
}
Then this code to /app/Console/Kernel.php
:
<?php
...
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Events\Dispatcher;
...
...
public function __construct(Application $app, Dispatcher $events)
{
parent::__construct($app, $events);
array_walk($this->bootstrappers, function(&$bootstrapper)
{
if($bootstrapper === 'Illuminate\Foundation\Bootstrap\ConfigureLogging')
{
$bootstrapper = 'Bootstrap\ConfigureLogging';
}
});
}
...
Note that we’re using Illuminate\Routing\Router
in /app/Http/Kernel.php
and Illuminate\Contracts\Events\Dispatcher
in /app/Console/Kernel.php
Now you can use the logger in your application, e.g.
<?php
...
use Log;
...
...
public function goLooney()
{
Log::info('I am Bugs Bunny!');
}
This should appear as below in your log file:
PS: The extra square brackets are serialized representations of empty arrays. The LineFormatter
class allows you to pass extra arguments to the log, e.g. if you want to pass an array:
<?php
...
public function goLooney()
{
$looneyFacts = array(
'favoriteFood' => 'orange carrots',
'bestFriend' => 'Daffy Duck'
);
Log::info('I am Bugs Bunny!', $looneyFacts);
}
it will be added to the log:
If the extra brackets are really bugging you (), check out how you can work around it in this StackOverflow question: http://stackoverflow.com/questions/19935899/laravel-logging-extra-square-brackets-at-end-of-log-lines
I hope this is helpful to someone! Back to code!
I pooled the information above from:
- Laravel Official Docs
- Monolog Official Docs
- Laravel Forums
- Laracasts Discussions
- Witty log contents thanks to Fortune