Hướng dẫn dùng sys log trong PHP
Trong ngôn ngữ PHP, Exception là một class được xây dựng sẵn để quản lý lỗi kiểu hướng đối tượng, nó cho phép bạn đưa ra các cảnh báo khi một vấn đề xấu xảy ra hoặc người dùng hoạt động theo những cách thức không mong muốn (ví dụ như phép chia cho 0 chẳng hạn). Không có exception, ứng dụng của bạn có thể dừng lại khi gặp lỗi và cũng rất khó để kiểm tra lỗi. Show 1. Exception là gì?
Đây là một định nghĩa hoàn chỉnh nhất cho Exception là gì được đưa ra bởi Martin Fowler, cũng chính là tác giả của một loạt bài viết rất hay về nguyên lý Inversion of Control. Trong thực tế một exception là một sự kiện, nó xảy ra khi chương trình thực thi và làm gián đoạn luồng thực hiện. Khi bạn tạo ra một exception, hệ thống sẽ bắt exception này và tìm cách xử lý phù hợp cùng với các message tương ứng.
Gợi ý: Bạn nên tham khảo bài viết Quản lý lỗi với Exception trong PHP để có kiến thức cơ bản về Exception. 1.1 Exception nên sử dụng trong những trường hợp nào?Sử dụng exception khi hệ thống phải đối mặt với những tình huống đặc biệt ngăn cản hệ thống giành quyền điều khiển hay nói một cách khác exception sử dụng khi hệ thống không thể xác định điều gì đã xảy ra. Nếu một lỗi là một hành vi mong đợi thì chúng ta không nên sử dụng exception, ví dụ trường hợp chúng ta cần kiểm tra dữ liệu nhập vào. Bắt exception với câu lệch catch là rất quan trọng vì nó nếu không thực hiện nó hệ thống sẽ trả về lỗi và ứng dụng dừng lại. Câu lệnh catch sẽ giúp chương trình quản lý được lỗi và vẫn hoạt động khi lỗi xảy ra. Chú ý: Exception không nên sử dụng trong thao tác với các toán tử logic. 2. Laravel Exception là gì?Trong framework Laravel Exception vẫn được sử dụng như class Exception thông thường của ngôn ngữ PHP và thêm vào đó, Laravel cho phép quản lý tập trung exception với class app\Exceptions\Handler. Với class này Laravel cho phép chúng ta có thể quản lý lỗi thông qua các dịch vụ bên thứ 3 và cũng cho phép điều hướng một cách phù hợp đến các trang báo lỗi. Đi kèm với các các exception, Laravel còn sử dụng thư viện Monolog để giúp ghi lại nhật ký lỗi với rất nhiều các thiết lập cấu hình tùy chọn như sử dụng file riêng lẻ hay file log theo ngày hoặc thậm chí ghi nhận vào system log. Chúng ta sẽ cùng tìm hiểu cách thiết lập cấu hình cho quản lý lỗi và ghi log trong Laravel, tiếp đó là phần ví dụ về xây dựng một class Exception riêng. 2.1 Cấu hình2.1.1 Bật tắt chế độ ghi log lỗiTùy chọn debug trong config/app.php xác định thông tin lỗi có được hiển thị cho người dùng hay không. Mặc định, tùy chọn này lấy giá trị biến môi trường APP_DEBUG trong file .env. Với phát triển cục bộ, bạn nên thiết lập biến môi trường APP_DEBUG là true, khi đưa mã nguồn lên máy chủ nên để giá trị này là false. 2.1.2 Thiết lập lưu trữ logLaravel hỗ trợ ghi thông tin log vào các file đơn lẻ, file log theo ngày hoặc syslog và errorlog. Để cấu hình cơ chế Laravel sử dụng để lưu trữ log, bạn thay đổi tùy chọn log trong config/app.php. Ví dụ, nếu bạn muốn sử dụng cách ghi log ra file theo ngày thay cho một file riêng lẻ thì bạn thiết lập giá trị log trong app.php thành daily:
Khi sử dụng chế độ daily, Laravel chỉ giữ lại 5 file log của 5 ngày gần nhất, nếu bạn muốn điều chỉnh số lượng file log được lưu trữ lại, bạn có thể thay đổi giá trị log_max_files trong app.php:
2.1.3 Thiết lập cấp độ lỗi cần ghi logKhi sử dụng Monolog, các message log có rất nhiều cấp độ với độ nghiêm trọng khác nhau. Mặc định, Laravel ghi tất cả các cấp độ log, tuy nhiên, trong môi trường ứng dụng chạy thực tế, bạn nên thiết lập chỉ ghi log với các cấp độ nghiêm trọng cần thiết thông qua giá trị log_level trong file app.php. Khi tùy chọn này được cấu hình, Laravel sẽ ghi log tất cả các cấp độ nghiêm trọng hơn hoặc bằng với cấp độ được cấu hình. Ví dụ, mặc định giá trị log_level có giá trị là error do đó Laravel sẽ ghi log các cấp độ là error, critical, alert và emergency:
2.1.4 Thiết lập cấu hình Monolog riêngNếu bạn muốn hoàn toàn kiểm soát cách Monolog được cấu hình trong ứng dụng của bạn, bạn có thể sử dụng phương thức configureMonologUsing và thực hiện gọi đến phương thức này trong file bootstrap/app.php trước khi trả về biến $app:
2.2 Quản lý Exception2.2.1 Phương thức reportTất cả các exception được quản lý bởi class app\Exceptions\Handler, class này chứa hai phương thức là report và render. Phương thức report được sử dụng để log exception và gửi chúng đến các dịch vụ ngoài như Bugsnag hoặc Sentry. Mặc định, phương thức report chỉ đơn giản truyền exception đến class nơi exception xảy ra. Ví dụ, nếu bạn cần báo cáo các dạng khác nhau của exception theo cách khác, bạn có thể sử dụng toán tử so sánh của PHP là instanceof:
Đôi khi chúng ta muốn bỏ qua một số exception, thuộc tính $dontReport của class app\Exceptions\Handler chứa một mảng các dạng exeception không muốn log. Ví dụ, các exception cho kết quả lỗi 404 không muốn ghi xuống file log, bạn có thể đưa các exception này vào thuộc tính $dontReport:
2.2.2 Phương thức renderPhương thức này được sử dụng cho mục đích điều hướng, với mỗi exception cụ thể bạn muốn điều hướng người dùng đến một trang HTTP. Mặc định, exception được truyền đến base class nơi sinh ra response, tuy nhiên bạn hoàn toàn có thể kiểm tra dạng exception và trả về một response tùy ý:
2.3 HTTP ExceptionMột số các exception tương ứng với một mã lỗi HTTP, ví dụ như lỗi "Trang không tìm thấy" tương ứng với mã lỗi 404 hay lỗi "Không được cấp quyền truy nhập" tương ứng với 401... Trong ứng dụng, phương thức abort giúp bạn tạo ra các exception này:
Helper abort sẽ ngay lập tức bung ra một exception, phương thức này cũng nhận một chuỗi text để hiển thị cho mã lỗi tương ứng.
2.3.1 Tạo ra view riêng cho mã lỗi HTTPLaravel cho phép tạo ra các trang thông báo lỗi riêng tương ứng với các mã lỗi. Ví dụ, nếu bạn muốn cá nhân hóa trang báo lỗi 404 "Không tìm thấy trang web" bạn có thể tạo view resources/views/errors/404.blade.php. View này sẽ được sử dụng khi lỗi 404 phát sinh trong ứng dụng. Các view trong thư mục này cần được đặt tên tương ứng với mã lỗi HTTP. Một instance của HttpException sẽ được truyền đến view trong biến $exception khi hàm abort được gọi đến.
2.4 Ghi logLaravel có một abstraction layer bao phủ thư viện Monolog, mặc định một file log được lưu trong thư mục storage/logs. Bạn hoàn toàn có thể ghi log vào đây sử dụng facade Log:
Các nhật ký lỗi được ghi nhận với 8 cấp độ khác nhau theo tiêu chuẩn RFC 5424: emergency, alert, critical, error, warning, notice, info và debug.
Trong quá trình ghi log, bạn muốn ghi thêm các thông tin khác để tăng cường thông tin ngữ cảnh của lỗi, các phương thức của facade Log ở trên đều có tham số thứ hai là một mảng thông tin. Ví dụ:
Facade Log là một lớp trìu tượng bao phủ Monolog, đôi khi bạn muốn đối tượng từ Monolog, sử dụng phương thức getMonolog():
3. Ví dụ về Laravel Eloquent ExceptionTrong ví dụ này chúng ta sẽ tạo ra một lỗi Laravel sẵn có bằng cách cố tình tạo ra một Exception với phương thức firstOrFail() của Eloquent Model. Trong một project Laravel sẵn có mở file routes\web.php và thêm vào (nếu bạn chưa có môi trường thực hành Laravel tham khảo Cài đặt nhanh môi trường Laravel với Laragon):
Khi thực hiện route này trên trình duyệt một exception ModelNotFoundException sẽ được sinh ra. Bạn có thể thêm vào đoạn mã quản lý exception để trả về một thông báo lỗi riêng bằng cách thêm code vào phương thức render trong app\Exceptions\Handler:
Chúng ta thêm một view với tên 404_user_not_found.blade.php vào trong thư mục resources\views\errors. Sở dĩ tạo ra view riêng vì chúng ta muốn trang hiển thị thông báo không tìm thấy user khác với trang "Không tìm thấy trang web" 404.blade.php.
Khi truy nhập vào route user\9999 chúng ta sẽ thấy thông báo lỗi như mong muốn: Qua ví dụ về Eloquent Exception chúng ta đã biết cách quản lý Exception trong Laravel và điều hướng đến thông báo lỗi phù hợp nâng cao trải nghiệm người dùng. Trong phương thức render ở trên chúng ta không đề cập đến NotFoundHttpException là exception phát sinh khi một trang không có trong routes\web.php. Thêm vào phương thức render phần code quản lý NotFoundHttpException:
Ở bất cứ đâu trong ứng dụng, bạn muốn tạo ra một exception NotFoundHttpException thì sử dụng hàm abort:
Trên đây là cách bạn quản lý Exception ở mức toàn cục của ứng dụng, nếu bạn chỉ muốn chuyển hướng đến 404_user_not_found trong những trường hợp riêng biệt, bạn hoàn toàn có thể sử dụng cặp cú pháp try catch trong những ngữ cảnh phù hợp:
4. Ví dụ tạo một class Exception riêngTrong ví dụ ở phần 3 chúng ta chỉ thực hiện quản lý một Exception có sẵn là ModelNotFoundException, chúng ta hoàn toàn có thể tạo ra những class Exception riêng. Chúng ta tạo ra một class trìu tượng mở rộng từ Exception để tất cả các class Exception khác trong ứng dụng sẽ được mở rộng từ đây.
Trong phương thức build() chúng ta có sử dụng đến file cấu hình errors.php là file chứa các id, title và detail được định nghĩa sẵn cho các Exception.
Giả sử trong ví dụ ở phần 3 chúng ta không sử dụng phương thức findOrFail() mà muốn thực hiện một truy vấn nào đó với User sau đó nếu user không tồn tại thì phát sinh UserNotFoundException là một Exception chúng ta tạo ra, vì có rất nhiều thứ NotFound nên chúng ta tạo ra class NotFoundException:
Và tiếp theo là class UserNotFoundException mở rộng từ NotFoundException:
Ok, chúng ta sẽ tìm user và nếu user không tồn tại sẽ throw ra UserNotFoundException:
Các phần quản lý Exception với phương thức render() của app\Exceptions\Handler bạn có thể xem lại ví dụ phần 3. Chú ý, nếu không muốn UserNotFoundException được ghi log thì bạn đưa class này vào thuộc tính $dontReport:
5. Lời kếtFramework Laravel luôn có những điều mới mẻ cho những kiến thức chuẩn trong PHP và với Exception chúng ta hoàn toàn quản lý tốt các lỗi xảy ra trong ứng dụng ở cả những ngữ cảnh đặc biệt nói riêng và quản lý toàn cục nói chung. Quản lý lỗi với Laravel Exception là rất cần thiết đảm bảo ứng dụng hoạt động thông suốt và nâng cao trải nghiệm người dùng. Chúng ta không muốn khách hàng than phiền rằng ứng dụng thỉnh thoảng bung ra những màn hình lỗi với các thông tin kỹ thuật rối rắm không thể hiểu nổi. Trong phần đầu của bài viết có nói đến các dịch vụ bên thứ 3 như Bugsnag hay Sentry là các dịch vụ ghi nhận và tổng hợp các exception giúp chúng ta quản lý lỗi ứng dụng tốt hơn. Phần ghi log trong Laravel sử dụng Monolog cũng còn rất nhiều tính ứng dụng, do khuôn khổ bài viết xin được dừng ở đây và hẹn các bạn trong những bài viết tiếp theo về vấn đề quản lý lỗi. CÁC BÀI VIẾT KHÁC |