錯誤和日志
簡介
當你開始一個新的 laravel 項目時,你一定會需要到對錯誤和異常的處理,而這些 laravel 都已經為你配置好了。另外,laravel 還集成了 Monolog 日志組件庫,它提供了各種強大的日志處理器。
配置
錯誤詳情
你的應用中通過瀏覽器來展示的錯誤詳情程度是通過你的 config/app.php
配置文件中的 debug
選項來進行配置的。默認的該配置項遵從 .env
文件中的 APP_DEBUG
環境變量。
日志模式
larvel 提供了幾種開箱即用的日志模式:single
,daily
,syslog
和 errorlog
。比如,如果你希望使用每日日期文件記錄日志來替換默認的單文件記錄方式。你可以簡單的在 config/app.php
配置文件中該設置 log
選項的值:
'log' => 'daily'
當使用 daily
日志模式時,laravel 默認只會保留 5 天內的日志文件。如果你需要保留更多的日志文件,你需要在 config/app.php
文件中添加 log_max_files
選項:
'log_max_files' => 30
自定義 Monolog 配置
如果你想要在應用中對 Monolog 的配置擁有完全的控制,你可以使用應用的 configureMonologUsing
方法。你應該在 bootstrap/app.php
文件中進行方法的調用,并且你應該把它放置在返回 $app
之前:
$app->configureMonologUsing(function ($monolog) {
$monolog->pushHandler(...);
});
return $app;
默認的,laravel 會記錄所有等級的日志。在生產環境中,你可能會想要只記錄某些等級的日志,你可以通過在 app.php
配置文件中添加 log_level
選項來做到。laravel 會記錄這個等級的日志和比這個等級日志更高級的日志。比如,設置 log_level
為 error
,那么它會記錄 error
,critical
,alert
和 emergency
等級的消息:
'log_level' => app_env('APP_LOG_LEVEL', 'debug'),
異常處理
所有的異常都會在 App\Exceptions\Handler
類中進行處理。該類包含了兩個方法:report
和 render
。我們將會對這個兩個方法進行詳細的剖析。
Report 方法
report
方法被用來記錄異常或者發送異常到其他的服務中去,比如 BugSnag 或者 Sentry。默認的,report
方法只是簡單的傳遞異常到異常記錄的基類中。事實上,你可以自由的按照自己的希望去記錄異常。
比如,如果你希望用不同的方式來記錄不同類型的異常,你可以使用 PHP 的 instanceof
方法來進行篩選操作:
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
{
if ($e instanceof CustomException) {
//
}
return parent::report($e);
}
根據類型來忽略異常
異常處理類的 $dontReport
屬性包含了一個需要忽略的異常類數組。這個數組中類型的異常將不會被記錄。默認的 404 類型的錯誤就不會記錄在日志文件中,你可以按需在這個數組中進行追加忽略的異常類名。
Render 方法
render
方法用來將異常轉換為傳遞回瀏覽器的響應信息。默認異常會被傳遞到基類并返回一個響應。事實上,你可以自由的按需進行定制化響應:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $e);
}
HTTP 異常
有些異常是直接從服務器來描述 HTTP 的錯誤代碼。比如,這可能是一個“頁面沒有找到”的錯誤(404),一個“未授權”的錯誤(401)或者是一個“開發錯誤”(500)。為了在你的應用中快速的生成這種類型的響應,你可以使用下面的方式:
abort(404);
abort
方法會立即的提出一個異常,該異常會在異常處理中被渲染。你也可以在該方法中提供一個可選的響應文本:
abort(403, 'Unauthorized action.');
該方法可以在請求的生命周期中的任意時間點使用。
自定義 HTTP 錯誤頁面
laravel 使根據 HTTP 響應狀態碼來創建自定義的錯誤頁面非常簡單。比如,你可能希望自定義一個錯誤頁面來提供給 404 HTTP 狀態碼。你可以創建一個 resoucres/views/errors/404.blade.php
文件。該文件會在應用拋出 404 錯誤時自動的提供服務。
在該目錄下的視圖的命名應該與 HTTP 狀態碼相對應。
日志
laravel 的日志系統是基于強大的 Monolog 類庫的。默認的,laravel 設置了 storage/logs
目錄來存放日志文件。你可以使用 Log
假面來記錄日志信息:
<?php
namespace App\Http\Controllers;
use Log;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @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 規范定義了 8 中日志等級:emergency,alert,critical,error,warning,notice,info 和 debug。
Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);
上下文信息
你可以在入日志方法中傳遞一個上下文數據的數組,這個上下文數據將會被格式化并在日志信息中顯示:
Log::info('User failed to login.', ['id' => $user->id]);
訪問底層的 Monolog 實例
Monolog 擁有多種額外日志處理方法。如果你需要,你可以在 laravel 中使用下面的方式訪問底層的 Monolog 實例:
$monolog = Log::getMonolog();