在開發現代應用程式時,日誌記錄應該放在優先順序列表的頂部。
日誌記錄提供了一種在開發和生產中視覺化您的應用程式的方法,從而實現透明度和可見性。通過適當結構化的日誌記錄,現代應用程式可以變得更容易維護,因為我們可以主動識別應用程式中的故障點和效能瓶頸。
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日誌記錄?
為什麼需要日誌記錄?
Twelve-Factor App宣言將日誌記錄視為現代應用程式的關鍵問題之一,因為日誌記錄是效能和監控的關鍵。
日誌有助於詳細瞭解生產中發生的錯誤及其來源。此外,通過適當的日誌結構,它可以顯示特定使用者、導致錯誤的操作以及更快修復和維護錯誤的可能解決方案。
結構化日誌記錄是生產應用程式中的救星,它可以幫助解決缺陷並解決生產中的問題。此外,您可以使用專門的日誌工具實時監控和收集所有日誌訊息,以進行實時分析和報告。
由於這些原因,您需要將結構化日誌記錄作為您下一個現代應用程式專案的重中之重。
讓我們看一下可用的不同日誌記錄樣式的概述。
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
facade,以定義要傳送的錯誤型別。下面是使用的示例
在方法中記錄store
facade。
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 }
格式化日誌訊息
假設你對Laravel使用的預設值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' => 'Y-m-d', ] ],
上面的示例使用daily
頻道配置中的formatter
和formatter_with
鍵將自定義MonologFormatterHtmlFormatter
新增到每日驅動程式中,以更改日期格式。
將日誌傳送到不同的通道
在Monolog的幫助下,Laravel可以將日誌同時傳送到不同的通道和多個通道。
讓我們演示如何按照這些簡單的步驟將日誌傳送到我們的Slack頻道。將預設日誌通道更改為Slack並在.env檔案中新增Slack Webhook URL 。
LOG_CHANNEL=slack LOG_SLACK_WEBBHOOK_URL= Slack_webhook_url_here
接下來,通過使用如下所示的Log
facade在您的應用程式中記錄一條訊息來測試您的配置:
Log::debug("The API instance is on fire caused by:", ['user' => 1])
您可以開啟您的Slack頻道以檢查在生成Webhook URL時指定的所需頻道中列印的錯誤。
小結
日誌記錄與應用程式的任何其他因素一樣重要,甚至更重要。這就是為什麼Twelve-Factor App宣言建議它作為任何現代應用程式最關鍵的問題之一。
通過有效的日誌記錄,您可以輕鬆閱讀、檢視和視覺化生產就緒應用程式中發生的錯誤和缺陷。為此,從專案開始就在應用程式中實施結構化日誌記錄非常重要。
在本文中,我們探討了Laravel日誌記錄以及為什麼要在下一個專案中使用它。我們詳細討論了結構化日誌記錄和集中式日誌記錄。此外,我們通過構建Todo應用程式學習瞭如何實現Laravel日誌記錄。
評論留言