在laravel中支持了 "monolog"日志系统,同时添加了自己的一些记录日志的功能,这也使得Larvael的日志记录功能非常完善。在Lavravel中,使用Log门面来记录日志,Log门面背后实际上是Illuminate\Logger\WriterLog,而在WriterLog函数中注入了Monolog\Logger,他们都实现了一个接口LoggerInterface。这里的抽象构件和抽象装饰角色都是LoggerInterface这个接口,而Monolog中的Logger类就是具体装饰角色,Log文件夹下的Logger类就是具体的构件,使用装饰器模式使得larvael在应用Monilog写入日志记录的时候添加一个职责,这个新功能通过fireLogEvent完成,在此函数中创建了一个MessageLogged对象,把日志的level,message,context都记录下来。生成的日志文件存放在storage/logs目录下。
文件路径:
抽象构件和抽象装饰角色:vendor\psr\log\Psr\Log\LoggerInterface.php
具体的构件:vendor\laravel\framework\src\Illuminate\Log\Logger.php
具体装饰角色:vendor\monolog\monolog\src\Monolog\Logger.php
//Log文件下Logger类中的写入日志方法writeLog()
protected function writeLog($level, $message, $context)
{
$this->logger->{$level}(
$message = $this->formatMessage($message),
$context = array_merge($this->context, $context)
);
$this->fireLogEvent($level, $message, $context);
}
//Log文件下Logger类中的具体添加方法fireLogEvent()
protected function fireLogEvent($level, $message, array $context = [])
{
if (isset($this->dispatcher)) {
$this->dispatcher->dispatch(new MessageLogged($level, $message, $context));
}
}
如果不用装饰器设计模式的话,想对新添加的职责进行修改或者删除就会很蛮烦。同时,如果还想再添加一些新的功能,也可以生成一个职责类然后实现LoggerInterface接口,聚集Monolog日志系统,就可以实现新功能的添加,也不需要修改原来的代码,遵循开闭原则。这种模式比继承更多的灵活性。当需要扩展多个功能时,装饰器模式只需要增加新的具体装饰类即可,而继承关系则需要继承原有类,再进行扩展,如果需要在不改变原有类的基础上继续扩展,则需要再次继承,这样代码耦合性比较高。
类图
时序图