开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

PHP使用Monolog

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

$ php -v
php -v
PHP 8.1.2 (cli) (built: Aug  8 2022 07:28:23) (NTS)
...

我们使用PHP版本8.1.2。

记录

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

记录的目的

记录是为了以下目的:

  • 信息收集
  • 故障排除
  • 生成统计数据
  • 审计
  • 分析

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

要记录的事件

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

不记录的事件

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

记录最佳实践

以下是日志记录的一些最佳实践:

  • 日志应该有意义。
  • 日志应该包含上下文。
  • 日志应该是平衡的;它不应该包含太少或太多的信息。
  • 记录消息应该是人类可以理解的并且可以被机器解析。
  • 记录应该是结构化的并且在不同的级别完成。
  • 日志记录应适应开发和生产。
  • 应将更复杂的应用程序的日志记录到多个日志文件中。

PHP独白

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

$ composer req monolog/monolog

我们用composer安装Monolog。

独白结构

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

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

消息记录是将要写入日志的一条信息。消息记录有以下几个部分:

td>datetime
Key Type Description
message string 日志信息。
level int 日志消息的严重性。
level_name string 日志级别的字符串表示。
context array 构造消息时传递的任意数据。
channel string 这条消息记录到的频道。
Monolog\DateTimeImmutable 记录消息的日期和时间。
extra array 一个占位符数组,处理器可以在其中放置额外的数据。

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

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

Formatters用于格式化消息记录。

Monolog日志级别

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

  • DEBUG-详细的调试信息
  • INFO-有趣的事件
  • NOTICE-正常但重要的事件
  • WARNING-非错误的异常事件
  • ERROR-不需要立即采取行动的运行时错误
  • CRITICAL-关键条件
  • ALERT-必须立即采取行动的事件
  • EMERGENCY-紧急事件

较不严重的日志不会由具有较严重日志记录级别的处理程序处理。通过将日志级别设置为ERROR,我们会收到ERROR级别及更高级别的消息。

每个处理程序都指定了一个日志级别;默认是DEBUG。要生成具有特定日志级别的消息,我们有方法包括infowarnerror和关键。由于Monolog早于PSR-3,它包含重复的方法(例如addInfoaddWarning)。

独白简单例子

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

<?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控制台日志记录

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

<?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');

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

独白上下文数组

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

<?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日志处理程序栈

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

<?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添加自定义处理器。

<?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();

    return $record;
});

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

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

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

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

MonologJsonFormatter

JsonFormatter以JSON格式写入记录。

<?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":[]}

这是记录的消息。

MonologLineFormatter

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

<?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包。

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

<?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创建一条关键消息。

在本教程中,我们使用Monolog在PHP中进行日志记录。

列出所有PHP教程。

未经允许不得转载:我爱分享网 » PHP使用Monolog

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏