日志

未匹配的标注

日志

介绍

为了帮助你了解程序中正在发生什么, Laravel 提供了健壮的日志服务,允许你记录日志信息到文件,到系统错误日志,甚至到 Slack 通知你的整个团队。

Laravel 日志基于「 通道 」。每个通道代表一个具体的记录日志消息的方式。举例来说,single 通道会把日志记录到一个单独的文件里, slack 通道会发送日志信息到 Slack。基于它们的重要程度,日志可能会被写入到多个通道中去。

Laravel 使用了 Monolog 库, 它为各种强大的日志处理提供支持。Laravel 使配置这些处理器变得小菜一碟,它允许以混合和匹配的方式,自定义你的程序日志处理。

配置

所有的应用程序日志系统配置都位于 config/logging.php 配置文件中。这个文件允许你配置程序的日志通道,因此务必查看每个可用通道和它们的选项。我们将在下面回顾一些常用的选项。
Laravel 默认使用 stack 通道记录日志消息。 stack 通道被用于将多个日志通道集成到一个单独的通道中去。获得更多构建堆栈信息,请查看 以下文档

配置通道名

默认情况下,Monolog 用与当前环境匹配的 channel name 实例化,例如 productionlocal。要更改此值,请在通道配置中添加 name 选项:

'stack' => [
    'driver' => 'stack',
    'name' => 'channel-name',
    'channels' => ['single', 'slack'],
],

可用的通道驱动

每个日志通道都由一个驱动程序驱动。驱动程序确定日志消息的实际记录方式和位置。以下日志通道驱动程序在每个 Laravel 应用程序中都可用。大多数驱动程序的条目已经存在于应用程序的 config/logging.php 配置文件中,因此请务必查看此文件以熟悉其内容:

名称 说明
custom 调用指定工厂来创建通道的驱动程序
daily 一个基于 RotatingFileHandler 的每日循环的 Monolog 驱动程序
errorlog 基于 ErrorLogHandler 的 Monolog 驱动程序
monolog 可以使用任何支持的 Monolog 处理程序的 Monolog 工厂驱动程序
null 丢弃所有日志消息的驱动程序
papertrail 基于 SyslogUdpHandler 的 Monolog 驱动程序
single 单个基于文件或路径的记录器通道 (StreamHandler)
slack 基于 SlackWebhookHandler 的 Monolog 驱动程序
stack 该通道有助于创建 「多通道」 的包装器
syslog 基于 SyslogHandler 的 Monolog 驱动程序

技巧:查看 高级通道定制 文档,了解有关 monologcustom 驱动程序的更多信息。

驱动先决条件

配置单通道和每日通道

singledaily 通道有三个可选配置选项: bubblepermissionlocking

名称 说明 默认值
bubble 指示消息在处理后是否应跳转到其他通道 true
locking 尝试在写入日志文件之前锁定它 false
permission 日志文件的权限 0644

配置 Papertrail 通道

papertrail 通道需要 hostport 配置选项。你可以从 Papertrail 获得这些值。

配置 Slack 通道。

slack 通道需要 url 配置选项。URL应该与你为 Slack 团队配置 传入 webhook 的URL匹配。

默认情况下,Slack 将仅接收 critical 级别及更高级别的日志;但是,你可以在 config/logging.php 配置文件中通过修改 level Slack 日志通道的配置数组中的配置选项来进行调整。

构建日志堆栈

如前所述, 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 选项: syslogslack。因此,在记录消息时,这两个渠道都将有机会记录消息。但是,正如我们将在下面看到的,这些通道是否实际记录了消息可能取决于消息的重要性/「级别」。

日志级别

请注意上面示例中的 syslogslack 通道配置上的 level 配置选项。此选项确定消息必须由通道记录的最低「级别」。Monolog,为 Laravel 的日志服务提供了所有在 RFC 5424规范 中定义的日志级别: emergencyalertcriticalerrorwarningnoticeinfodebug

因此,假设我们使用 debug 方法记录了一条消息:

Log::debug('An informational message.');

根据我们的配置,syslog 通道会将消息写入系统日志。但是,由于错误消息不是 critical 或更高级别,因此不会将其发送到 Slack。但是,如果我们记录一个 emergency 消息,它将被发送到系统日志和 Slack,因为 emergency 级别高于两个通道的最低级别阈值:

Log::emergency('The system is down!');

写日志消息

你可以使用 Log facade 将信息写入日志。如前所述,记录器提供 RFC 5424规范 中定义的八个记录级别:emergencyalertcriticalerrorwarningnoticeinfodebug

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

你可以调用这些方法中的任何一种来记录相应级别的消息。默认情况下,该消息将被写入到你的 logging 配置文件所配置的默认日志通道:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Log;

class UserController extends Controller
{
    /**
     * 显示给定用户的配置信息
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        Log::info('Showing the user profile for user: '.$id);

        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}

语境信息

上下文数据数组也可以传递给 log 方法。 下文数据将被格式化并与日志消息一起显示:

Log::info('User failed to login.', ['id' => $user->id]);

写入到指定通道

有时您可能希望将消息记录到应用程序的默认通道以外的其他通道。您可以使用 Facade channel 上的方法 Log 来检索并登录到配置文件中定义的任何通道:

use Illuminate\Support\Facades\Log;

Log::channel('slack')->info('Something happened!');

如果要创建一个由多个通道组成的按需日志记录堆栈,则可以使用以下 stack 方法:

Log::stack(['single', 'slack'])->info('Something happened!');

Monolog 通道自定义

为通道自定义 Monolog

有时,你可能需要完全控制如何为现有通道配置 Monolog 。例如,你可能想为Laravel的内置 single 通道配置自定义 Monolog FormatterInterface

首先,在通道的配置上定义一个 tap 数组。 tap 数组应该包含一个类列表, 这些类应该有机会在独白实例创建后自定义 (或 「tap」 into) 这些类没有固定的存放位置,所以你可以在你的应用程序中创建一个目录来存放这些类:

'single' => [
    'driver' => 'single',
    'tap' => [App\Logging\CustomizeFormatter::class],
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

一旦你在你的通道上配置了 tap 选项,你就可以定义自定义你的 Monolog 实例的类了。这个类只需要一个方法:__invoke,它接收一个 Illuminate\Log\Logger 实例。Illuminate\Log\Logger 实例将所有方法调用代理到底层的 Monolog 实例:

<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * 自定义给定的记录器实例。
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}

技巧:你所有的 「tap」类都由 服务容器 解析,因此它们所需的任何构造函数依赖项都将自动注入。

创建 Monolog 处理器通道

Monolog 有多种 可用的处理器 ,而 Laravel 并没有为每一个都包含一个内置的通道。在某些情况下,您可能希望创建一个自定义通道,它仅仅是一个没有相应 Laravel 日志驱动程序的特定 Monolog 处理程序的实例。这些通道可以很容易地使用 monolog 驱动程序创建。

当使用 monolog 驱动程序时,handler 配置选项用于指定将实例化哪个处理程序。可选地,处理程序需要的任何构造函数参数都可以使用 with 配置选项指定:

'logentries' => [
    'driver'  => 'monolog',
    'handler' => Monolog\Handler\SyslogUdpHandler::class,
    'with' => [
        'host' => 'my.logentries.internal.datahubhost.company.com',
        'port' => '10000',
    ],
],

Monolog 格式化器

使用 monolog 驱动程序时,Monolog LineFormatter 将用作默认格式化程序。但是,你也可以使用 formatterformatter_with 配置选项来自定义传递给处理程序的格式化程序的类型:

'browser' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\BrowserConsoleHandler::class,
    'formatter' => Monolog\Formatter\HtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],

如果你使用的 Monolog 处理程序能够提供自己的格式化程序,则可以将 formatter 配置选项的值设置为 default

'newrelic' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\NewRelicHandler::class,
    'formatter' => 'default',
],

通过工厂创建通道

如果要定义一个完全自定义的通道,在其中可以完全控制Monolog的实例化和配置,则可以 customconfig/logging.php 配置文件中指定驱动程序类型。你的配置应包括一个 via 包含工厂类名称的选项,该名称将被调用以创建 Monolog 实例:

'channels' => [
    'example-custom-channel' => [
        'driver' => 'custom',
        'via' => App\Logging\CreateCustomLogger::class,
    ],
],

一旦配置了 custom 驱动程序通道,就可以定义将创建 Monolog 实例的类。此类仅需要一个 __invoke 方法,该方法应返回 Monolog 记录器实例。该方法将接收通道配置数组作为其唯一参数:

<?php

namespace App\Logging;

use Monolog\Logger;

class CreateCustomLogger
{
    /**
     * 创建一个自定义 Monolog 实例。
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        return new Logger(...);
    }
}

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
上一篇 下一篇
Summer
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
贡献者:6
讨论数量: 1
发起讨论 只看当前版本


文档的日志:通过工厂创建通道 疑问?
0 个点赞 | 1 个回复 | 问答 | 课程版本 8.5