这多是php世界中最好的日志库——monolog

因为一些历史缘由,php中并无内建的日志接口,故长期以来也没一个功能完备而且应用普遍的日志库。在个人工做生涯中,若是系统须要记录一些应用日志的话,基本上就是封装一个日志类,而后把一些要记录的字段写入到磁盘文件。php

这样就不免要一遍一遍的造轮子,而且在没有一个规范的状况下,记录下来的日志也是不方便分析的。可是但愿读完本文后但愿大家能够放弃本身造这种日志类的轮子了,由于几乎你不可能造得比咱们今天要介绍的主角:monolog更圆。json

monolog是一个为5.3以上版本php开发的日志库,可是须要注意的是如今主干版本只支持php 7以上版本,若是你的服务器环境仍是php 5的话,可使用monolog的1.x版本。设计模式

值得一提的是monolog是一个符合psr-3规范的日志类库,而且符合psr-4加载规范。若是有对psr规范不太了解的同窗能够参看以下连接:http://www.php-fig.org/psr/,咱们在这里就不具体介绍这些规范了,反正知道monolog是复合当前最新行业规范的日志库就够了。服务器

若是想要在你的代码中引入monolog的话只须要执行:数据结构

composer require monolog/monolog架构

mongolog中有几个很重要的概念:app

第一个:handler 日志管理器composer

存放handler的数据结构是一个“栈”,一个日志实例能够有多个handler,经过Logger实例的pushHandler方法压入一个handler,该方法接受一个HandlerInterface类型的参数。若是你设置了多个handler,当你新增一条日志的时候,他会从栈顶开始往下传播,关心这个级别日志的handler将会处理这条日志。全部的handler都会继承AbstractProcessingHandler这个抽象类,而且只须要实现里面的抽象方法write就能够了;同时这个抽象类会继承AbstractHandler这个抽象类,这个抽象类的构造函数有两个参数:level和bubble,前者表示该handler关心的最低日志级别,是个整型,后者表示日志被当前handler处理后是否接着向下传递。参照以下代码:函数

use Monolog\Logger;学习

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

$logger = new Logger('my_logger');

$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::INFO));

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::ERROR, false));

$logger->info('码王教育——多是最具含金量的IT培训');

如上这段代码,这条日志被ErrorLogHandler处理了,而且ErrorLogHandler的bubble参数设置为false,则日志不会被写入my_app.log中了。

第二个:formatter 设置日志格式

每一个handler能够单独设置记录的日志格式,AbstractHandler抽象类中有一个setFormatter方法,该参数接受一个FormatterInterface类型的参数。能够看到monolog自带的formatter都继承自NormalizerFormatter,该类实现了format和formatBatch方法。咱们修改上面的示例代码,让两个handler记录不一样格式的日志:

use Monolog\Logger;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

use Monolog\Formatter\JsonFormatter;

$logger = new Logger('my_logger');

$stream_handler = new StreamHandler(__DIR__.'/my_app.log', Logger::INFO);

$stream_handler->setFormatter(new JsonFormatter());

$logger->pushHandler($stream_handler);

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::INFO));

$logger->info('码王教育——多是最具含金量的IT培训');

此时能够看到my_app.log中记录的日志就变为了更方便解析的json格式了。

第三个:processor 日志处理器,用来给日志添加额外信息

存放processor的结构也是一个“栈”,意味着你也能够经过pushProcessor方法给一个Logger实例配置多个processor。咱们注意到,这里pushProcessor接受一个callable,也就是须要一个函数或者类方法,可是官方自带的这些processor都是类,随便点进去一个源码就会发现,其实这些类都用到了__invoke魔术方法,因此在被当作callable调用的时候会自动调用__invoke。咱们接着修改上面示例,给咱们的日志加上更多信息:

use Monolog\Logger;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

use Monolog\Formatter\JsonFormatter;

use Monolog\Processor\UidProcessor;

use Monolog\Processor\ProcessIdProcessor;

$logger = new Logger('my_logger');

$stream_handler = new StreamHandler(__DIR__.'/my_app.log', Logger::INFO);

$stream_handler->setFormatter(new JsonFormatter());

$logger->pushHandler($stream_handler);

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::INFO));

$logger->pushProcessor(new UidProcessor);

$logger->pushProcessor(new ProcessIdProcessor);

$logger->info('码王教育——多是最具含金量的IT培训');

再次执行这段代码就能看到,咱们在日的后面加上了uid和process_id。

经过以上的介绍相信你对monolog的使用和库的总体架构都有一个比较系统的认识了,这个时候你应该能发现,本身开发一个handler、formatter、processor是如此简单,只用实现两个接口,再写一个匿名函数,就能彻底控制本身的日志处理方式和日志格式了。

程序开发中很重要的一点就是像monolog这样易于扩展,要作到这点其实只要遵照如下几点:

一、依赖接口而不是实现(依赖反转、设计模式)

二、在有标准的时候遵照行业标准(psr)

在学习完了monolog的用法和设计架构以后,何不如今在mongolog之上实现一套记录日志到关系型数据的代码:)

更多的PHP进阶学习资料尽在码王信息,欢迎加群632109190进行讨论和学习

相关文章
相关标签/搜索