ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # 日志 ## 简介 Laravel 使用[Monolog](https://github.com/Seldaek/monolog)库,它为各种强大的日志处理提供支持。Laravel 使配置这些处理程序变得简单,允许混合并匹配它们自定义的应用程序日志处理。 ## 配置 所有的应用程序日志系统配置都位于`config/logging.php`配置文件中。 默认情况下,Laravel 将使用`stack`去记录日志消息。`stack 通道被用来将多个日志通道聚合到一个单一的通道中。` #### 配置通道名称 默认情况下,Monolog 使用与当前环境匹配的『通道名称』进行实例化,比如`production`或者`local`。要改变这个值,需添加一个`name`选项到你的通道配置中: ``` // 新增 name 选项 'stack' => [ 'driver' => 'stack', 'name' => 'channel-name', 'channels' => ['single', 'slack'], ], ``` #### 可用的通道驱动 名称 | 描述 ------------- | ------------- `stack` | 一个便于创建『多通道』通道的包装器 `single` | 单个文件或者基于日志通道的路径 (`StreamHandler`) `daily` | 一个每天轮换的基于 Monolog 驱动的 `RotatingFileHandler` `slack` | 一个基于 Monolog 驱动的 `SlackWebhookHandler` `syslog` | 一个基于 Monolog 驱动的 `SyslogHandler` `errorlog` | 一个基于 Monolog 驱动的 `ErrorLogHandler` `monolog` | 一个可以使用任何支持 Monolog 处理程序的 Monolog 工厂驱动程序 `custom` | 一个调用指定工厂创建通道的驱动程序 #### 配置 Single 和 Daily 通道 `single`和`daily`通道包含三个可选配置项:`bubble`、`permission`和`locking`。 名称 | 描述 | 默认值 ------------- | ------------- | ------------- `bubble` | 消息处理后,指示消息是否推送到其他通道 | `true` `permission` | 日志文件权限 | `0644` `locking` | 写入之前尝试锁定日志文件 | `false` #### 配置 Slack 通道 `slack`通道需要`url`配置选项。这个 URL 应当与你为 Slack 团队配置的一个[incoming webhook](https://slack.com/apps/A0F7XDUAZ-incoming-webhooks)相匹配。 ### 构建日志堆栈 前面说过,`stack`驱动允许你在单一日志通道中整合多个通道。让我们通过一个产品级应用的配置实例来看看如果使用日志堆栈: ``` 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['syslog', 'slack'], ], 'syslog' => [ 'driver' => 'syslog', 'level' => 'debug', ], 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ], ], ``` 首先要注意的是`stack`通过借助它的`channels`选项聚合了另外两个通道:`syslog`和`slack`。因此,在记录日志消息时,这两个通道都有机会完成日志消息记录: #### 日志级别 请留意上面例子中`syslog`和`slack`中存在的`level`配置项。`level选项决定了需要被该通道记录的日志的最低「级别」`。Monolog (一个功能强劲的 Laravel 日志服务)接受定义在[RFC 5424 specification](https://tools.ietf.org/html/rfc5424)中的全部级别:**emergency**、**alert**、**critical**、**error**、**warning**、**notice**、**info**和**debug**。 假设我们使用`debug`方法记录日志消息: ``` Log::debug('An informational message.'); ``` 根据我们的配置,`syslog`通道将把该消息记录到系统日志;不过因为错误消息不是`critical`或更高级别,它将不会被发送到 Slack。如果我们记录一条`emergency`消息,它将被发送给系统日志和 Slack,因为`emergency`的级别高于两个通道的最低级别限制: ``` Log::emergency('The system is down!'); ``` ## 写日志消息 可以使用`Log`facade 将信息写入日志。 ``` use Illuminate\\Support\\Facades\\Log; Log::emergency($message); Log::alert($message); Log::critical($message); Log::error($message); Log::warning($message); Log::notice($message); Log::info($message); Log::debug($message); ``` #### 上下文信息 可以将上下文数据数组传递给日志方法。这些信息将被格式化,并与日志消息一直显示: ``` Log::info('User failed to login.', ['id' => $user->id]); ``` ### 写入指定通道 将消息写入到默认通道之外的通道中。 ``` // 写入slack通道 Log::channel('slack')->info('Something happened!'); // 创建一个由多通道构成的按需记录的堆栈 Log::stack(['single', 'slack'])->info('Something happened!'); ``` ## 高度自定义 Monolog 通道 [参考文档](https://learnku.com/docs/laravel/5.8/logging/3901#14f57e) ``` // 为通道自定义 Monolog // tap 数组包含自定义 Monolog 实例的类列表 'single' => [ 'driver' => 'single', 'tap' => [App\Logging\CustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ], // App/Logging/CustomizeFormatter.php <?php namespace App\Logging; class CustomizeFormatter { /** * 自定义给定的日志实例。 * * @param \Illuminate\Log\Logger $logger * @return void */ public function __invoke($logger) { foreach ($logger->getHandlers() as $handler) { $handler->setFormatter(...); } } } // 创建 Monolog 处理器通道 'logentries' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\SyslogUdpHandler::class, 'with' => [ 'host' => 'my.logentries.internal.datahubhost.company.com', 'port' => '10000', ], ], // Monolog 格式化 'browser' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\BrowserConsoleHandler::class, 'formatter' => Monolog\Formatter\HtmlFormatter::class, 'formatter_with' => [ 'dateFormat' => 'Y-m-d', ], ], 'newrelic' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\NewRelicHandler::class, 'formatter' => 'default', ], // 通过工厂创建渠道 'channels' => [ 'custom' => [ 'driver' => 'custom', 'via' => App\Logging\CreateCustomLogger::class, ], ], // App/Logging/CreateCustomLogger.php <?php namespace App\Logging; use Monolog\Logger; class CreateCustomLogger { /** * 创建一个 Monolog 实例. * * @param array $config * @return \Monolog\Logger */ public function __invoke(array $config) { return new Logger(...); } } ```