设为首页 收藏本站
查看: 582|回复: 0

[经验分享] 这可能是php世界中最好的日志库

[复制链接]

尚未签到

发表于 2017-12-30 21:50:14 | 显示全部楼层 |阅读模式
  由于一些历史原因,php中并没有内建的日志接口,故长期以来也没一个功能完备并且应用广泛的日志库。在我的工作生涯中,如果系统需要记录一些应用日志的话,基本上就是封装一个日志类,然后把一些要记录的字段写入到磁盘文件。
  这样就难免要一遍一遍的造轮子,并且在没有一个规范的情况下,记录下来的日志也是不方便分析的。但是希望读完本文后希望你们可以放弃自己造这种日志类的轮子了,因为几乎你不可能造得比我们今天要介绍的主角:monolog更圆。
  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中有几个很重要的概念:
  第一个:handler 日志管理器
  存放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这样易于扩展,要做到这点其实只要遵守以下几点:
  1、依赖接口而不是实现(依赖反转、设计模式)
  2、在有标准的时候遵守行业标准(psr)
  在学习完了monolog的用法和设计架构之后,何不现在在mongolog之上实现一套记录日志到关系型数据的代码:)
  更多的PHP进阶学习资料尽在码王信息,欢迎加群632109190进行讨论和学习

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-430134-1-1.html 上篇帖子: 原创:微信小程序调用PHP后台接口,解析纯html文本 下篇帖子: 偏执Code
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表