monolog 源码分析

简介

monolog是基于psr-3设计的日志记录组件。

monolog抽象层

Logger

日志记录总控类,通过pushHandler、popHandler、pushProcessor、popProcessor排兵布阵。 根据PSR-3,Logger可以记录8个不同等级的日志信息。

handler的种类丰富,以下例举部分:
  • ElasticesearchHandler
  • ErrorLogHandler
  • PHPConsoleHandler
  • NullHandler
  • .....
processor的种类也不少,且可以自定义
  • GitProcessor 将git分支信息和提交信息加入到记录($record)中
  • HostnameProcessor 在记录中加入hostname信息
  • .....

Handler

handler处理日志记录的具体事项。

AbstractProcessingHandler抽象类

一般情况下,handler都需继承AbstractProcessingHandler抽象类。该类提供handler所必须的方法,实现ProcessableHandlerInterface和FormattableHandlerInterface接口以操作processor和formatter。

abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
{
    use ProcessableHandlerTrait;
    use FormattableHandlerTrait;
    ......
}

继承该类后,通过handler也可以实现出入栈processor及操作formatter。对processor和formatter的在调用在handle方法中实现。

 public function handle(array $record): bool
    {
        if (!$this->isHandling($record)) {
            return false;
        }

        if ($this->processors) {
            $record = $this->processRecord($record); //获取processor日志
        }

        $record['formatted'] = $this->getFormatter()->format($record); //格式化日志

        $this->write($record);

        return false === $this->bubble;
    }

在ProcessableHandlerTrait中实现出入栈processor

 public function pushProcessor(callable $callback): HandlerInterface
    {
        array_unshift($this->processors, $callback);

        return $this;
    }

    public function popProcessor(): callable
    {
        if (!$this->processors) {
            throw new \LogicException('You tried to pop from an empty processor stack.');
        }

        return array_shift($this->processors);
    }

在FormattableHandlerTrait中设置formatter

public function setFormatter(FormatterInterface $formatter): HandlerInterface
    {
        $this->formatter = $formatter;

        return $this;
    }

    public function getFormatter(): FormatterInterface
    {
        if (!$this->formatter) {
            $this->formatter = $this->getDefaultFormatter();
        }

        return $this->formatter;
    }

Formatter

formatter用于日志记录的格式化,往往不同的handler有各自不同的formatter。比如ElasticsearchHandler有ElasticsearchFormatter。一个handler对应一个formatter。当没有指定formatter时,handler就会调用默认的LineFormatter。LineFormatter将输入的record格式化成一行的字符串,主要用于将日志记录到文件的场景。

class LineFormatter extends NormalizerFormatter
{
    ......
}

Processor

processor用来追加一些额外的记录

你可以自定义processor

$logger->pushProcessor(function($record){
        $record['extra']['foo'] = 'bar';
        return $record;
    });

也可以使用monoglog自带的。HostnameProcessor类实现了invoke静态方法,当以调用函数的方式调用一个对象时,invoke方法会被自动调用。

$logger->pushProcessor(new \Monolog\Processor\HostnameProcessor);

monolog使用策略模式

monolog使用策略模式实现handler与processor、formatter的代码分离

本作品采用《CC 协议》,转载必须注明作者和本文链接
blabla
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!