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

由于一些历史原因,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之上实现一套记录日志到关系型数据的代码:)

https://www.cnblogs.com/mawang/p/6740862.html  (转自)

monolog 日志库相关推荐

  1. php monolog uid,php程序日志库——monolog 包的使用

    由于一些历史原因,php中并没有内建的日志接口,故长期以来也没一个功能完备并且应用广泛的日志库.在我的工作生涯中,如果系统需要记录一些应用日志的话,基本上就是封装一个日志类,然后把一些要记录的字段写入 ...

  2. 深度|从Go高性能日志库zap看如何实现高性能Go组件

    导语:zap是uber开源的Go高性能日志库.本文作者深入分析了zap的架构设计和具体实现,揭示了zap高效的原因.并且对如何构建高性能Go语言库给出自己的建议. 作者简介:李子昂,美图公司架构平台系 ...

  3. libslog---高性能开源C/C++多线程安全日志库

    Fromwiki: https://code.google.com/p/easynetwork/wiki/libslog libslog是一个基于linux的高性能开源C/C++多线程安全日志库.Ea ...

  4. 新写的c++日志库:log4K

    新写的c++日志库:log4K 网是开源的c/c++日志库也不少,但用起来总觉得不方便,于是动手写了一个C++日志框架Log4K. 测试代码: #include "log4k.h" ...

  5. android log耗性能吗,一个高性能的Android日志库

    clue 一个高性能的Android日志库. 为什么性能高 通常的Android日志库, 为了获取到class名, 方法名, 行号, 都是通过以下API实现的: StackTraceElement[] ...

  6. 日志库EasyLogging++学习系列(11)—— 共享日志库

    在前面的学习系列文章中,我们都是在单独的一个应用程序中使用 Easylogging++ 日志库.其实 Easylogging++ 日志库是可以共享给动态库.静态库以及应用程序共同使用的.在编写一些大型 ...

  7. 日志库EasyLogging++学习系列(10)—— 日志文件滚动

    在很多应用场合,我们是需要实现日志文件滚动的,特别是在一些长期运行的服务器程序中,如果把所有的日志都记录在一个文件之中,势必会造成日志文件越来越大.当日志内容很多的时候,万一哪天突然需要查询某个日志信 ...

  8. 日志库EasyLogging++学习系列(7)—— 记录方式详解

    在前面所列文章的演示代码中,其实已经展示了一部分记录日志的方式.为了使用方便,在 Easylogging++ 中,通过使用宏的集合来完成日志记录. 普通日志记录 对于普通的日志记录,我们可以选择以下两 ...

  9. 日志库EasyLogging++学习系列(6)—— 日志记录器

    所有的日志都是由日志记录器完成的,日志记录器使用唯一的 ID(大小写敏感)来标识.在 Easylogging++ 中默认了三个现有的日志记录器: 默认日志记录器,其 ID 为:default 性能日志 ...

最新文章

  1. 半吊子菜鸟学Web开发 -- PHP学习 4 --异常
  2. 跨国婚姻登记指南是怎样的一个流程呢??
  3. 休眠自动冲洗的黑暗面
  4. 笨方法“学习python笔记之列表
  5. java8的spliterator
  6. SSM框架入门学习记录
  7. 注册了Stack Overflow
  8. 吃糖果hdu2502
  9. linux监控http连接数,zabbix监控linux tcp连接数
  10. iOS开发UI篇—UIScrollView控件实现图片缩放功能
  11. nginx源码分析——filter模块
  12. Apache Commons Net 实现 FTP 上传/下载/删除/同步
  13. 【图像分割】基于matlab随机游走算法图像分割【含Matlab源码 149期】
  14. ug怎么画曲线_UG怎么画雨伞?ug曲面造型实例教程
  15. ardupilot 增加新的定点控制实现刹车
  16. 树莓派开发笔记(十):Qt读取ADC模拟量电压(ADS1115读取电压模拟量)
  17. 广域网技术-PPP协议
  18. 巧用位运算实现大小写转换
  19. charles证书信任设置
  20. dw常用标签_一个新人对于DW标签的理解

热门文章

  1. 教你如何使用安卓AS开发直播游戏类APP
  2. restful接口的原理
  3. Jmeter接口自动化总结
  4. VS2015 + WDK10
  5. python 公众号付费视频地址_python批量下载公众号内的视频
  6. 计算机编程图林先生,【电脑维修】台中林先生:我的电脑平均1週画面
  7. 用嵌套的循环结构完成右上左下直角三角形、菱形等各种图形的输出
  8. 信息管理毕业设计 SSM的在线音乐网站设计与实现(源码+论文)
  9. potPlayer-windows安装包,皮肤,配置及使用
  10. 吊打面试官之SQL面试题30问及答案