PHP Monolog 教程

PHP Monolog 教程展示了如何使用 Monolog 在 PHP 中进行日志记录。

记录

日志记录是将信息写入日志文件的过程,日志文件包含有关在操作系统,软件或通信中发生的各种事件的信息。

记录目的

完成记录是出于以下目的:

  • 信息收集
  • 故障排除
  • 产生统计资料
  • 稽核
  • 剖析

记录不仅限于识别软件开发中的错误。 它还可用于检测安全事件,监视策略违规,在出现问题时提供信息,查找应用瓶颈或生成使用情况数据。

要记录的事件

应记录的事件包括输入验证失败,身份验证和授权失败,应用错误,配置更改以及应用启动和关闭。

不记录的事件

不应记录的事件包括应用源代码,会话标识值,访问令牌,敏感的个人数据,密码,数据库连接字符串,加密密钥,银行帐户和持卡人数据。

记录最佳做法

以下是一些日志记录最佳做法:

  • 日志记录应该有意义。
  • 日志应包含上下文。
  • 测井应保持平衡; 它不应包含过多或过多的信息。
  • 记录消息应该是人类可以理解的,并且可以被机器解析。
  • 日志记录应在不同级别进行结构化和完成。
  • 测井应适应开发和生产。
  • 登录更复杂的应用应完成几个日志文件。

PHP Monolog

Monolog 是流行的 PHP 日志记录库。 它允许将日志发送到文件,套接字,收件箱,数据库和各种 Web 服务。 它实现了 PSR-3 接口。

$ composer req monolog/monolog

Monolog 结构

Monolog 记录器实例具有通道(名称)和处理程序的堆栈。 处理程序负责将消息保存到文件,数据库或将其发送到邮件。

记录的消息在处理程序堆栈中传播。 最后一个处理程序首先执行。 消息的进一步传播由bubble变量控制,该变量默认设置为true

消息记录是一条将要写入日志的信息,消息记录包含以下部分:

类型 描述
info string 日志消息。
level integer 日志消息的严重性。
level_name string 日志级别的字符串表示形式。
context array 随消息的构造传递任意数据。
channel string 此消息被登录到的频道。
datetime Monolog/DateTimeImmutable 消息记录的日期和时间。
extra array 处理器可在其中放置其他数据的占位符数组。

处理器是可用于处理日志消息的任何 PHP 可调用对象,它可以向记录中添加一些额外的数据。

context是数组数据,其中包含的附加信息不太适合主字符串。 上下文是日志记录方法的参数(例如info()warn())。

格式化程序用于格式化消息记录。

Monolog 日志级别

日志记录级别用于按紧急程度对日志消息进行分类。 Monolog 具有以下日志级别:

  • 调试-详细的调试信息
  • INFO-有趣的事件
  • 注意-正常但重要的事件
  • 警告-并非错误的特殊情况
  • 错误-不需要立即采取措施的运行时错误
  • 关键-关键条件
  • 警报-必须立即采取措施的事件
  • 紧急-紧急事件

日志级别较低的处理程序将不处理不太严重的日志。 通过将日志级别设置为 ERROR,我们将获得 ERROR 级别及更高级别的消息。

每个处理程序都指定了一个日志级别,默认值为DEBUG。 为了产生具有特定日志级别的消息,我们有包括info()warn()error()critical()的方法。 由于 Monolog 早于 PSR-3,因此它包含重复的方法(例如addInfo()addWarning())。

Monolog 简单示例

在第一个示例中,我们使用Streamhandler将消息记录到文件中。

simple.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

logger = new Logger('main');logger->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::DEBUG));

$logger->info('First message');

该示例将信息消息写入logs/app.log文件。

$logger = new Logger('main');

创建了一个名为main的新记录器。

$logger->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::DEBUG));

我们使用pushHandler()StreamHandler添加到记录器。 处理程序以 DEBUG 严重性将消息写入指定的文件。

$logger->info('First message');

我们使用info()方法记录一条信息消息。

$ cat logs\app.log
[2019-05-15 15:49:48] main.INFO: First message [] []

日志消息以当前日期时间开头,后面是日志通道名称和级别。 然后是消息记录,两对方括号是我们可以指定上下文和额外数据的位置。 我们可以使用 Monolog 格式化程序自定义此输出。

Monolog 控制台日志记录

我们可以将日志消息写入终端。

console_log.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

logger = new Logger('stderr');logger->pushHandler(new StreamHandler('php://stderr', Logger::WARNING));

$logger->warn('A warning message');

我们通过向StreamHandler指定php://stderr来写入控制台。

Monolog 上下文数组

Monolog 上下文数组允许在用户级级别将信息添加到消息记录中。

context_array.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

logger = new Logger('main');logger->pushHandler(new StreamHandler('php://stderr'));

$logger->info('Information message', ['user' => get_current_user()]);

info()方法的第二个参数是上下文数组,我们将当前用户添加到消息中。

$ php context_array.php
[2019-05-15 15:37:56] main.INFO: Information message {"user":"Jano"} []

Monolog 记录器处理程序堆栈

我们可以将多个处理程序添加到堆栈中。 最后添加的处理程序将首先执行。

handler_stack.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

main = new Logger('main');main->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log'));

main->pushHandler(new StreamHandler('php://stdout',level = Logger::DEBUG,
        bubble = true));main->info('Information message');

在示例中,我们有两个记录器处理程序:一个文件和一个控制台处理程序。 如果将$bubble更改为false,则消息将不会写入logs/app.log文件。

Monolog 定制处理器

可以向pushProcessor()添加自定义处理器。

custom_processor.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

logger = new Logger('main');logger->pushHandler(new StreamHandler('php://stderr'));

logger->pushProcessor(function (record) {
    record['extra']['user'] = get_current_user();

    returnrecord;
});

$logger->info('Information message');

在示例中,我们向处理器中的消息记录添加了一些额外的信息。 根据文档,上下文和额外数据之间的区别在于上下文是在用户区域中提供的,而额外数据仅是内部的,可以由处理器填充。

$ php custom_processor.php
[2019-05-15 17:24:48] main.INFO: Information message [] {"user":"Jano"}

额外的信息将添加到输出的末尾。

Monolog JsonFormatter

JsonFormatter以 JSON 格式写入记录。

json_formatter.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Formatter\JsonFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

logger = new Logger('main');formatter = new JsonFormatter();

stream = new StreamHandler(__DIR__ . '/logs/app-json.log');stream->setFormatter(formatter);logger->pushHandler(stream);logger->info('Information message', ['user' => get_current_user()]);

该示例使用JsonFormatter将信息消息以 JSON 格式写入文件。

$ cat logs\app-json.log
{"message":"Information message","context":{"user":"Jano"},"level":200,"level_name":"INFO",
"channel":"main","datetime":{"date":"2019-05-15 17:37:40.433222","timezone_type":3,
"timezone":"Europe/Berlin"},"extra":[]}

Monolog LineFormatter

LineFormatter将日志记录格式化为单行字符串。

line_format.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Processor\ProcessIdProcessor;

output = "[%datetime%] %channel%.%level_name%: %message% %context.user%\n";formatter = new LineFormatter(output);streamHandler = new StreamHandler('php://stdout');
streamHandler->setFormatter(formatter);

logger = new Logger('main');logger->pushHandler(streamHandler);logger->info('Information message from', ['user' => get_current_user()]);

在示例中,我们使用LineFormatter自定义消息记录。

$output = "[%datetime%] %channel%.%level_name%: %message% %context.user%\n";
$formatter = new LineFormatter($output);

我们创建一个自定义记录消息。 它包含日期时间,频道名称,级别名称,消息和上下文数据。

$streamHandler->setFormatter($formatter);

我们使用setFormatter()将格式化程序添加到处理程序中。

$ php line_format.php
[2019-05-15 17:43:36] main.INFO: Information message from Jano

Monolog 邮件日志消息

可以使用SwiftMailerHandler发送电子邮件

$ composer req swiftmailer/swiftmailer

对于此示例,我们需要安装swiftmailer/swiftmailer软件包。

注意: Gmail不适合测试应用程序。我们应该使用诸如Mailtrap或Mailgun之类的在线服务,或者使用由网络托管公司提供的SMTP服务器。

在我们的示例中,我们使用 Mailtrap 服务。

mail_log.php

<?php

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Handler\SwiftMailerHandler;

transporter = new Swift_SmtpTransport('smtp.mailtrap.io', 2525, 'tls');transporter->setUsername('3178491df14b6d');
transporter->setPassword('7c1d6fa59a5v08');mailer = new Swift_Mailer(transporter);message = new Swift_Message('Critical message');
message->setFrom(['approot@example.com' => 'App root']);message->setTo(['support@example.com' => 'Support']);

logger = new Logger('main');logger->pushHandler(new SwiftMailerHandler(mailer,message, Logger::CRITICAL));
$logger->critical('Could not connect to the database');

在示例中,我们使用SwiftMailerHandler将消息记录发送到邮件收件箱。

$transporter = new Swift_SmtpTransport('smtp.mailtrap.io', 2525, 'tls');
$transporter->setUsername('3178491df14b6d');
$transporter->setPassword('7c1d6fa59a5v08');

使用 Mailtrap 连接详细信息,我们构建了传输器。

$mailer = new Swift_Mailer($transporter);

创建了Swinf_Mailer

$message = new Swift_Message('Critical message');
$message->setFrom(['approot@example.com' => 'App root']);
$message->setTo(['support@example.com' => 'Support']);

创建了Swift_Message。 它包含从到字段。

$logger = new Logger('main');
$logger->pushHandler(new SwiftMailerHandler($mailer, $message, Logger::CRITICAL));
$logger->critical('Could not connect to the database');

我们将SwiftMailerHandler添加到记录器,并使用critical()创建关键消息。

您可能也对以下相关教程感兴趣: PHP Rakit 验证教程PHP PDO 教程PHP 教程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程