日志神器Monolog自定义日志操作


monolog是PHP的一个日志类库,功能强大,扩展性很强,可以通过Handler、Formatter和Processor进行非常方便的扩展和自定义.

安装方法不再累赘描述,网上资料大把,这里主要介绍下如何通过Handler、Formatter和Processor来自定义一些日志需求.

该类库的作者介绍了核心的概念,具体点这里查看:传送门

翻译过来就是:

  1. 每一个Logger实例都包含一个频道名(channel)和handler的堆栈。当你添加一条记录时,记录会依次通过handler堆栈的处理。而每个handler也可以决定是否把记录传递到下一个堆栈里的下一个handler。

  2. 通过handler,我们可以实现一些复杂的日志操作。例如我们把StreamHandler放在堆栈的最下面,那么所有的日志记录最终都会写到硬盘文件里。同时我们把MailHandler放在堆栈的最上面,通过设置日志等级把错误日志通过邮件发送出去。Handler里有个$bubble属性,这个属性定义了handler是否拦截记录不让它流到下一个handler。所以如果我们把MailHandler的$bubble参数设置为false,则出现错误日志时,日志会通过MailHandler发送出去,而不会经过StreamHandler写到硬盘上。

  3. Logger可以创建多个,每个都可以定义自己的频道名和handler堆栈。handler可以在多个Logger中共享。频道名会反映在日志里,方便我们查看和过滤日志记录。

  4. 如果没有指定日志格式(Formatter),Handler会使用默认的Formatter。

  5. 日志的等级不能自定义,目前使用的是RFC 5424里定义的8个等级:debug、info、notice、warning、error、critical、alert和emergency。如果对日志记录有其他的需求,可以通过Processor对日志记录添加内容。


日志等级
DEBUG(100): 详细的debug信息。
INFO(200): 关键事件。
NOTICE(250): 普通但是重要的事件。
WARNING(300): 出现非错误的异常。
ERROR(400): 运行时错误,但是不需要立刻处理。
CRITICA(500): 严重错误。
EMERGENCY(600): 系统不可用。


用法示例:

<?php
use Monolog/Logger;
use Monolog/Handler/StreamHandler;
use Monolog/Handler/FirePHPHandler;
// 创建Logger实例
$logger = new Logger('my_logger');
// 添加handler
$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
$logger->pushHandler(new FirePHPHandler());
// 开始使用
$logger->addInfo('My logger is now ready');

Logger实例本身并不知道如何处理日志记录,它是通过handler进行处理的。handler可以设置多个,例如上面的例子设置了两个handler,可以对日志记录进行两种不同方式的处理。 需要注意的是,由于handler是采用堆栈的方式保存,所以后面添加的handler位于栈顶,会首先被调用。

重点来了,如何自定义处理日志记录呢?

通过使用Processor把日志记录当做参数,经过处理后返回处理过的日志内容(当然也可以通过写自定义的handler来实现),Processor可以是任何可调用的方法(回调)。它们接受$record作为参数,然后返回它($record),返回之前,即是我们添加额外信息的操作,在这里,这个操作是改变$record的extra key的值。像这样:

$logger->pushProcessor(function ($record) { 
    $record['extra']['dummy'] = 'Hello world!'; 
    return $record;
});

Monolog 提供了一些内置的 processors,详细可以看:dedicated chapter

上一篇

评论



分享

我的公众号

恩波的公众号

最新加入

最新评论

dreamer: 求邀请码1079623171@qq.com 查看原文 06月20日 09:03
恩波: 时隔2年多了,目前微信卡券估计已经变了好多了,不好意思啊 查看原文 06月01日 15:33
lwj: 你好,我刚看了你发的这个帖子,不知道现在评论是否能看到。我现在在做这个功能,可以用。但我这还有个需求就是,可以推送多张,我在cardList里,把需要推送的卡券,都添加上了,微信端页面也显示正确,有个领取按钮,但可以领取多次,每次卡包里多一张,而且这张是列表上的第一张 。。请问,你有没有遇到过 推送多张的情况 查看原文 05月15日 14:29
roly: 另外添加卡券接口的参数cardId: "xxxxxxxxxxxxxxxxxxxxxx", cardExt: '{"timestamp":"1426222398","signature":"fdd892770eb681e925f92acb9015c75107b2227a"}' 是通过自己服务获取以上参数 还是用js在html5页面直接生产签名参数? 查看原文 05月12日 16:41
roly: 您好,请问怎么查询当前用户卡券是否领取状态? 查看原文 05月12日 16:20

赞助商