[Laravel] Errors & Logging

Giới thiệu

Khi bạn bắt đâu với một project mới, việc xử lý về error và exception đã được cấu hình cho bạn rồi. Class App\Exceptions\Handler là nơi mà tất cả đã được trigger ứng dụng của bạn đang đăng nhập và trả lại cho người dùng. Chúng ta sẽ tìm hiểu sâu hơn về nó trong suốt tài liệu này.

Đối với logging, Laravel tích hợp thư viện Monolog, nó cung cấp rất một loạt các xử lý rất hay. Laravel cấu hình một vài sử lý đó cho bạn, cho phép bạn chọn giữa một hoặc nhiều file log, hoặc viết thông tin error vào hệ thống log.

Cấu hình

Chi tiết Error

Lựa chọn debug bên trong config/app.php cho phép thông tin về error thực sự hiển thị cho người dùng. Mặc định, cấu hình này thiết lập dựa trên biến môi trường APP_DEBUG, lưu trong file .env.

Trong môi trường phát triển local, bạn nên đặt giá trị biến APP_DEBUG thành true. Đối với môi trường production, giá trị này phải luôn luôn là false. Nếu giá trị này là true trên môi trường production, người dùng có thể sẽ thấy được các giá trị cấu hình ứng dụng của bạn.

Lưu trữ Log

Cơ bản, Laravel hỗ trợ các chế độ single files, daily files, the syslog, và errorlog. Để cấu hình cơ chế lưu trữ log của Laravel, bạn có thể chỉnh log trong file config/app.php. Ví dụ, nếu bạn muốn sử dụng log file hàng ngày thay vì log một file, bạn có thể đặt log trong file app thành daily:

'log' => 'daily' Giới hạn thời gian file Daily Log Khi bạn sử dụng chế độ daily log, mặc định Laravel chỉ để lại files log năm ngày gần nhất. Nếu bạn muốn thay đổi số ngày đó, bạn cần thêm 1 dòng log_max_files vào trong file app:

'log_max_files' => 30

Các mức độ của Log

Khi sử dụng Monolog, nội dung tin nhắn log có thể khác cấp độ với nhau. mặc định, Laravel viết tất cả các cấp độ log được lưu trữ lại. Tuy nhiên, trong môi trường production, bạn có thể giới hạn cấp độ bằng cách thêm log_level trong file app.php.

Khi tùy biến đã được cấu hình, Laravel sẽ log tất cả những cấp độ cao hơn hoặc bằng cấp độ tùy biến. Ví dụ, mặc định log_level của error sẽ log nội dung error, critical, alert, and emergency:

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

Monolog quy định mức độ theo thứ tự từ nhỏ đến theo theo thứ tự sau: debug, info, notice, warning, error, critical, alert, emergency.

Tùy biến cấu hình Monolog

Nếu bạn muốn điều chỉnh toàn bộ quy trình Monolog trong ứng dụng của bạn, bạn có thể sử dụng phương thức configureMonologUsing method. Bạn nên gọi phương thức xử lý này trong file bootstrap/app.php ngay trước biến $app được trả về:


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

return $app;

The Exception Handler

Phương thức report

Tất cả các exception được xử lý bởi class App\Exceptions\Handler. Class này chứa 2 phương thức: report và render. Chúng ta sẽ xem xét chi tiết hai phương thức này. Phương thức report được sử dụng để log các exception hoặc gửi chúng tới các dịch vụ ngoài như Bugsnag hoặc Sentry. Mặc định, Phương thức report đơn giải chỉ đấy các exception về class nơi mà exception được log lại. Tuy nhiên, bạn có thể hoàn toàn tùy biến theo ý bạn muốn.

Ví dụ, nếu bạn cần report nhiều kiểu exception theo nhiều cách khác nhau, bạn có thể sử dụng toán tử kiểm tra của PHP instanceof:

/**
 * Report or log an exception.
 *
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
 *
 * @param    \Exception  $exception
 * @return  void
 */
public function report(Exception $exception)
{
    if ($exception instanceof CustomException) {
        //
    }

    return parent::report($exception);
}

Loại bỏ exception theo kiểu Thuộc tính $dontReport của handler chứa một mảng các kiểu exception sẽ không cần log. Ví dụ, exceptions của lỗi 404, cũng như mội vài kểu lỗi khác, sẽ không được lưu vào file log. Bạn có thể thêm kểu exception khác vào mảng nếu cần thiết:

/**
 * A list of the exception types that should not be reported.
 *
 * @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,
];

Phương thức Render

Phương thức render có tránh nhiệm chuyển đổi một exception thành một HTTP response để trả lại cho trình duyệt. Mặc định, exception được đẩy tới class cơ sở để tạo một response cho bạn. Tuy nhiên, bạn có thể thoải mái trong việc kiểm tra kiểu exception và trả về response tùy biến theo ý của bạn:

/**
 * Render an exception into an HTTP response.
 *
 * @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 Exceptions

Một số exceptions miêu tả mã HTTP từ server. Ví dụ, đây có thể là một lỗi "page not found" (404), một lỗi "unauthorized error" (401) hoặc lỗi 500. Để tạo ra response tương ứng với mã lỗi ở bất kỳ đâu trong ứng dụng, bạn có thể sử dụng phương thức abort:

abort(404); Phương thức abort sẽ lập tức đẩy ra một exception sẽ được render bởi exception handler. Bạn cũng có thể tùy chọn cung cấp thêm nội dung response:

abort(403, 'Unauthorized action.');

Tùy biến HTTP Error Pages

Laravel làm việc trả về trang lỗi tùy biến tương ứng với mã HTTP status rất dễ dàng. Ví dụ, nếu bạn chỉnh sửa trang lỗi tương ứng với mã 404 HTTP status, chỉ việc tạo một file resources/views/errors/404.blade.php. File này sẽ được gọi ra khi có lỗi 404 HTTP status được sinh ra trong ứng dụng của bạn. Các view nằm trong thư mục này phải trùng với mã lỗi HTTP status. HttpException có hàm abort nó sẽ được xem như là một biến $exception.

Logging

Laravel cung cấp một lớp abstraction đơn giản ở trên thư viện Monolog. Mặc định, Laravel cấu hình tạo ra file log cho ứng dụng cuản bạn trong thư mục storage/logs. Bạn có thể viết thêm nội dung vào trong logs sử dụng Log facade:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Log;
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)]);
    }
}

Logger cung cấp 8 cấp độ cơ bản theo định nghĩa RFC 5424: emergency, alert, critical, error, warning, notice, info and debug.

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

Thông tin theo ngữ cảnh

Một mảng dữ liệu theo ngữ cảnh có thể được truyền vào trong phương thức Log. Các dữ liệu này sẽ được format và hiển thị cùng với nội dung log:

Log::info('User failed to login.', ['id' => $user->id]); Truy cập vào đối tượng phía dưới Monolog Monolog có một số hander bổ sung mà bạn có thể sử dụng nó cho việc log. Nếu cần thiết, bạn có thể truy cập vào đối tường phía dưới của Monolog bằng cách:

$monolog = Log::getMonolog();

nguồn : https://laravel.com/docs/5.5/errors