Can we create a custom log file for different purposes in laravel 5.2 like for order related log entries that should be in order.log and for payment related stuff the entry shou
To expand on ShQ's answer:
One issue I noticed is that the log will be appended with [] []
, which are the empty array values for $context
and $extra
within LineFormatter.format();
ie, vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php
There are two ways around this, either provide a format which does not include extra or context to the constructor of LineFormatter
, or provide the 4th argument $ignoreEmptyContextAndExtra
= true
.
All files within ShQ's answer remain the same but ChannelStreamHandler
must change.
ChannelStreamHandler:
channel = $channel;
$formatter = new LineFormatter(null, null, false, true);
$this->setFormatter($formatter);
parent::__construct($stream, $level, $bubble);
}
/**
* When to handle the log record.
*
* @param array $record
* @return bool
*/
public function isHandling(array $record)
{
//Handle if Level high enough to be handled (default mechanism)
//AND CHANNELS MATCHING!
if (isset($record['channel'])) {
return ($record['level'] >= $this->level && $record['channel'] == $this->channel);
} else {
return ($record['level'] >= $this->level);
}
}
}
The important change is to provide 4th param of true, which is $ignoreEmptyContextAndExtra
. This param, tells LineFormatter
to ignore either context
of extra
arrays if empty:
$formatter = new LineFormatter(null, null, false, true);
$this->setFormatter($formatter);
You must be sure to also ensure your running monolog 1.22 because it includes a bug fix regarding ignoreEmptyContextAndExtra
.
I also added an override for info() to the ChannelWritter
class:
public function info($channel, $message, array $context = [])
{
$level = array_flip($this->levels)[$this->channels[$channel]['level']];
$this->writeLog($channel, $level, $message, $context);
}
Additionally, I wasn't happy with the "lazy load logger" in ShQ's solution so modified to use the service provider/IoC
Replace ChannelWriter.writeLog()
:
public function writeLog(string $channel, string $level, string $message, array $context = [])
{
if (!in_array($channel, array_keys($this->channels))) {
throw new InvalidArgumentException('Invalid channel used.');
}
$logger = \App::make("{$channel}log");
$channelHandler = new ChannelStreamHandler(
$channel,
storage_path() . '/' . $this->channels[$channel]['path'],
$this->channels[$channel]['level']
);
$logger->pushHandler($channelHandler);
$logger->{$level}($message);
}
and in your AppServiceProvider
:
$this->app->bind('eventlog', function () {
return new Logger('event');
});
$this->app->bind('auditlog', function () {
return new Logger('audit');
});
I'll try bundle this together into a package.