laravel 5.2 针对不同任务的自定义日志文件
2022-08-30 12:31:42
我们是否可以在laravel 5.2中为不同的目的创建自定义日志文件,例如用于应该按顺序排列的订单相关日志条目.log以及用于与付款相关的东西,该条目应该登录付款.log
我想找到最好的Laravel方式。
目前,我们只能更改日志文件频率(如每日,单个),或者我们可以更改日志文件的名称,而不是默认值,即laravel.log
我们是否可以在laravel 5.2中为不同的目的创建自定义日志文件,例如用于应该按顺序排列的订单相关日志条目.log以及用于与付款相关的东西,该条目应该登录付款.log
我想找到最好的Laravel方式。
目前,我们只能更改日志文件频率(如每日,单个),或者我们可以更改日志文件的名称,而不是默认值,即laravel.log
有一个简单的方法:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = ['orderId' => 10,
'description' => 'Some description'];
//first parameter passed to Monolog\Logger sets the logging channel name
$orderLog = new Logger('order');
$orderLog->pushHandler(new StreamHandler(storage_path('logs/order.log')), Logger::INFO);
$orderLog->info('OrderLog', $log);
日志/订单中的输出.log:
[2017-04-30 00:00:00] order.INFO: OrderLog {"orderId":10, "description":"Some description"} []
给你。。。我花了很多时间向Monolog添加自定义功能,这些功能能够以正确的方式做到这一点。我尝试了很多不同的方法,但一切都有点笨拙。最后,我找到了一个好方法来让这个功能工作....
由于应用程序很大,我需要单独的日志文件,并尽可能地维护现有的Laravel的日志界面。我需要这样的东西:
Log::write('audit', 'User logged in to the app.');
Log::info('event', 'User sent out 2 emails.');
解决方案:
App\Providers\AppServiceProvider.php(添加到注册函数)
//Facade to Object binding
$this->app->bind('chanellog', 'App\Helpers\ChannelWriter');
config\app.php(添加到别名)
//Custom Alias Class
'ChannelLog' => App\Contracts\Facades\ChannelLog::class,
应用程序\合同\外观\通道日志.php
<?php
namespace App\Contracts\Facades;
use Illuminate\Support\Facades\Facade;
/**
* @see \Illuminate\Log\Writer
*/
class ChannelLog extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'chanellog';
}
}
App\Helpers\ChannelWriter.php
<?php
namespace App\Helpers;
use Monolog\Logger;
use App\Helpers\ChannelStreamHandler;
class ChannelWriter
{
/**
* The Log channels.
*
* @var array
*/
protected $channels = [
'event' => [
'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
<?php
namespace App\Helpers;
use Monolog\Handler\StreamHandler;
/**
* Use channels to log into separate files
*
* @author Peter Feher
*/
class ChannelStreamHandler extends StreamHandler
{
/**
* Channel name
*
* @var String
*/
protected $channel;
/**
* @param String $channel Channel name to write
* @see parent __construct for params
*/
public function __construct($channel, $stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
{
$this->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
);
}
}
}
在此之后,您可以在任何文件中执行以下操作:
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])
}