使用 Laravel 在 Stdout 和 Stderr 之间拆分日志级别
2024 年 10 月 1 日
您是否曾想过在 Laravel 中记录特定级别?当然,您可以使用
level
配置选项来指定
最低限度
级别来记录,但如果你只想要
Debug
和
Info
日志是否进入特定的记录器?
假设你正在编写一个 CLI,并希望将日志记录拆分为
stdout
和
stderr
。使用 Laravel Zero 或 Artisan 之类的程序,您可以使用以下命令来演示仅将 stderr 日志发送到某处:
php artisan my-command 2> storage/logs/stderr.log
[2024-10-01 02:48:34] development.INFO: Daemon started.
[2024-10-01 02:48:34] development.INFO: The daemon has run 1 times.
[2024-10-01 02:48:37] development.INFO: The daemon has run 2 times.
[2024-10-01 02:48:40] development.INFO: The daemon has run 3 times.
[2024-10-01 02:48:43] development.INFO: The daemon has run 4 times.
然后 stderr 日志可能看起来像下面这样:
[2024-10-01 02:48:49] development.ERROR: The daemon has run too many times. (6 times now, come on!)
[2024-10-01 02:48:52] development.ERROR: The daemon has run too many times. (7 times now, come on!)
[2024-10-01 02:48:55] development.ERROR: The daemon has run too many times. (8 times now, come on!)
[2024-10-01 02:48:58] development.ERROR: The daemon has run too many times. (9 times now, come on!)
[2024-10-01 02:49:01] development.ERROR: The daemon has run too many times. (10 times now, come on!)
[2024-10-01 02:49:04] development.ERROR: The daemon has run too many times. (11 times now, come on!)
[2024-10-01 02:49:07] development.ERROR: The daemon has run too many times. (12 times now, come on!)
[2024-10-01 02:49:10] development.ERROR: The daemon has run too many times. (13 times now, come on!)
[2024-10-01 02:49:13] development.ERROR: The daemon has run too many times. (14 times now, come on!)
配置 Laravel 过滤日志级别
配置 Laravel 的记录器来分割日志的技巧是使用 Monolog 的 过滤处理器 ,它只允许给定级别的记录通过包装的处理程序。一个直接的示例可能如下所示:
use Monolog\Handler\FilterHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
// Using minimum and maximum level parameters
$handler = new FilterHandler(
handler: new StreamHandler('php://stdout'),
minLevelOrList: Level::Debug,
maxLevel: Level::Info,
);
// Using a list
$handler = new FilterHandler(
handler: new StreamHandler('php://stdout'),
minLevelOrList: [Level::Debug, Level::Info]
);
我使用了命名参数来帮助说明如何在 Laravel 中配置 FilterHandler
logging.php
配置文件。我们可以更改
stderr
和
stdout
使用以下配置记录通道(或创建新通道),使用
stack
司机:
<?php
return [
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => explode(',', env('LOG_STACK', 'stdout,stderr')),
'ignore_exceptions' => false,
],
'stdout' => [
'driver' => 'monolog',
'handler' => \Monolog\Handler\FilterHandler::class,
'formatter' => env('LOG_STDOUT_FORMATTER'),
'with' => [
'handler' => fn () => new StreamHandler('php://stdout'),
'minLevelOrList' => [Monolog\Level::Debug, Monolog\Level::Info],
],
'processors' => [PsrLogMessageProcessor::class],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
'level' => 'notice',
'processors' => [PsrLogMessageProcessor::class],
],
],
];
注意
with
键是否与 FilterLogger 构造函数命名参数相匹配?
stdout
记录器将记录调试和信息日志,而
stderr
记录器有
level
设置
notice
捕获任何 CLI 错误(通知或更高版本)。
我还想指出,Monolog 接受 Closure 来
FilterHandler
处理程序,以便包装
StreamHandler
直到使用日志通道时才会创建实例:
'handler' => fn () => new StreamHandler('php://stdout'),
当我们将日志从容器发送到日志服务时,以这种方式捕获日志对于无头/守护进程 CLI 命令很有帮助。例如,使用 JSON 格式化错误日志以供 DataDog 等服务使用。以下是您可能拥有的环境设置示例,如下所示
compose.yaml
文件:
services:
cli:
build:
context: .
dockerfile: build/Dockerfile
# Do not output any messages to the console.
# Only logs will be sent.
command: ["daemon", "--quiet"]
environment:
LOG_CHANNEL: "stack"
LOG_LEVEL: "info"
LOG_STACK: "stdout,stderr"
LOG_STDOUT_FORMATTER: "\\Monolog\\Formatter\\JsonFormatter"
LOG_STDERR_FORMATTER: "\\Monolog\\Formatter\\JsonFormatter"
Monolog 有很多
处理程序、格式化程序和处理器
您可以在 Laravel 中配置可用的功能,并且所有常见用例都已在
logging.php
配置文件。
您可以在以下位置了解有关 Laravel 应用程序登录的更多信息 官方文档 。
帖子 使用 Laravel 在 Stdout 和 Stderr 之间拆分日志级别 首先出现在 Laravel 新闻 。
加入 Laravel 时事通讯 获取最新信息 类似这样的 Laravel 文章将直接发送到您的收件箱。