[ Laravel 5.6 文档 ] 基础组件 —— 日志

简介

为了帮助你了解更多关于应用中所发生的事情,Laravel 提供了强大的日志服务来记录日志信息到文件、系统错误日志、甚至是 Slack 以便通知整个团队。

在日志引擎之下,Laravel 集成了 Monolog 日志库以便提供各种功能强大的日志处理器,从而允许你通过它们来定制自己应用的日志处理。

配置

应用日志系统的所有配置都存放在配置文件 config/logging.php 中,该文件允许你配置应用的日志频道,因此请务必查看每个可用频道及其配置项。下面我们就来看看其中某些配置项。

默认情况下,Laravel 使用 stack 频道来记录日志信息,stack 频道被用于聚合多个日志频道到单个频道,更多关于构建 stack 的信息,请查看下面的文档

配置频道名称

默认情况下,Monolog 通过与当前环境匹配的「频道名」实例化,例如 productionlocal,要改变这个值,添加 name 项到频道配置:

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

配置 Slack 频道

slack 频道需要一个 url 配置项,这个 URL 需要和你配置的 Slack 团队请求 URL 相匹配。

构建日志堆栈

如上所述,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 配置项,这个配置项决定了日志信息被频道记录所必须达到的最低「级别」。为 Laravel 提供日志服务的 Monolog,支持定义在 RFC 5424规范中的所有日志级别:emergencyalertcriticalerrorwarningnoticeinfodebug

因此,假设我们使用 debug 方法来记录日志信息:

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

鉴于我们的配置,syslog 频道将会将信息记录到系统日志;不过,由于错误消息不是 critical 或更高级别,将不会发送到 Slack。但是,如果我们记录的是 emergency 级别的信息,就会被发送到系统日志和 Slack,因为 emergency 级别高于两个频道的最低级别门槛:

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

写入日志信息

你可以使用 Log 门面记录日志信息,如上所述,日志系统提供了定义在 RFC 5424 规范中的八种日志级别:emergencyalertcriticalerrorwarningnoticeinfodebug

Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);

因此,你可以调用其中的任意一个方法来记录相应级别的日志信息,默认情况下,信息会被写入到通过配置文件 config/logging.php 所配置的默认频道:

<?php

namespace App\Http\Controllers;

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

class UserController extends Controller
{
    /**
     * 显示指定用户的属性
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        Log::info('Showing user profile for user: '.$id);
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }
}

上下文信息

上下文数据也会以数组形式传递给日志方法,然后和日志信息一起被格式化和显示:

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

写入指定频道

有时候你可能希望将日志信息记录到某个频道而不是应用的默认频道。要实现这个目的,你可以使用 Log 门面上的 channel 方法来获取配置文件定义的频道并将日志写入进去:

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

如果你想要创建一个由多个频道组成的按需日志堆栈,可以使用 stack 方法:

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

为频道自定义 Monolog

有时候你可能需要在某个频道中完全控制 Monolog 的配置,例如,你可能想要为给定频道的处理器配置一个自定义的 Monolog FormatterInterface 实现。

作为开始,我们在频道的配置上定义一个 tap 数组,这个 tap 数组需要包含可以自定义创建后的 Monolog 实例的类列表:

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

在频道上配置好 tap 项后,就可以定义自定义 Monolog 实例的类了。这个类只需要一个获取 Illuminate\Log\Logger 实例的方法:__invokeIlluminate\Log\Logger 实例会代理所有调用底层 Monolog 实例的方法:

<?php

namespace App\Logging;

class CustomizeFormatter
{
    /**
     * Customize the given logger instance.
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(...);
        }
    }
}

注:所有「tap」类都通过服务容器解析,所以他们需要的所有构造函数依赖都会被自动注入。

创建自定义频道

如果你想要定义一个完整的自定义频道从而可以完全控制 Monolog 的实例化和配置,可以在配置文件 config/logging.php 中指定一个 custom 驱动类型。此外,你的配置中还要包含一个 via 项来指定被调用来创建 Monolog 实例的类:

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

配置好 custom 频道后,就可以定义创建 Monolog 实例的类了,这个类只需要一个返回 Monolog 实例的方法:__invoke

<?php

namespace App\Logging;

use Monolog\Logger;

class CreateCustomLogger
{
    /**
     * Create a custom Monolog instance.
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        return new Logger(...);
    }
}

学院君 has written 847 articles

终身学习者,Laravel学院院长

发表评论

标记为*的字段是必填项(邮箱地址不会被公开)

你可以使用这些HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>