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
Here you go... I've spent so much time to add custom functionality to Monolog which able to do THAT in a proper way. I tried sooooo many different ways, but all was a bit hacky. Finally I found a good way to get this functionality working....
As the application is big, I needed separate log files, and maintain the existing Laravel's Log interface as much as possible. I needed something like:
Log::write('audit', 'User logged in to the app.');
Log::info('event', 'User sent out 2 emails.');
The Solution:
App\Providers\AppServiceProvider.php (add to register function)
//Facade to Object binding
$this->app->bind('chanellog', 'App\Helpers\ChannelWriter');
config\app.php (add to aliases)
//Custom Alias Class
'ChannelLog' => App\Contracts\Facades\ChannelLog::class,
App\Contracts\Facades\ChannelLog.php
App\Helpers\ChannelWriter.php
[
'path' => 'logs/audit.log',
'level' => Logger::INFO
],
'audit' => [
'path' => 'logs/audit.log',
'level' => Logger::INFO
]
];
/**
* The Log levels.
*
* @var array
*/
protected $levels = [
'debug' => Logger::DEBUG,
'info' => Logger::INFO,
'notice' => Logger::NOTICE,
'warning' => Logger::WARNING,
'error' => Logger::ERROR,
'critical' => Logger::CRITICAL,
'alert' => Logger::ALERT,
'emergency' => Logger::EMERGENCY,
];
public function __construct() {}
/**
* Write to log based on the given channel and log level set
*
* @param type $channel
* @param type $message
* @param array $context
* @throws InvalidArgumentException
*/
public function writeLog($channel, $level, $message, array $context = [])
{
//check channel exist
if( !in_array($channel, array_keys($this->channels)) ){
throw new InvalidArgumentException('Invalid channel used.');
}
//lazy load logger
if( !isset($this->channels[$channel]['_instance']) ){
//create instance
$this->channels[$channel]['_instance'] = new Logger($channel);
//add custom handler
$this->channels[$channel]['_instance']->pushHandler(
new ChannelStreamHandler(
$channel,
storage_path() .'/'. $this->channels[$channel]['path'],
$this->channels[$channel]['level']
)
);
}
//write out record
$this->channels[$channel]['_instance']->{$level}($message, $context);
}
public function write($channel, $message, array $context = []){
//get method name for the associated level
$level = array_flip( $this->levels )[$this->channels[$channel]['level']];
//write to log
$this->writeLog($channel, $level, $message, $context);
}
//alert('event','Message');
function __call($func, $params){
if(in_array($func, array_keys($this->levels))){
return $this->writeLog($params[0], $func, $params[1]);
}
}
}
App\Helpers\ChannelStreamHandler.php
channel = $channel;
parent::__construct($stream, $level, $bubble);
}
/**
* When to handle the log record.
*
* @param array $record
* @return type
*/
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
);
}
}
}
After this, you can do in any file:
use ChannelLog as Log;
...
function myFunction(){
//Recommended (writes INFO to logs/event.log)
Log::write('event', 'User sent out 3 voucher.')
//Possible to use (writes ALERT to logs/audit.log)
Log::alert('audit', 'User modified xyz entry.')
//Or even:
Log::write('audit', 'User modified xyz entry.', ['user'=>1])
}