Logging
Table of Contents
Introduction
あなたが application 内で何が起こっているかをより詳しく理解するために、 Laravel は強力な logging services を提供しており、これにより、メッセージをファイルに log したり、システム error log に記録したり、さらには Slack に通知してチーム全体に知らせることも可能です。
Laravel logging は"channels"に基づいています。各 channel は、log 情報を書き込む特定の方法を表しています。例えば、single channel は log ファイルを"single log"ファイルに書き込みますが、slack channel は log メッセージを Slack に送信します。log メッセージは、その重要度に基づいて複数の channel に書き込むことができます。
ホードの下で、 Laravel はMonolog library を利用しており、これにより様々な強力な log ハンドラのサポートが提供されます。 Laravel によってこれらのハンドラの設定が簡単になり、あなたの application の log ハンドリングをカスタマイズするために混ぜたり、 match させたりすることができます。
Configuration
すべての設定 options は、アプリケーションの logging の振る舞いを制御し、config/logging.php 設定ファイルに収容されています。このファイルにより、アプリケーションの log チャンネルを設定できますので、利用可能な各チャンネルとその options を確認してください。以下でいくつかの一般的な options をご説明します。
Laravel は logging メッセージをデフォルトでstack channel を使用します。stack channel は、複数の log チャンネルを 1 つの channel に集約するために使用されます。スタックの構築に関する詳細については、以下のドキュメントを参照してください。
利用可能な Channel ドライバー
各々の log channel は"driver"によって動作しています。driver は log メッセージが実際にどのように、どこに recorded されるかを決定します。以下の log channeldriver は全ての Laravel application で利用可能です。これらの driver のほとんどは、すでにあなたの application のconfig/logging.php設定ファイルにエントリが存在していますので、その内容に精通するために必ずこのファイルを見直してください。
| 名前 | 説明 |
|---|---|
custom | 指定された factory を呼び出して channel を作成する driver |
daily | 日々ローテーションする Monolog driver であるRotatingFileHandler |
errorlog | ErrorLogHandlerベースの Monolog driver |
monolog | どのサポートされた Monolog handler も使用可能な Monolog factory driver |
papertrail | Monolog driver を基盤とした SyslogUdpHandler |
single | single ファイルまたは path ベースのロガー channel (StreamHandler) |
slack | Monolog driver をベースにした SlackWebhookHandler |
stack | 複数チャネルを作成しやすくするためのラッパー |
syslog | SyslogHandlerをベースとした Monolog driver |
NOTE
詳細は、高度な channel のカスタマイズのドキュメンテーションをご覧ください。これにより、
monologとcustomドライバについての詳細を理解することができます。
Channel 名の設定
default では、Monolog は現在の環境に一致する channel 名でインスタンス化されます。たとえば、productionやlocalなどです。この value を変更するには、channel の設定にname option を追加することができます:
'stack' => [
'driver' => 'stack',
'name' => 'channel-name',
'channels' => ['single', 'slack'],
],
Channel の前提条件
Single と Daily チャンネルの設定
single と daily チャンネルには、3 つのオプション設定 options があります: bubble、permission、そして locking。
| 名前 | 説明 | Default |
|---|---|---|
bubble | メッセージが処理された後に他のチャンネルにバブルアップするべきかどうかを示します | true |
locking | Attempt log ファイルを書き込む前にロックする | false |
permission | log ファイルの権限 | 0644 |
さらに、daily channel のリテンション policy は、LOG_DAILY_DAYS environment variable を通じて、またはdays設定 option を設定することで設定することができます。
| 名前 | 説明 | Default |
|---|---|---|
days | 日々の log ファイルが保持されるべき日数 | 7 |
Papertrail Channel の設定
papertrail channel は、host および port 構成 options を必要とします。これらは PAPERTRAIL_URL と PAPERTRAIL_PORT environment 変数で定義できます。これらの values は Papertrail から取得できます。
Slack Channel の設定
slackの channel は url の設定 option が必要です。この value は、 LOG_SLACK_WEBHOOK_URL の environment variables を介して定義できます。URL は、あなたが自分の Slack チーム用に設定したwebhook への入力 の URL と一致すべきです。
default として、 Slack は critical レベル以上の logs のみを受け取ります。ただし、 LOG_LEVEL environment variables を使用したり、 Slack log channel の設定 array 内の level 設定 option を変更することで、これを調整できます。
Logging 非推奨警告
PHP、Laravel、および他の libraries は、一部の機能が廃止予定であり、将来の version で削除されることを、しばしばその users に通知します。これらの廃止警告を log に記録したい場合は、 deprecations ログ channel を指定するために、LOG_DEPRECATIONS_CHANNEL 環境 variables を使用するか、application の config/logging.php 設定ファイル内で指定することができます。
'deprecations' => [
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
'trace' => env('LOG_DEPRECATIONS_TRACE', false),
],
'channels' => [
// ...
]
または、deprecationsという名前の logchannel を定義することもできます。この名前の logchannel が存在する場合、常に非推奨の log に使用されます:
'channels' => [
'deprecations' => [
'driver' => 'single',
'path' => storage_path('logs/php-deprecation-warnings.log'),
],
],
Building Log Stacks
前述の通り、stack driver を使用すると、複数の channels を単一のログ channels に結合することができ、便利です。 log stack の使用方法を示すために、production application で見かけるかもしれない設定例を見てみましょう:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['syslog', 'slack'], // [tl! add]
'ignore_exceptions' => false,
],
'syslog' => [
'driver' => 'syslog',
'level' => env('LOG_LEVEL', 'debug'),
'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER),
'replace_placeholders' => true,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),
'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
'level' => env('LOG_LEVEL', 'critical'),
'replace_placeholders' => true,
],
],
この設定を解析してみましょう。まず、stack channel が、channelsoption を通じて他の 2 つのチャンネル、syslogとslackを組み込んでいることに注目してください。したがって、 logging メッセージを出力する際には、これらの両方のチャンネルがメッセージを log に出力する機会を持つことになります。しかし、この後で説明するように、これらのチャンネルが実際にメッセージを log に出力するかどうかは、メッセージの重大度 / "レベル"によって決まるかもしれません。
Log レベル
syslog および slack channel 構成に存在する level 構成オプションに注意してください。このオプションは、メッセージが channel によって記録されるために必要な最小の「レベル」を決定します。Laravel の logging services を動かす Monolog は、RFC 5424 規格 で定義されたすべての log レベルを提供します。重大度が高い順に、これらの log レベルは次のとおりです: emergency, alert, critical, error, warning, notice, info, および debug。
それでは、debug method を使ってメッセージを log に記録することを想像してみてください:
Log::debug('An informational message.');
私たちの設定を考えると、syslog channel はメッセージをシステムログに書き込みますが、 error メッセージは critical 以上ではないため、 Slack には送信されません。しかし、もしこれを log として emergency メッセージを記録した場合、emergency レベルは両方のチャンネルに対する最小レベル閾 values を上回っているため、システムの log と Slack の双方に送信されます:
Log::emergency('The system is down!');
Writing Log Messages
Log facadeを使用して、Logs に情報を書き込むことができます。前述の通り、ロガーはRFC 5424 の仕様 で定義された 8 つの logging レベルを提供します: emergency, alert, critical, error, warning, notice, info, debug:
use Illuminate\Support\Facades\Log;
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
これらのメソッドのいずれかを使用して、対応するレベルのメッセージを log に記録することができます。 default では、メッセージは logging 設定ファイルで設定された default log channel に書き込まれます。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*/
public function show(string $id): View
{
Log::info('Showing the user profile for user: {id}', ['id' => $id]);
return view('user.profile', [
'user' => User::findOrFail($id)
]);
}
}
文脈情報
log メソッドには、コンテキスト data の array が渡されることがあります。このコンテキスト data はフォーマットされ、 log メッセージと一緒に表示されます:
use Illuminate\Support\Facades\Log;
Log::info('User {id} failed to login.', ['id' => $user->id]);
たまに、特定の channel のすべての後続の log エントリーに含まれるべき文脈情報を指定したいと思うかもしれません。例えば、あなたの application に対する各入力 request に関連付けられた request ID を log したいと思うかもしれません。これを実現するには、Log ファサードの withContext method を呼び出すことができます:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class AssignRequestId
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$requestId = (string) Str::uuid();
Log::withContext([
'request-id' => $requestId
]);
$response = $next($request);
$response->headers->set('Request-Id', $requestId);
return $response;
}
}
あなたがcontextual情報をすべての logging チャネル間で共有したい場合は、Log::shareContext() method を呼び出すことができます。この method は、すべての作成されたチャネルと、その後作成されたチャネルにコンテクスト情報を提供します。
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class AssignRequestId
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$requestId = (string) Str::uuid();
Log::shareContext([
'request-id' => $requestId
]);
// ...
}
}
NOTE
キュー化された jobs の processing 中に log context を共有する必要がある場合、あなたはjob middlewareを利用することができます。
特定のチャンネルへの書き込み
時々、アプリケーションの default channel 以外の channel にメッセージを log したい場合があるかもしれません。 Log facade 上の channel method を使用して、設定ファイルで定義された任意の channel に log を取得および記録することができます。
use Illuminate\Support\Facades\Log;
Log::channel('slack')->info('Something happened!');
もし複数のチャネルで構成されるオンデマンドの logging stack を作成したい場合は、stack method を使用することができます:
Log::stack(['single', 'slack'])->info('Something happened!');
オンデマンドチャンネル
また、アプリケーションのlogging設定ファイルにその設定が存在しなくても、 runtime で設定を提供することでオンデマンドの channel を作成することも可能です。これを達成するために、設定の array をLogファサードのbuild method に渡すことができます:
use Illuminate\Support\Facades\Log;
Log::build([
'driver' => 'single',
'path' => storage_path('logs/custom.log'),
])->info('Something happened!');
また、オンデマンドの channel をオンデマンドの logging stack に含めたい場合があります。これは、オンデマンドの channel インスタンスをstack method に渡される array に含めることで実現できます。
use Illuminate\Support\Facades\Log;
$channel = Log::build([
'driver' => 'single',
'path' => storage_path('logs/custom.log'),
]);
Log::stack(['slack', $channel])->info('Something happened!');
Monolog Channel Customization
チャンネル用の Monolog のカスタマイズ
時折、既存の channel に対して Monolog が設定される方法を完全に制御する必要があるかもしれません。例えば、Laravel の組み込み single channel 用に custom Monolog の FormatterInterface 実装を設定したいかもしれません。
始めるには、チャンネルの構成に tap array を定義します。tap array には、Monolog インスタンスが作成された後にカスタマイズ(または "tap")する機会を持つクラスのリストを含める必要があります。これらのクラスを配置するための通常の場所はないため、これらのクラスを含むディレクトリを application 内に自由に作成できます。
'single' => [
'driver' => 'single',
'tap' => [App\Logging\CustomizeFormatter::class],
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'replace_placeholders' => true,
],
tapオプションをご自身の channel に設定したら、 Monolog インスタンスをカスタマイズする class を定義する準備が整います。この class は single method のみ必要であり、それは __invoke で、これは Illuminate\Log\Logger インスタンスを受け取ります。Illuminate\Log\Logger インスタンスは、全ての method 呼び出しを基礎となる Monolog インスタンスにプロキシします。
<?php
namespace App\Logging;
use Illuminate\Log\Logger;
use Monolog\Formatter\LineFormatter;
class CustomizeFormatter
{
/**
* Customize the given logger instance.
*/
public function __invoke(Logger $logger): void
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new LineFormatter(
'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
));
}
}
}
NOTE
あなたの全ての"tap"クラスはservice containerによって解決されているので、必要なコンストラクタの依存関係は自動的に注入されます。
Monolog Handler チャネルの作成
Monolog は、さまざまな利用可能なハンドラー を持っており、Laravel はそれぞれに対応する組み込みの channel を持っていません。場合によっては、特定の Monolog ハンドラーの単なるインスタンスである custom チャンネルを作成したいと思うかもしれません。これらのチャンネルは、monolog driver を使用して簡単に作成できます。
monologの driver を使用する際、handler設定 option を用いて実体化されるハンドラーを指定します。option として、with設定 option を用いて、ハンドラーが必要とする任意のコンストラクタパラメータを指定することもできます:
'logentries' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\SyslogUdpHandler::class,
'with' => [
'host' => 'my.logentries.internal.datahubhost.company.com',
'port' => '10000',
],
],
Monolog フォーマッター
monolog driver を使用する場合、Monolog の LineFormatter が default フォーマッタとして使用されます。ただし、formatter および formatter_with 構成 options を使用して、ハンドラに渡されるフォーマッタの type をカスタマイズできます。
'browser' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\BrowserConsoleHandler::class,
'formatter' => Monolog\Formatter\HtmlFormatter::class,
'formatter_with' => [
'dateFormat' => 'Y-m-d',
],
],
あなたが自身のフォーマッターを提供できる Monolog handler を使用している場合、formatter設定 option の value をdefaultに設定することができます。
'newrelic' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\NewRelicHandler::class,
'formatter' => 'default',
],
Monolog プロセッサ
Monolog は、 logging する前にメッセージを process することもできます。あなた自身のプロセッサを作成することも、Monolog が提供する既存のプロセッサ を使用することもできます。
monologの driver のプロセッサをカスタマイズしたい場合は、channel の設定にprocessorsの設定 value を追加してください:
'memory' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\StreamHandler::class,
'with' => [
'stream' => 'php://stderr',
],
'processors' => [
// Simple syntax...
Monolog\Processor\MemoryUsageProcessor::class,
// With options...
[
'processor' => Monolog\Processor\PsrLogMessageProcessor::class,
'with' => ['removeUsedContextFields' => true],
],
],
],
ファクトリーを介した Custom チャンネルの作成
もし Monolog のインスタンス化と設定に完全にコントロールを持つ、全く新たな custom channel を定義したいと思われるなら、config/logging.php 設定ファイルで custom driver type を指定することができます。設定には、Monolog インスタンスを生成するために呼び出される factory class の名称を含む via option を含むべきです。
'channels' => [
'example-custom-channel' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
],
],
custom driverchannels を設定したら、Monolog インスタンスを生成する class を定義する準備が整いました。この class には、Monolog ロガーインスタンスを返すべき __invoke method が単一であれば十分です。この method は、唯一の引数として channels 設定の array を受け取ります:
<?php
namespace App\Logging;
use Monolog\Logger;
class CreateCustomLogger
{
/**
* Create a custom Monolog instance.
*/
public function __invoke(array $config): Logger
{
return new Logger(/* ... */);
}
}
Tailing Log Messages Using Pail
多くの場合、あなたのアプリケーションのログをリアルタイムで追う必要があるかもしれません。たとえば、 debugging の問題を解決したり、アプリケーションのログで特定の種類の errors を監視する際などです。
Laravel Pail は、 command ラインから直接 Laravel application の log ファイルに簡単にアクセスできるようにするパッケージです。標準のtail command とは異なり、Pail は Sentry や Flare を含む任意の log driver と連携して動作するように設計されています。さらに、Pail はあなたが探しているものをすばやく見つけるのに役立つ一連の便利なフィルターを提供します。
Installation
WARNING
はじめに、パッケージマネージャーの Composer を使用して、あなたの project に Pail をインストールします:
composer require laravel/pail
Usage
ログの追跡を開始するには、pail command を実行します:
php artisan pail
output の詳細度を増やし、切り捨て(…)を避けるために、-v オプションを使用します:
php artisan pail -v
最大の詳細性を得るため、そして例外の stack トレースを表示するために、-vv オプションを使用します:
php artisan pail -vv
ログの追跡を停止するには、いつでもCtrl+Cを press こと。
ログのフィルタリング
--filter
あなたは--filterオプションを使用して、その type 、ファイル、メッセージ、そして stack トレースの content によってログをフィルタリングすることが可能です:
php artisan pail --filter="QueryException"
--message
メッセージのみでログをフィルタリングするには、--message オプションを使用できます:
php artisan pail --message="User created"
--level
--levelオプションは、それらのlog levelによってログをフィルタリングするために使用することができます:
php artisan pail --level=error
--user
特定の user が認証されている間に書かれたログのみを表示するには、ユーザーの ID を--userオプションに提供することができます:
php artisan pail --user=1