github地址:https://github.com/Seldaek/monolog

使用 Monolog

  • 安装
  • 核心概念
  • 日志级别
  • 配置一个日志服务
  • 为记录添加额外的数据
  • 使用通道
  • 自定义日志格式

Monolog是php下比较全又容易扩展的记录日志组件。目前有包括Symfony 、Laravel、 CakePHP等诸多知名php框架都内置了Monolog。

Monolog可以把你的日志发送到文件,sockets,收件箱,数据库和各种web服务器上。一些特殊的组件可以给你带来特殊的日志策略。

安装

Monolog 在 Packagist (monolog/monolog) 上可用,并且可以通过 Composer 安装:

composer require monolog/monolog

如果你不使用 Composer, 那你可以从 GitHub 上获取代码,然后使用任何兼容 PSR-0 的自动加载器(比如Symfony2 ClassLoader 组件)来加载 Monolog 的类

核心概念

每一个日志服务实例 (Logger) 都有一个通道(名称),并有一个处理器 (Handler)栈. 无论何时你添加一条 记录 到对应的日志服务实例,这个处理器栈将被遍历一遍:每个处理器都将依次决定是否要处理这条记录,而如果要处理,则遍历结束(译注:类似DOM事件冒泡)。

这样子可以创建非常灵活的日志配置。比如一个 StreamHandler 可以把所有日志都写入磁盘,而上面加个MailHandler 可以把错误日志作为邮件发送出去。处理器还有一个 $bubble 属性定义了是否屏蔽某条记录或者处理了某条记录。在这个示例中,配置 MailHandler 的 $bubble 参数为 false 则意味着 MailHandler 将不会把自己已处理过的记录继续冒泡给 StreamHandler.

你可以创建许多日志服务实例(Logger),每一个则定义一个通道(比如数据库、请求、路由...)。而每一个日志服务实例都可以组合各种各样的处理器,可以共享处理器也可以不共享。这个通道将会在日志中反映出来,从而允许你可以很容易地查看或者筛选记录。

每一个处理还会有一个格式化器(Formatter)。如果你没有配置一个,则一个有意义的默认的格式化器将被创建。格式化器用来规范化并格式化输入的记录,以便处理器能输出一些有用的信息。

不支持自定义的严重性级别。只支持使用RFC 5424中定义的八个级别(调试/Debug、信息/Info、提示/Notice、警告/Warning、错误/Error、严重/Critical、警报/Alert、紧急/Emergency)来作为基本的筛选目的。不过,如果为了排序或者其他需要灵活性的使用场景,你可以添加加工程序(Processor)从而可以在(处理器)处理前添加额外的信息(标签、用户IP...)。

日志级别

Monolog 支持一下 RFC 5424 中的日志级别:

  • 调试/DEBUG (100): 详细的调试信息。
  • 信息/INFO (200): 有意义的事件,比如用户登录、SQL日志。
  • 提示/NOTICE (250): 正常但是值得注意的事件。
  • 警告/WARNING (300): 异常事件,但是并不是错误。比如使用了废弃了的API,错误地使用了一个API,以及其他不希望发生但是并非必要的错误。
  • 错误/ERROR (400): 运行时的错误,不需要立即注意到,但是需要被专门记录并监控到。
  • 严重/CRITICAL (500): 边界条件/危笃场景。比如应用组件不可用了,未预料到的异常。
  • 警报/ALERT (550): 必须立即采取行动。比如整个网站都挂了,数据库不可用了等。这种情况应该发送短信警报,并把你叫醒。
  • 紧急/EMERGENCY (600): 紧急请求:系统不可用了。

配置一个日志服务

这里有一个基本的配置,可以记录日志到文件,并在 DEBUG 级别下记录到 firephp 中:

<?php

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler; // 创建日志服务
$logger = new Logger('my_logger'); // 添加一些处理器
$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
$logger->pushHandler(new FirePHPHandler()); // 现在你就可以用日志服务了
$logger->info('My logger is now ready');

解释一下。第一步是创建日志服务实例,这个实例后将在代码中用到。唯一的参数是通道的名称,它在你有多个日志服务实例的时候很有用。(更多详情参见下面)

这个日志服务实例自己是不是知道如何处理一条日志记录的。它把记录代理给了一些处理器。上面的代码中注册了两个处理器到栈中,以便允许使用两种不同的方式来处理日志记录。

注意,FirePHPHandler 是被先调用的,因而它被添加到了栈顶。这允许你临时添加一个禁止冒泡的处理器从而允许你覆盖其他配置的日志(处理器)。

如果你单独使用 Monolog, 并且在寻找一种简单的方式来配置许多处理器,那可以用
theorchard/monolog-cascade 。
它可以帮你使用PHP数组、YAML或者JSON来构建复杂的日志配置。

为记录添加额外的数据

Monolog 提供了两种不同的方式来为简单的文本消息增加额外的信息

使用上下文(context)

第一种方式是使用上下文(context),这允许你在传递记录的时候传递一个数组格式的数据:

<?php
$logger->info('Adding a new user', array('username' => 'Seldaek'));

简单的处理器(比如StreamHandler)将只是把数组转换成字符串。而复杂的处理器则可以利用上下文的优点(如 FirePHP 则将以一种优美的方式显示数组)。

使用加工程序(Processor)

第二种方式是使用加工程序来为所有的记录添加额外数据。加工程序可以是任何可以调用的函数。
加工程序接收日志记录作为参数,并且需要在修改了extra字段后再返回日志记录。让我们来写一个添加一些假数据的加工程序:

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

Monolog提供了一些内置的加工程序,你可以在你的项目中使用它们。

小技巧:加工程序可以被注册到一个特定的处理器上而不是直接在日志服务实例上,从而可以只在对应的处理器上生效。

使用通道

通道是一种非常棒的方式来区分是应用的哪个部分的日志被记录下来的。这通常在大型项目中非常有用(而且被Symfony2的MonologBundle所使用)。

假设有两个日志服务实例共享了一个处理器,这个处理器将日志写入单个日志文件。通道则将允许你来区分是哪个日志服务实例记录了哪条日志。你可以很简单地通过通道来筛选日志。

<?php

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler; // 创建一些处理器
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
$firephp = new FirePHPHandler(); // 创建应用的主要日志服务实例
$logger = new Logger('my_logger');
$logger->pushHandler($stream);
$logger->pushHandler($firephp); // 使用另外的通道来创建安全相关的日志服务示例
$securityLogger = new Logger('security');
$securityLogger->pushHandler($stream);
$securityLogger->pushHandler($firephp); // 或者克隆第一个,只是改变下通道
$securityLogger = $logger->withName('security');

自定义日志格式

在Monolog中,可以很简单地来自定义日志的格式,无论是写入文件、套接字、邮件、数据库还是其他处理器。大多数处理器都是用 $record['formatted'] 这个值来自动写入日志设备。这个值依赖格式化器的配置。你可以选择预定义的格式化器类,也可以自己写一个(比如一个可读的多行文本文件)。

想要配置一个预定义的格式化器类,可以直接把它设置为处理器的字段:

// 默认的日期格式是 "Y-m-d H:i:s"
$dateFormat = "Y n j, g:i a";
// 默认的输出格式是 "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
$output = "%datetime% > %level_name% > %message% %context% %extra%\n";
// 最后创建一个格式化器
$formatter = new LineFormatter($output, $dateFormat); // 创建一个处理器
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
$stream->setFormatter($formatter); // 将其绑定到日志服务对象上
$securityLogger = new Logger('security');
$securityLogger->pushHandler($stream);

你还可以在多个处理器之间复用同一个格式化器,并且在多个日志服务实例间共享这些处理器

转 https://www.jianshu.com/p/b99dc5c3b760

Monolog - Logging for PHP的更多相关文章

  1. Monolog - Logging for PHP 5.3+

    Monolog 是PHP的一个日志类库.相比于其他的日志类库,它有以下的特点: 功能强大.可以把日志发送到文件.socket.邮箱.数据库和各种web services. 遵循 PSR3 的接口规范. ...

  2. 记一次Monolog的BufferHandler使用

    laravel中可以设置自定义的日记channel(config/logging中设置),按照laravel-china的一篇文章,把log按一定格式并且以批量的方式写入日志文件: https://l ...

  3. 记一次monolog的RotatingFileHandler使用

    需求如下: 1.需要一种日记格式,能把同一次请求的日记归在一起,请求间的日记以空行隔开,即使并发操作也不会像laravel默认的日记一样很"被动"的记录(不同请求的日记可能被交替记 ...

  4. Logging with PSR-3 to Improve Reusability

    可以用composer的autoload来,导入自己写的类库.   composer dump-autoload -o  ----------------> 改成 composer update ...

  5. Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

    学习架构探险,从零开始写Java Web框架时,在学习到springAOP时遇到一个异常: "C:\Program Files\Java\jdk1.7.0_40\bin\java" ...

  6. Oracle补全日志(Supplemental logging)

    Oracle补全日志(Supplemental logging)特性因其作用的不同可分为以下几种:最小(Minimal),支持所有字段(all),支持主键(primary key),支持唯一键(uni ...

  7. Java程序日志:java.util.logging.Logger类

    一.Logger 的级别 比log4j的级别详细,全部定义在java.util.logging.Level里面.各级别按降序排列如下:SEVERE(最高值)WARNINGINFOCONFIGFINEF ...

  8. python 学习笔记 -logging模块(日志)

    模块级函数 logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root loggerlogging.debug().logging.info().lo ...

  9. python logging colorlog

    import logging LOG_LEVEL = logging.NOTSET LOGFORMAT = "[%(log_color)s%(levelname)s] [%(log_colo ...

随机推荐

  1. 编程体系结构(03):Java集合容器

    本文源码:GitHub·点这里 || GitEE·点这里 一.集合容器简介 集合容器是Java开发中最基础API模块,通常用来存储运行时动态创建的元素,基本特点如下: 泛型特点,存储任意类型对象: 动 ...

  2. 11.redis cluster的hash slot算法和一致性 hash 算法、普通hash算法的介绍

    分布式寻址算法 hash 算法(大量缓存重建) 一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡) redis cluster 的 hash slot 算法 一.hash 算法 来了一 ...

  3. 【源码讲解】Spring事务是如何应用到你的业务场景中的?

    初衷 日常开发中经常用到@Transaction注解,那你知道它是怎么应用到你的业务代码中的吗?本篇文章将从以下两个方面阐述Spring事务实现原理: 解析并加载事务配置:本质上是解析xml文件将标签 ...

  4. netty字节分包

    高并发压测时,发现来自网关的消息出现粘包现象:分包就是势在必行的 前置和处理平台(暂时)使用netty通话,由于都是服务器平台使用DelimiterBasedFrameDecoder来解决分包 和网关 ...

  5. ribbon源码(1) 概述

    ribbon的核心功能是提供客户端在进行网络请求时负载均衡的能力.主要有以下几个模块: 负载均衡器模块 负载均衡器模块提供了负载均衡能力,详细参见ribbon源码之负载均衡器. 配置模块 配置模块管理 ...

  6. 关于微信小程序官网的使用

    我们在看微信支付相关的东西的时候,会发现有些想找的地址不好找,,没看到入口,接下来我就是整理了一下 链接: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa ...

  7. TKE 集群组建最佳实践

    Kubernetes 版本 Kubernetes 版本迭代比较快,新版本通常包含许多 bug 修复和新功能,旧版本逐渐淘汰,建议创建集群时选择当前 TKE 支持的最新版本,后续出新版本后也是可以支持 ...

  8. Oracle学习(十二)标量函数

    UCASE()大写转换  LCASE()小写转换 --把查询结果对应的列进行大写转换 SELECT UCASE(列) FROM 表; --把查询结果对应的列进行小写转换 SELECT LCASE(列) ...

  9. 牛客在线习题:链表的k各节点翻转

    题目描述 将给出的链表中的节点每\ k k 个一组翻转,返回翻转后的链表如果链表中的节点数不是\ k k 的倍数,将最后剩下的节点保持原样你不能更改节点中的值,只能更改节点本身.要求空间复杂度 \ O ...

  10. Python-生成器函数(协程实现底层原理)-yield

    yield 1. 函数执行的时候,找到yield关键字,则会标记这个函数,返回生成器对象 2. Python解释器会记录最近一次函数中yield位置 3. 生成器对象也是分配在栈堆上 4. 通过yie ...