💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# PHP Monolog 教程 > 原文: [https://zetcode.com/php/monolog/](https://zetcode.com/php/monolog/) PHP Monolog 教程展示了如何使用 Monolog 在 PHP 中进行日志记录。 ## 记录 日志记录是将信息写入日志文件的过程。 日志文件包含有关在操作系统,软件或通信中发生的各种事件的信息。 ## 记录目的 完成记录是出于以下目的: * 信息收集 * 故障排除 * 产生统计数据 * 审计 * 性能分析 记录不仅限于识别软件开发中的错误。 它还可用于检测安全事件,监视策略违规,在出现问题时提供信息,查找应用瓶颈或生成使用情况数据。 ## 要记录的事件 应记录的事件包括输入验证失败,认证和授权失败,应用错误,配置更改以及应用启动和关闭。 ## 不记录的事件 不应记录的事件包括应用源代码,会话标识值,访问令牌,敏感的个人数据,密码,数据库连接字符串,加密密钥,银行帐户和持卡人数据。 ## 记录最佳做法 以下是一些日志记录最佳做法: * 日志记录应该有意义。 * 日志应包含上下文。 * 日志应保持平衡; 它不应包含过多或过多的信息。 * 记录消息应该是人类可以理解的,并且可以被机器解析。 * 日志记录应在不同级别进行结构化和完成。 * 日志应适应开发和生产。 * 记录更复杂的应用应产生几个日志文件。 ## PHP Monolog Monolog 是流行的 PHP 日志记录库。 它允许将日志发送到文件,套接字,收件箱,数据库和各种 Web 服务。 它实现了 PSR-3 接口。 ```php $ composer req monolog/monolog ``` 我们用 Composer 安装 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 具有以下日志级别: * `DEBUG` - 详细的调试信息 * `INFO` - 有趣的事件 * `NOTICE` - 正常但重要的事件 * `WARNING` - 并非错误的特殊情况 * `ERROR` - 不需要立即采取措施的运行时错误 * `CRITICAL` - 关键条件 * `ALERT` - 必须立即采取措施的事件 * `EMERGENCY` - 紧急事件 日志级别较低的处理器将不处理不太严重的日志。 通过将日志级别设置为`ERROR`,我们将获得`ERROR`级别及更高级别的消息。 每个处理器都指定了一个日志级别; 默认值为`DEBUG`。 为了产生具有特定日志级别的消息,我们有包括`info()`,`warn()`,`error()`和`critical()`的方法。 由于 Monolog 早于 PSR-3,因此它包含重复的方法(例如`addInfo()`或`addWarning()`)。 ## Monolog 简单示例 在第一个示例中,我们使用`Streamhandler`将消息记录到文件中。 `simple.php` ```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`文件。 ```php $logger = new Logger('main'); ``` 创建了一个名为`main`的新记录器。 ```php $logger->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::DEBUG)); ``` 我们使用`pushHandler()`将`StreamHandler`添加到记录器。 处理器以`DEBUG`严重性将消息写入指定的文件。 ```php $logger->info('First message'); ``` 我们使用`info()`方法记录一条信息消息。 ```php $ cat logs\app.log [2019-05-15 15:49:48] main.INFO: First message [] [] ``` 这是书面信息。 日志消息以当前日期时间开头。 后面是日志通道名称和级别。 然后是消息记录。 两对方括号是我们可以指定上下文和额外数据的位置。 我们可以使用 Monolog 格式化程序自定义此输出。 ## Monolog 控制台日志记录 我们可以将日志消息写入终端。 `console_log.php` ```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 <?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 $ php context_array.php [2019-05-15 15:37:56] main.INFO: Information message {"user":"Jano"} [] ``` 这是输出。 ## Monolog 记录器处理器栈 我们可以将多个处理器添加到栈中。 最后添加的处理器将首先执行。 `handler_stack.php` ```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 <?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'); ``` 在示例中,我们向处理器中的消息记录添加了一些额外的信息。 根据文档,上下文和额外数据之间的区别在于上下文是在用户区域中提供的,而额外数据仅是内部的,可以由处理器填充。 ```php $ php custom_processor.php [2019-05-15 17:24:48] main.INFO: Information message [] {"user":"Jano"} ``` 额外的信息将添加到输出的末尾。 ## Monolog `JsonFormatter` `JsonFormatter`以 JSON 格式写入记录。 `json_formatter.php` ```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 格式写入文件。 ```php $ 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 <?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`自定义消息记录。 ```php $output = "[%datetime%] %channel%.%level_name%: %message% %context.user%\n"; $formatter = new LineFormatter($output); ``` 我们创建一个自定义记录消息。 它包含日期时间,频道名称,级别名称,消息和上下文数据。 ```php $streamHandler->setFormatter($formatter); ``` 我们使用`setFormatter()`将格式化程序添加到处理器中。 ```php $ php line_format.php [2019-05-15 17:43:36] main.INFO: Information message from Jano ``` 这是一个示例输出。 ## Monolog 邮件日志消息 可以使用`SwiftMailerHandler`发送电子邮件 ```php $ composer req swiftmailer/swiftmailer ``` 对于此示例,我们需要安装`swiftmailer/swiftmailer`包。 > **注意**:Gmail 不是理想的测试应用。 我们应该使用诸如 Mailtrap 或 Mailgun 之类的在线服务,或者使用由网络托管公司提供的 SMTP 服务器。 在我们的示例中,我们使用 Mailtrap 服务。 `mail_log.php` ```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`将消息记录发送到邮件收件箱。 ```php $transporter = new Swift_SmtpTransport('smtp.mailtrap.io', 2525, 'tls'); $transporter->setUsername('3178491df14b6d'); $transporter->setPassword('7c1d6fa59a5v08'); ``` 使用 Mailtrap 连接详细信息,我们构建了传输器。 ```php $mailer = new Swift_Mailer($transporter); ``` 创建了`Swinf_Mailer`。 ```php $message = new Swift_Message('Critical message'); $message->setFrom(['approot@example.com' => 'App root']); $message->setTo(['support@example.com' => 'Support']); ``` 创建了`Swift_Message`。 它包含从到字段。 ```php $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/rakitvalidation/), [PHP PDO 教程](/php/pdo/), [PHP 教程](/lang/php/)或列出[所有 PHP 教程。](/all/#php) 在本教程中,我们使用 Monolog 在 PHP 中进行日志记录。