Laravel 日誌記錄:你需要知道的一切
已發表: 2022-08-19在開發現代應用程序時,日誌記錄應該放在優先級列表的頂部。
日誌記錄提供了一種在開發和生產中可視化您的應用程序的方法,從而實現透明度和可見性。 通過適當結構化的日誌記錄,現代應用程序可以變得更容易維護,因為我們可以主動識別應用程序中的故障點和性能瓶頸。
Laravel 框架帶有一個健壯的日誌系統,它可以處理所有在配置正確結構化的日誌系統時遇到的障礙。 Laravel 6.5 中引入的這個新的日誌系統非常強大,我們將在本文中對其進行探索。
本文將探討 Laravel 日誌記錄的基礎知識,以及為什麼應該在下一個項目中使用 Laravel 日誌記錄。 我們將詳細討論結構化日誌記錄和集中式日誌記錄。 此外,我們將學習如何通過構建一個 Todo 應用程序來實現 Laravel 日誌記錄。
如果您已經掌握了以下內容,您將從本文中獲得更多收益:
- 良好的網絡開發知識
- Laravel的基本理解
- 使用 Laravel 構建應用程序
什麼是 Laravel 日誌記錄?
Laravel 日誌記錄是關於 Laravel 如何使用稱為 Monolog 的病毒式 PHP 日誌記錄系統處理日誌記錄或自動問題報告的。 然而,由於 Laravel 使用流行的現有庫來實現不同框架功能的理念,Laravel 使用 Monolog 來滿足其所有日誌記錄需求。
Monolog 是一個高度靈活且流行的 PHP 日誌庫,我們可以將其配置為將您的日誌發送到文件、套接字、數據庫和其他 Web 服務。 Monolog 提供了一個熟悉的界面,用於將標准文本文件中的日誌寫入高級第三方日誌管理服務。 Laravel 通常將 Monolog 設置為使用標準的日誌記錄配置文件。
有關 Monolog 及其功能的更多信息,請查看官方文檔,因為這超出了本文的範圍。
在我們深入使用 Monolog 配置和實現 Laravel 日誌之前,讓我們探索更多使用 Laravel 日誌和不同類型的原因。
為什麼使用 Laravel 日誌記錄?
為什麼需要日誌記錄?
十二要素應用宣言將日誌記錄視為現代應用程序的關鍵問題之一,因為日誌記錄是性能和監控的關鍵。
日誌有助於詳細了解生產中發生的錯誤及其來源。 此外,通過適當的日誌結構,它可以顯示特定用戶、導致錯誤的操作以及更快修復和維護錯誤的可能解決方案。
結構化日誌記錄是生產應用程序中的救星,它可以幫助解決缺陷並解決生產中的問題。 此外,您可以使用專門的日誌工具實時監控和收集所有日誌消息,以進行實時分析和報告。
由於這些原因,您需要將結構化日誌記錄作為您下一個現代應用程序項目的重中之重。
讓我們看一下可用的不同日誌記錄樣式的概述。
Laravel 日誌基礎
學習日誌記錄的基礎知識將幫助您了解 Laravel 如何處理日誌記錄以及如何改進結構化日誌記錄實踐。
讓我們檢查日誌中的兩個基本概念,以更好地理解如何實現我們的日誌過程。
Laravel 結構化日誌
在軟件開發中,結構化日誌記錄是為應用程序日誌實現預定且一致的消息格式。 這種格式允許將消息視為可以比常規文本格式更好地監視、操作和可視化的數據。
您必須在現代應用程序開發中實施結構化日誌記錄方法,因為當您的應用程序在生產中出現問題時,日誌文件是開發人員必不可少的資產。
由於 Laravel 使用 Monolog,開發者可以通過配置 logger 接收特定類型的信息,將日誌文件以不同格式存儲,並將日誌發送到各種第三方日誌管理服務進行可視化,從而快速實現結構化日誌。
Laravel 集中式日誌記錄
集中式日誌記錄系統是將來自多個來源的日誌發送到集中式日誌管理 (CLM) 解決方案,以便於整合和可視化。 然而,CLM 是一種專門的記錄器解決方案,它從不同來源收集日誌消息並整合數據以便於處理和可視化。
除了數據收集,CLM 還有望支持日誌數據的分析和分析後的數據清晰呈現。
結構化日誌記錄與基本日誌記錄
讓我們來看看結構化日誌和基本(非結構化)日誌之間的區別,以及為什麼應該在 Laravel 項目中使用結構化日誌。
基本日誌記錄
在基本日誌記錄中,日誌文件以原始格式存儲,用於查詢和識別單個日誌的數據有限。
使用基本日誌記錄時,開發人員將無法使用第三方分析工具來讀取、查看和分析日誌,除非他們開發自定義工具或堅持使用支持其日誌格式的有限工具。
避免使用基本日誌記錄的三大原因:
- 如果沒有額外的支持,集中式日誌管理系統無法處理數據。
- 需要定制解決方案來讀取和解析基本日誌記錄解決方案的數據。
- 管理員讀取基本日誌數據可能具有挑戰性,因為它是原始的和非結構化的。
結構化日誌
結構化日誌通過使用支持標準日誌結構的開源第三方日誌分析工具來讀取、查看和分析日誌,從而節省開發人員的時間。
如果日誌包含下面列出的正確數據,則日誌會很有幫助,這是結構化日誌記錄的目標。 我們可以使用結構化日誌記錄中包含的數據來創建儀表板、圖形、圖表和任何其他有用的可視化,以確定應用程序的運行狀況。
這些是我們可以包含在結構化日誌消息中的信息的基本示例。 此外,您可以完全自定義數據以滿足您的需求。
以下是您可以使用結構化日誌記錄收集的數據的一些示例:
- 用於執行函數的端口
- 事件發生的日期和時間
- 客戶用戶名或 ID
- 事件描述(日誌消息)
- 用於執行功能的協議
- 觸發事件的位置(表示 API 或正在運行的應用程序)
- 唯一的事件 ID
- 觸發的操作類型(日誌級別)
日誌應包含足夠的數據,以便輕鬆可視化解決方案或日誌事件的原因。 另外請注意,您不應在日誌中存儲所有類型的信息,例如密碼或敏感數據。
現在我們已經了解了 Laravel 日誌記錄的全部內容,讓我們繼續通過構建一個將日誌記錄作為一等公民的應用程序來實現 Laravel 日誌記錄。
如何使用 Todo 應用實現 Laravel 日誌記錄
現在我們將通過創建一個新的 Laravel 項目並實現 Laravel 日誌記錄來應用到目前為止所學的知識。
如果您以前沒有使用過 Laravel,您可以閱讀 Laravel 是什麼或查看我們的優秀 Laravel 教程列表以開始使用。
設置 Laravel
首先,我們將使用以下命令創建一個新的 Laravel 實例。 您可以查看官方文檔了解更多信息。
在運行以下命令之前,打開您的控制台並導航到您存儲 PHP 項目的位置。 確保正確安裝和配置了 Composer。
composer create-project laravel/laravel laravel-logging-app cd laravel-logging-app // Change directory to current Laravel installation php artisan serve // Start Laravel development server
配置和播種數據庫
接下來,我們將建立我們的數據庫,創建一個新的Todo
模型,並播種 200 個假數據進行測試。
打開您的數據庫客戶端並創建一個新數據庫。 我們將對名稱laravel_logging_app_db
執行相同的操作,然後使用數據庫憑據填充我們的.env文件:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_logging_app_db DB_USERNAME=//DB USERNAME HERE DB_PASSWORD=//DB PASSWORD HERE
接下來,我們將運行以下命令來同時創建遷移和Todo
模型:
php artisan make:model Todo -mc
打開新創建的遷移找到database/migrations/xxx-create-todos-xxx.php並粘貼以下代碼:
<?php use IlluminateSupportFacadesSchema; use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateTodosTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('todos', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description')->nullable(); $table->boolean('is_completed')->default(false); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('todos'); } }
您可以通過學習使用 Faker 在 Laravel 中為您的數據庫播種來使用偽造數據播種您的待辦事項。
獨白概述
使用 Laravel Monolog,您可以將結構化日誌流式傳輸並發送到不同的渠道,例如電子郵件、Slack、文件、套接字、收件箱、數據庫和各種 Web 服務。 在 Laravel 中,您可以從位於config/logging.php的單個配置文件中配置日誌記錄。
配置文件帶有預定義的日誌驅動程序可供選擇,默認驅動程序是一個stack
,它使用single
記錄到storage/logs文件夾中的laravel.log文件。 我們將使用幾個 Laravel 日誌驅動程序來演示結構化日誌記錄。
Laravel 提供了一些與 Logs 交互的方法,正如稍後在TodosController.php控制器文件中所展示的那樣。
在控制器中寫入日誌消息
打開新創建的TodosController.php控制器文件找到app/Http/Controllers文件夾並粘貼以下代碼:
<?php namespace AppHttpControllers; use AppModelsTodo; use IlluminateHttpRequest; use AppHttpControllersController; use IlluminateSupportFacadesAuth; use IlluminateSupportFacadesLog; class TodosController extends Controller { public function index(Request $request) { $todos = Todo::all(); Log::warning('User is accessing all the Todos', ['user' => Auth::user()->id]); return view('dashboard')->with(['todos' => $todos]); } public function byUserId(Request $request) { $todos = Todo::where('user_id', Auth::user()->id)->get(); Log::info('User is accessing all his todos', ['user' => Auth::user()->id]); return view('dashboard')->with(['todos' => $todos]); } public function show(Request $request, $id) { $todo = Todo::find($id); Log::info('User is accessing a single todo', ['user' => Auth::user()->id, 'todo' => $todo->id]); return view('show')->with(['todo' => $todo]); } public function update(Request $request, $id) { # Validations before updating $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first(); Log::warning('Todo found for updating by user', ['user' => Auth::user()->id, 'todo' => $todo]); if ($todo) { $todo->title = $request->title; $todo->desc = $request->desc; $todo->status = $request->status == 'on' ? 1 : 0; if ($todo->save()) { Log::info('Todo updated by user successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]); return view('show', ['todo' => $todo]); } Log::warning('Todo could not be updated caused by invalid todo data', ['user' => Auth::user()->id, 'todo' => $todo->id, 'data' => $request->except('password')]); return; // 422 } Log::error('Todo not found by user', ['user' => Auth::user()->id, 'todo' => $id]); return; // 401 } public function store(Request $request) { Log::warning('User is trying to create a single todo', ['user' => Auth::user()->id, 'data' => $request->except('password')]); # Validations before updating $todo = new Todo; $todo->title = $request->title; $todo->desc = $request->desc; $todo->user_id = Auth::user()->id; if ($todo->save()) { Log::info('User create a single todo successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]); return view('show', ['todo' => $todo]); } Log::warning('Todo could not be created caused by invalid todo data', ['user' => Auth::user()->id, 'data' => $request->except('password')]); return; // 422 } public function delete(Request $request, $id) { Log::warning('User is trying to delete a single todo', ['user' => Auth::user()->id, 'todo' => $id]); $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first(); if ($todo) { Log::info('User deleted a single todo successfully', ['user' => Auth::user()->id, 'todo' => $id]); $todo->delete(); return view('index'); } Log::error('Todo not found by user for deleting', ['user' => Auth::user()->id, 'todo' => $id]); return; // 404 } }
在TodoController
的每個方法中,我們添加了具有特定日誌級別的Log
門面,以定義我們要發送的錯誤類型。 下面是一個使用
在store
方法中記錄外觀。
public function store(Request $request) { Log::warning('User is trying to create a single todo', ['user' => Auth::user()->id, 'data' => $request->except('password')]); # Validations before updating $todo = new Todo; $todo->title = $request->title; $todo->desc = $request->desc; $todo->user_id = Auth::user()->id; if ($todo->save()) { Log::info('User create a single todo successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]); return view('show', ['todo' => $todo]); } Log::warning('Todo could not be created caused by invalid todo data', ['user' => Auth::user()->id, 'data' => $request->except('password')]); return; // 422 }
格式化日誌消息
假設您對LineFormatter
使用的默認 LineFormatter 不滿意,它在提供可讀和有用的消息方面做得很好。
在這種情況下,您可以輕鬆啟動自定義格式化程序對像以適合您的用例並在整個應用程序中使用它。
Monolog 官方文檔提供了可用格式化程序的完整列表,並且可以輕鬆創建自定義格式化程序。
在 Laravel 中,您可以輕鬆地將任何驅動程序設置為使用您的自定義格式化程序,方法是將其添加到位於config/logging.php的配置文件中的如下列表中:
'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), 'days' => 14, 'formatter' => MonologFormatterHtmlFormatter::class, 'formatter_with' => [ 'dateFormat' => 'Ym-d', ] ],
上面的示例使用daily
頻道配置中的formatter
和formatter_with
鍵將自定義MonologFormatterHtmlFormatter
添加到daily
驅動程序,以更改日期格式。
將日誌發送到不同的通道
在 Monolog 的幫助下,Laravel 可以將日誌同時發送到不同的通道和多個通道。
讓我們演示如何按照這些簡單的步驟將日誌發送到我們的 Slack 頻道。 將默認日誌通道更改為 Slack 並在.env文件中添加 Slack Webhook URL。
LOG_CHANNEL=slack LOG_SLACK_WEBBHOOK_URL= Slack_webhook_url_here
接下來,通過使用Log
門面在應用程序中記錄一條消息來測試您的配置,如下所示:
Log::debug("The API instance is on fire caused by:", ['user' => 1])
您可以打開您的 Slack 頻道以檢查在生成 Webhook URL 時指定的所需頻道中打印的錯誤。
概括
日誌記錄與應用程序的任何其他因素一樣重要,甚至更重要。 這就是為什麼十二要素應用程序宣言建議它作為任何現代應用程序最關鍵的問題之一。
通過有效的日誌記錄,您可以輕鬆閱讀、查看和可視化生產就緒應用程序中發生的錯誤和缺陷。 為此,從項目開始就在應用程序中實施結構化日誌記錄非常重要。
在本文中,我們探討了 Laravel 日誌記錄以及為什麼要在下一個項目中使用它。 我們詳細討論了結構化日誌記錄和集中式日誌記錄。 此外,我們通過構建 Todo 應用程序學習瞭如何實現 Laravel 日誌記錄。
您打算如何實現登錄到您的下一個應用程序? 在評論部分讓我們知道。