日志
日志
日志
簡介
為了幫助你更多的了解應用程序中到底發(fā)生了什么,Laravel 提供了強大的日志服務,允許你將日志消息、系統(tǒng)錯誤日志記錄到文件,甚至使用 Slack 通知到你的整個團隊。
在 Laravel 框架中,Laravel 使用 Monolog 庫,它為各種強大的日志處理提供支持。Laravel 使配置這些處理程序變得簡單,允許你混合并匹配它們自定義的應用程序日志處理。
配置
所有的應用程序日志系統(tǒng)配置都位于 config/logging.php
配置文件中。這個文件允許你配置你的應用程序日志通道,所以務必查看每個可用的通道及它們的選項。當然,我們將在下面回顧一些常用的選項。
默認情況下,Laravel 將使用 stack
去記錄日志消息。stack 通道被用來將多個日志通道聚合到一個單一的通道中。關于堆棧的更多信息,查看 以下文檔。
配置通道名稱
默認情況下,Monolog 使用與當前環(huán)境匹配的『通道名稱』進行實例化,比如 production
或者 local
。要改變這個值,需添加一個 name
選項到你的通道配置中:
'stack' => [ 'driver' => 'stack', 'name' => 'channel-name', 'channels' => ['single', 'slack'], ],
可用的通道驅動
名稱 | 描述 |
---|---|
stack | 一個便于創(chuàng)建『多通道』通道的包裝器 |
single | 單個文件或者基于日志通道的路徑 (StreamHandler ) |
daily | 一個每天輪換的基于 Monolog 驅動的 RotatingFileHandler |
slack | 一個基于 Monolog 驅動的 SlackWebhookHandler |
syslog | 一個基于 Monolog 驅動的 SyslogHandler |
errorlog | 一個基于 Monolog 驅動的 ErrorLogHandler |
monolog | 一個可以使用任何支持 Monolog 處理程序的 Monolog 工廠驅動程序 |
custom | 一個調(diào)用指定工廠創(chuàng)建通道的驅動程序 |
{tip} 有關
monolog
和custom
驅動,查看 高級通道自定義
配置 Single 和 Daily 通道
single
和 daily
通道包含三個可選配置項:bubble
、permission
和 locking
.
名稱 | 描述 | 默認值 |
---|---|---|
bubble | 消息處理后,指示消息是否推送到其他通道 | true |
permission | 日志文件權限 | 644 |
locking | 寫入之前嘗試鎖定日志文件 | false |
配置 Slack 通道
slack
通道需要 url
配置選項。這個 URL 應當與你為 Slack 團隊配置的一個 incoming webhook 相匹配。
構建日志堆棧
前面說過, stack
驅動允許你在單一日志通道中整合多個通道。讓我們通過一個產(chǎn)品級應用的配置實例來看看如果使用日志堆棧::
'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.');
根據(jù)我們的配置, syslog
通道將把該消息記錄到系統(tǒng)日志;不過因為錯誤消息不是 critical
或更高級別,它將不會被發(fā)送到 Slack。如果我們記錄一條 emergency
消息,它將被發(fā)送給系統(tǒng)日志和 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);
因此,你可以調(diào)用這些方法中的任一方法記錄相應級別的日志。默認情況下,消息被寫入到在 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)]); } }
上下文信息
可以將上下文數(shù)據(jù)數(shù)組傳遞給日志方法。這些信息將被格式化,并與日志消息一直顯示:
Log::info('User failed to login.', ['id' => $user->id]);
寫入指定通道
有時候你可能希望將消息寫入到應用默認通道之外的通道中??梢允褂?Log
facade 的 channel
方法獲取定義在配置文件中的任一通道并將消息寫入其中 :
Log::channel('slack')->info('Something happened!');
如果想要創(chuàng)建一個由多通道構成的按需記錄的堆棧,可以使用 stack
方法:
Log::stack(['single', 'slack'])->info('Something happened!');
高度自定義 Monolog 通道
為通道自定義 Monolog
有時需要完全控制已存在通道的 Monolog: 比如,你可能想要為給定通道的日志處理配置自定義的 Monolog FormatterInterface
實現(xiàn):
先在通道配置中定義一個 tap
數(shù)組。 tap
數(shù)組包含一個在通道創(chuàng)建后有機會用于自定義 Monolog 實例的類列表:
'single' => [ 'driver' => 'single', 'tap' => [App\Logging\CustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ],
一旦在通道中有了 tap
選項配置,就要準備用于自定義 Monolog 實例的類。這種類這需要一個方法: __invoke
,它接受一個 Illuminate\Log\Logger
實例作為其參數(shù)。 Illuminate\Log\Logger
實例將所有方法調(diào)用代理到基礎的 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" 類都是由 服務容器 解析的,因此任何依賴它們的構造器都會自動被注入。
創(chuàng)建 Monolog 處理器通道
Monolog 多種 可用處理器。在某些情況下,你會希望僅創(chuàng)建一個帶有指定處理器的 Monolog 驅動的日志類型。這些通道可以使用 monolog
驅動創(chuàng)建。
在使用 monolog
驅動時, handler
配置項用于指定被實例化的處理器。如果該處理器的構造器需要參數(shù),可以使用可選的 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', ],
通過工廠創(chuàng)建渠道
如果你想定義一個完全自定義的通道,你可以完全控制 Monolog 的實例化和配置,你可以在 config/logging.php
配置文件中指定 custom
驅動程序類型。 你的配置應該包含一個 via
選項,指向將被調(diào)用以創(chuàng)建 Monolog 實例的工廠類:
'channels' => [ 'custom' => [ 'driver' => 'custom', 'via' => App\Logging\CreateCustomLogger::class, ], ],
一旦配置了 custom
通道,就可以定義創(chuàng)建 Monolog 實例的類。 這個類只需要一個方法: __invoke
,它就可以返回 Monolog 實例:
<?php namespace App\Logging;use Monolog\Logger; class CreateCustomLogger{ /** * 創(chuàng)建一個 Monolog 實例. * * @param array $config * @return \Monolog\Logger */ public function __invoke(array $config) { return new Logger(...); } }