紀錄
簡介
為了幫助你更多的了解應用程式中到底發生了什麼,Laravel 提供了強大的日誌服務,讓你可以將日誌訊息、系統錯誤日誌記錄到文件,甚至使用Slack 通知到你的整個團隊。
在 Laravel 框架中,Laravel 使用 Monolog 函式庫,它為各種強大的日誌處理提供支援。 Laravel 讓配置這些處理程序變得簡單,允許你混合併匹配它們自訂的應用程式日誌處理。
設定
所有的應用程式日誌系統設定都位於config/logging.php
設定檔中。這個檔案允許你配置你的應用程式日誌通道,所以務必查看每個可用的通道及它們的選項。當然,我們將在下面回顧一些常用的選項。
預設情況下,Laravel 將使用 stack
去記錄日誌訊息。 stack 通道被用來將多個日誌通道聚合到一個單一的通道。關於堆疊的更多信息,請查看 以下文件。
配置通道名稱
預設情況下,Monolog 使用與目前環境相符的『通道名稱』進行實例化,例如production
或local
。要改變這個值,需要增加一個 name
選項到你的通道設定:
'stack' => [ 'driver' => 'stack', 'name' => 'channel-name', 'channels' => ['single', 'slack'], ],
可用的通道驅動
名稱 | 描述 |
---|---|
stack | 一個方便建立『多通道』通道的包裝器 |
single | 單一檔案或者基於日誌通道的路徑(StreamHandler ) |
#daily | 一個每天輪換的基於Monolog 驅動程式的 RotatingFileHandler |
slack | #一個基於Monolog 驅動程式的SlackWebhookHandler |
##syslog | 一個基於Monolog 驅動程式的SyslogHandler |
errorlog | #一個基於Monolog 驅動的ErrorLogHandler |
monolog | 一個可以使用任何支援Monolog 處理程序的Monolog工廠驅動程式 |
custom | 一個呼叫指定工廠建立通道的驅動程式 |
{tip} 有關
monolog
與custom
驅動,請參閱進階通道自訂
##配置Single 和Daily 通道
single
和daily
通道包含三個可選配置項目:bubble
、permission
和locking
.
名稱 | 描述 | 預設值 |
---|---|---|
#bubble | 訊息處理後,指示訊息是否推送到其他通道 | true |
#permission | 日誌檔案權限 | 644 |
locking | 寫入之前嘗試鎖定日誌檔案 | false |
設定 Slack 通道
slack
通道需要 url
設定選項。這個 URL 應該與你為 Slack 團隊配置的一個 incoming webhook 相符。
#建置日誌堆疊
#前面說過, stack
驅動程式允許你在單一日誌通道中整合多個通道。讓我們透過一個產品級應用的設定實例來看看如果使用日誌堆疊::
'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['syslog', 'slack'], ], 'syslog' => [ 'driver' => 'syslog', 'level' => 'debug', ], 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ], ],
我們來分析這個配置。首先要注意的是 stack
透過使用它的 channels
選項聚合了另外兩個通道: syslog
和 slack
。因此,在記錄日誌訊息時,這兩個通道都有機會完成日誌訊息記錄:
日誌等級
請留意上面範例syslog
和slack
中存在的level
設定項。這個選項決定了需要被該頻道記錄的日誌的最低 “等級”。 Monolog (一個功能強勁的Laravel 日誌服務)接受定義在RFC 5424 specification 中的全部等級: emergency、alert、 critical、 error、 warning、 notice、 info 和debug。
假設我們使用debug
方法來記錄日誌訊息:
Log::debug('An informational message.');
根據我們的配置, syslog
頻道將把該訊息記錄到系統日誌;不過因為錯誤訊息不是 critical
或更高級別,它將不會被傳送到Slack。如果我們記錄一條emergency
訊息,它將被傳送給系統日誌和Slack,因為emergency
的等級高於兩個通道的最低等級限制:
Log::emergency('The system is down!');
寫入日誌訊息
可以使用Log
facade 將資訊寫入日誌。如前所述,日誌提供定義在RFC 5424 specification 中的可用日誌等級: emergency、 alert、 critical、 error、 warning、 notice、 info 和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);
因此,你可以呼叫這些方法中的任一方法記錄對應等級的日誌。預設情況下,訊息會寫入到在config/logging.php
設定檔中定義的預設日誌通道:
<?php namespace App\Http\Controllers;use App\User; use Illuminate\Support\Facades\Log; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 显示给定用户的配置信息。 * * @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)]); } }
上下文資訊
可以將上下文資料數組傳遞給日誌方法。這些資訊將被格式化,並與日誌訊息一直顯示:
Log::info('User failed to login.', ['id' => $user->id]);
寫入指定通道
有時候你可能希望將訊息寫入到應用預設通道以外的通道。可以使用Log
facade 的channel
方法取得定義在設定檔中的任一通道並將訊息寫入其中:
Log::channel('slack')->info('Something happened!');
如果想要建立一個由多通道構成的按需記錄的堆疊,可以使用stack
方法:
Log::stack(['single', 'slack'])->info('Something happened!');
高度自訂Monolog 通道
為通道自訂Monolog
有時需要完全控制已存在通道的Monolog: 例如,你可能想要為給定通道的日誌處理配置自訂的Monolog FormatterInterface
實作:
先在通道配置中定義一個tap
陣列。 tap
陣列包含一個在通道建立後有機會用於自訂Monolog 實例的類別清單:
'single' => [ 'driver' => 'single', 'tap' => [App\Logging\CustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ],
一旦在通道中有了tap
選項配置,就要準備用於自訂Monolog 實例的類別。這種類別這需要一個方法: __invoke
,它接受一個 Illuminate\Log\Logger
實例作為其參數。 Illuminate\Log\Logger
實例將所有方法呼叫代理到基礎的Monolog 實例:
<?php namespace App\Logging; class CustomizeFormatter{ /** * 自定义给定的日志实例。 * * @param \Illuminate\Log\Logger $logger * @return void */ public function __invoke($logger) { foreach ($logger->getHandlers() as $handler) { $handler->setFormatter(...); } } }
{tip} 所有的"tap" 類別都是由服務容器解析的,因此任何依賴它們的構造器都會自動被注入。
建立 Monolog 處理器通道
Monolog 多種 可用處理器。在某些情況下,你會想要只建立一個具有指定處理器的 Monolog 驅動程式的日誌類型。這些通道可以使用 monolog
驅動程式建立。
在使用 monolog
驅動時, handler
設定項用於指定被實例化的處理器。如果該處理器的建構器需要參數,可以使用可選的with
組態項目來指定:
'logentries' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\SyslogUdpHandler::class, 'with' => [ 'host' => 'my.logentries.internal.datahubhost.company.com', 'port' => '10000', ], ],
Monolog 格式化
使用monolog
驅動時,Monolog 的LineFormatter
用於預設的格式化處理器。當然,你也可以使用formatter
and formatter_with
設定項自訂格式化處理器類型:
'browser' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\BrowserConsoleHandler::class, 'formatter' => Monolog\Formatter\HtmlFormatter::class, 'formatter_with' => [ 'dateFormat' => 'Y-m-d', ], ],
如果所使用的Monolog 處理器能夠提供自訂的格式代處理器,可以將formatter
配置項目指定為default
:
'newrelic' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\NewRelicHandler::class, 'formatter' => 'default', ],
透過工廠建立頻道
如果你想定義一個完全自訂的通道,你可以完全控制Monolog 的實例化和配置,你可以在config/logging.php
配置文件中指定custom
驅動程式類型。你的配置應該包含一個via
選項,指向將被呼叫以創建Monolog 實例的工廠類別:
'channels' => [ 'custom' => [ 'driver' => 'custom', 'via' => App\Logging\CreateCustomLogger::class, ], ],
一旦配置了custom
通道,就可以定義創建Monolog 實例的類別。這個類別只需要一個方法: __invoke
,它就可以傳回 Monolog 實例:
<?php namespace App\Logging;use Monolog\Logger; class CreateCustomLogger{ /** * 创建一个 Monolog 实例. * * @param array $config * @return \Monolog\Logger */ public function __invoke(array $config) { return new Logger(...); } }