Skip to content
赞助商
虚位以待
赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

错误与日志记录

介绍

当你开始一个新的 Laravel 项目时,错误和异常处理已经为你配置好了。App\Exceptions\Handler 类是所有由应用程序触发的异常被记录并呈现给用户的地方。我们将在本文档中更深入地探讨这个类。

对于日志记录,Laravel 使用 Monolog 库,该库提供了对多种强大日志处理程序的支持。Laravel 为你配置了其中的几个处理程序,允许你在单个日志文件、旋转日志文件或将错误信息写入系统日志之间进行选择。

配置

错误详情

config/app.php 配置文件中的 debug 选项决定了实际向用户显示多少错误信息。默认情况下,此选项设置为遵循存储在 .env 文件中的 APP_DEBUG 环境变量的值。

对于本地开发,你应该将 APP_DEBUG 环境变量设置为 true。在生产环境中,此值应始终为 false。如果在生产中将此值设置为 true,你可能会将敏感的配置值暴露给应用程序的最终用户。

日志存储

开箱即用,Laravel 支持将日志信息写入 single 文件、daily 文件、syslogerrorlog。要配置 Laravel 使用哪种存储机制,你应该修改 config/app.php 配置文件中的 log 选项。例如,如果你希望使用每日日志文件而不是单个文件,你应该将 app 配置文件中的 log 值设置为 daily

php
'log' => 'daily'

最大每日日志文件

使用 daily 日志模式时,Laravel 默认只保留五天的日志文件。如果你想调整保留文件的数量,可以在 app 配置文件中添加 log_max_files 配置值:

php
'log_max_files' => 30

日志严重级别

使用 Monolog 时,日志消息可能具有不同的严重级别。默认情况下,Laravel 将所有日志级别写入存储。然而,在生产环境中,你可能希望通过在 app.php 配置文件中添加 log_level 选项来配置应记录的最低严重级别。

一旦配置了此选项,Laravel 将记录所有大于或等于指定严重级别的日志。例如,默认的 log_levelerror 将记录 errorcriticalalertemergency 消息:

php
'log_level' => env('APP_LOG_LEVEL', 'error'),

NOTE

Monolog 识别以下严重级别 - 从最不严重到最严重:debuginfonoticewarningerrorcriticalalertemergency

自定义 Monolog 配置

如果你希望完全控制 Monolog 在应用程序中的配置,可以使用应用程序的 configureMonologUsing 方法。你应该在 bootstrap/app.php 文件中 $app 变量返回之前调用此方法:

php
$app->configureMonologUsing(function ($monolog) {
    $monolog->pushHandler(...);
});

return $app;

异常处理器

报告方法

所有异常都由 App\Exceptions\Handler 类处理。此类包含两个方法:reportrender。我们将详细检查这两个方法。report 方法用于记录异常或将其发送到外部服务,如 BugsnagSentry。默认情况下,report 方法只是将异常传递给基类,在那里记录异常。然而,你可以随意记录异常。

例如,如果你需要以不同的方式报告不同类型的异常,可以使用 PHP 的 instanceof 比较运算符:

php
/**
 * 报告或记录异常。
 *
 * 这是将异常发送到 Sentry、Bugsnag 等的好地方。
 *
 * @param  \Exception  $exception
 * @return void
 */
public function report(Exception $exception)
{
    if ($exception instanceof CustomException) {
        //
    }

    return parent::report($exception);
}

按类型忽略异常

异常处理器的 $dontReport 属性包含一个异常类型数组,这些类型的异常不会被记录。例如,由 404 错误以及其他几种类型的错误导致的异常不会写入日志文件。你可以根据需要将其他异常类型添加到此数组中:

php
/**
 * 不应报告的异常类型列表。
 *
 * @var array
 */
protected $dontReport = [
    \Illuminate\Auth\AuthenticationException::class,
    \Illuminate\Auth\Access\AuthorizationException::class,
    \Symfony\Component\HttpKernel\Exception\HttpException::class,
    \Illuminate\Database\Eloquent\ModelNotFoundException::class,
    \Illuminate\Validation\ValidationException::class,
];

渲染方法

render 方法负责将给定的异常转换为应发送回浏览器的 HTTP 响应。默认情况下,异常被传递给基类,基类为你生成响应。然而,你可以检查异常类型或返回自己的自定义响应:

php
/**
 * 将异常渲染为 HTTP 响应。
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $exception)
{
    if ($exception instanceof CustomException) {
        return response()->view('errors.custom', [], 500);
    }

    return parent::render($request, $exception);
}

HTTP 异常

某些异常描述来自服务器的 HTTP 错误代码。例如,这可能是一个 "页面未找到" 错误 (404)、一个 "未授权错误" (401) 或甚至是开发人员生成的 500 错误。为了从应用程序的任何地方生成这样的响应,你可以使用 abort 辅助函数:

php
abort(404);

abort 辅助函数将立即引发一个异常,该异常将由异常处理器渲染。可选地,你可以提供响应文本:

php
abort(403, 'Unauthorized action.');

自定义 HTTP 错误页面

Laravel 使得为各种 HTTP 状态代码显示自定义错误页面变得容易。例如,如果你希望自定义 404 HTTP 状态代码的错误页面,请创建一个 resources/views/errors/404.blade.php。此文件将在应用程序生成的所有 404 错误时提供。此目录中的视图应命名为与其对应的 HTTP 状态代码相匹配。abort 函数引发的 HttpException 实例将作为 $exception 变量传递给视图。

日志记录

Laravel 在强大的 Monolog 库之上提供了一个简单的抽象层。默认情况下,Laravel 被配置为在 storage/logs 目录中为你的应用程序创建一个日志文件。你可以使用 Log facade 将信息写入日志:

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

记录器提供了 RFC 5424 中定义的八个日志级别:emergencyalertcriticalerrorwarningnoticeinfodebug

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

上下文信息

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

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

访问底层 Monolog 实例

Monolog 有多种额外的处理程序可用于日志记录。如果需要,你可以访问 Laravel 使用的底层 Monolog 实例:

php
$monolog = Log::getMonolog();