ロギング
導入
アプリケーション内で何が起こっているかをより深く理解するために、Laravelは強力なロギングサービスを提供しています。これにより、メッセージをファイル、システムエラーログ、さらにはSlackにログしてチーム全体に通知することができます。
Laravelのロギングは「チャネル」に基づいています。各チャネルは、ログ情報を書き込む特定の方法を表します。たとえば、`single`チャネルはログファイルを単一のログファイルに書き込み、`slack`チャネルはログメッセージをSlackに送信します。ログメッセージは、その重大度に基づいて複数のチャネルに書き込むことができます。
内部的には、Laravelはさまざまな強力なログハンドラーをサポートするMonologライブラリを使用しています。Laravelでは、これらのハンドラーの設定が非常に簡単で、それらを組み合わせてアプリケーションのログ処理をカスタマイズできます。
設定
アプリケーションのロギング動作を制御するすべての設定オプションは、`config/logging.php`設定ファイルに格納されています。このファイルでは、アプリケーションのログチャネルを設定できます。そのため、利用可能な各チャネルとそのオプションを確認してください。以下では、いくつかの一般的なオプションについて説明します。
デフォルトでは、Laravelはメッセージのログに`stack`チャネルを使用します。`stack`チャネルは、複数のログチャネルを単一のチャネルに集約するために使用されます。スタックの構築の詳細については、以下のドキュメントを参照してください。
利用可能なチャネルドライバー
各ログチャネルは「ドライバー」によって制御されています。ドライバーは、ログメッセージが実際にどのように記録されるかを決定します。すべてのLaravelアプリケーションで次のログチャネルドライバーを使用できます。これらのドライバーのほとんどのエントリは、アプリケーションの`config/logging.php`設定ファイルに既に存在しているので、このファイルを確認して内容をよく理解してください。
名前 | 説明 |
---|---|
custom |
チャネルを作成するために指定されたファクトリを呼び出すドライバー。 |
daily |
毎日ローテーションを行う`RotatingFileHandler`ベースのMonologドライバー。 |
errorlog |
`ErrorLogHandler`ベースのMonologドライバー。 |
monolog |
サポートされているMonologハンドラーを使用できるMonologファクトリドライバー。 |
papertrail |
`SyslogUdpHandler`ベースのMonologドライバー。 |
single |
単一ファイルまたはパスベースのロガーチャネル(`StreamHandler`)。 |
slack |
`SlackWebhookHandler`ベースのMonologドライバー。 |
stack |
「マルチチャネル」チャネルを作成するためのラッパー。 |
syslog |
`SyslogHandler`ベースのMonologドライバー。 |
`monolog`および`custom`ドライバーの詳細については、高度なチャネルのカスタマイズに関するドキュメントを参照してください。
チャネル名の設定
デフォルトでは、Monologは`production`や`local`など、現在の環境と一致する「チャネル名」でインスタンス化されます。この値を変更するには、チャネルの設定に`name`オプションを追加できます。
'stack' => [ 'driver' => 'stack', 'name' => 'channel-name', 'channels' => ['single', 'slack'],],
チャネルの前提条件
SingleおよびDailyチャネルの設定
`single`および`daily`チャネルには、`bubble`、`permission`、`locking`の3つのオプションの設定オプションがあります。
名前 | 説明 | デフォルト |
---|---|---|
bubble |
メッセージが処理された後に他のチャネルにバブルアップするかどうかを示します。 | true |
locking |
書き込む前にログファイルをロックしようとします。 | false |
permission |
ログファイルのパーミッション。 | 0644 |
さらに、`daily`チャネルの保持ポリシーは、`LOG_DAILY_DAYS`環境変数で設定するか、`days`設定オプションを設定することで設定できます。
名前 | 説明 | デフォルト |
---|---|---|
days |
毎日ログファイルを保持する日数。 | 14 |
Papertrailチャネルの設定
`papertrail`チャネルには、`host`と`port`の設定オプションが必要です。これらは、`PAPERTRAIL_URL`と`PAPERTRAIL_PORT`環境変数で定義できます。これらの値は、Papertrailから取得できます。
Slackチャネルの設定
`slack`チャネルには、`url`設定オプションが必要です。この値は、`LOG_SLACK_WEBHOOK_URL`環境変数で定義できます。このURLは、Slackチームで設定した着信WebhookのURLと一致する必要があります。
デフォルトでは、Slackは`critical`レベル以上のログのみ受信しますが、`LOG_LEVEL`環境変数を使用するか、Slackログチャネルの設定配列内の`level`設定オプションを変更することで調整できます。
ロギング非推奨警告
PHP、Laravel、その他のライブラリは、多くの機能が非推奨になり、将来のバージョンで削除されることをユーザーに通知することがよくあります。これらの非推奨警告をログに記録する場合は、`LOG_DEPRECATIONS_CHANNEL`環境変数またはアプリケーションの`config/logging.php`設定ファイルを使用して、優先する`deprecations`ログチャネルを指定できます。
'deprecations' => [ 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), 'trace' => env('LOG_DEPRECATIONS_TRACE', false),], 'channels' => [ // ...]
または、`deprecations`という名前のログチャネルを定義することもできます。この名前のログチャネルが存在する場合は、常に非推奨のログに記録されます。
'channels' => [ 'deprecations' => [ 'driver' => 'single', 'path' => storage_path('logs/php-deprecation-warnings.log'), ],],
ログスタックの構築
前述のように、`stack`ドライバーを使用すると、複数のチャネルを単一のログチャネルにまとめて便利です。ログスタックの使用方法を説明するために、本番アプリケーションで見られる可能性のある設定例を見てみましょう。
'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['syslog', 'slack'], '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`チャネルは、その`channels`オプションを介して他の2つのチャネル(`syslog`と`slack`)を集約していることに注意してください。そのため、メッセージをログに記録すると、これらのチャネルの両方がメッセージをログに記録する機会を持ちます。しかし、以下で説明するように、これらのチャネルが実際にメッセージをログに記録するかどうかは、メッセージの重大度/「レベル」によって決まる可能性があります。
ログレベル
上記の例で`syslog`と`slack`チャネルの設定に存在する`level`設定オプションに注意してください。このオプションは、チャネルによってログに記録されるためにメッセージが満たす必要がある最小「レベル」を決定します。Laravelのロギングサービスを制御するMonologは、RFC 5424仕様で定義されているすべてのログレベルを提供します。重大度の降順で、これらのログレベルは:**緊急**、**警告**、**クリティカル**、**エラー**、**警告**、**通知**、**情報**、**デバッグ**です。
そこで、`debug`メソッドを使用してメッセージをログに記録するとします。
Log::debug('An informational message.');
設定を考慮すると、`syslog`チャネルはメッセージをシステムログに書き込みます。ただし、エラーメッセージが`critical`以上ではないため、Slackに送信されません。ただし、`emergency`メッセージをログに記録すると、両方のチャネルの最小レベルしきい値を超えるため、システムログとSlackの両方に送信されます。
Log::emergency('The system is down!');
ログメッセージの書き込み
Log
ファサード を使用して、ログに情報を書き込むことができます。前述のように、ロガーはRFC 5424仕様で定義されている8つのログレベルを提供します: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);
これらのメソッドのいずれかを呼び出して、対応するレベルのメッセージをログに記録できます。デフォルトでは、メッセージはlogging
設定ファイルで設定されたデフォルトのログチャンネルに書き込まれます。
<?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) ]); }}
コンテキスト情報
コンテキストデータの配列をログメソッドに渡すことができます。このコンテキストデータはフォーマットされ、ログメッセージと共に表示されます。
use Illuminate\Support\Facades\Log; Log::info('User {id} failed to login.', ['id' => $user->id]);
特定のチャンネルの後続のすべてのログエントリに含めるべきコンテキスト情報を指定したい場合があります。たとえば、アプリケーションへの各着信リクエストに関連付けられているリクエストIDをログに記録したい場合があります。これを実現するには、Log
ファサードのwithContext
メソッドを呼び出すことができます。
<?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; }}
すべてのログチャンネルでコンテキスト情報を共有したい場合は、Log::shareContext()
メソッドを呼び出すことができます。このメソッドは、作成されたすべてのチャンネルと、その後作成されるすべてのチャンネルにコンテキスト情報を提供します。
<?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 ]); // ... }}
キューされたジョブを処理中にログコンテキストを共有する必要がある場合は、ジョブミドルウェア を使用できます。
特定のチャネルへの書き込み
アプリケーションのデフォルトチャンネル以外のチャンネルにメッセージをログに記録したい場合があります。Log
ファサードのchannel
メソッドを使用して、設定ファイルで定義されている任意のチャンネルを取得し、ログに記録することができます。
use Illuminate\Support\Facades\Log; Log::channel('slack')->info('Something happened!');
複数のチャンネルからなるオンデマンドのログスタックを作成したい場合は、stack
メソッドを使用できます。
Log::stack(['single', 'slack'])->info('Something happened!');
オンデマンドチャンネル
アプリケーションのlogging
設定ファイルにその設定が存在しなくても、実行時に設定を提供することで、オンデマンドチャンネルを作成することも可能です。これを実現するには、設定配列をLog
ファサードのbuild
メソッドに渡すことができます。
use Illuminate\Support\Facades\Log; Log::build([ 'driver' => 'single', 'path' => storage_path('logs/custom.log'),])->info('Something happened!');
オンデマンドログスタックにオンデマンドチャンネルを含めることもできます。これは、stack
メソッドに渡される配列にオンデマンドチャンネルインスタンスを含めることで実現できます。
use Illuminate\Support\Facades\Log; $channel = Log::build([ 'driver' => 'single', 'path' => storage_path('logs/custom.log'),]); Log::stack(['slack', $channel])->info('Something happened!');
Monologチャネルのカスタマイズ
チャネルのMonologのカスタマイズ
既存のチャンネルのMonologの設定方法を完全に制御する必要がある場合があります。たとえば、Laravelの組み込みsingle
チャンネルにカスタムMonolog FormatterInterface
実装を設定したい場合があります。
開始するには、チャンネルの設定にtap
配列を定義します。tap
配列には、作成後にMonologインスタンスをカスタマイズ(または「タップ」)する機会を持つべきクラスのリストを含める必要があります。これらのクラスを配置する従来の場所はないため、アプリケーション内にこれらのクラスを含むディレクトリを作成できます。
'single' => [ 'driver' => 'single', 'tap' => [App\Logging\CustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), 'replace_placeholders' => true,],
チャンネルでtap
オプションを設定したら、Monologインスタンスをカスタマイズするクラスを定義できます。このクラスに必要なのは、Illuminate\Log\Logger
インスタンスを受け取る単一のメソッド__invoke
だけです。Illuminate\Log\Logger
インスタンスは、すべてのメソッド呼び出しを基になる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%' )); } }}
すべての「タップ」クラスはサービスコンテナによって解決されるため、必要なコンストラクタ依存関係は自動的に注入されます。
Monologハンドラーチャネルの作成
Monologにはさまざまな利用可能なハンドラーがあり、Laravelはそれぞれに組み込みのチャンネルを含んでいません。場合によっては、対応するLaravelログドライバーがない特定の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
と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プロセッサ
Monologは、ログに記録する前にメッセージを処理することもできます。独自のプロセッサを作成するか、Monologが提供する既存のプロセッサを使用できます。
monolog
ドライバーのプロセッサをカスタマイズする場合は、チャンネルの設定にprocessors
設定値を追加します。
'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], ], ],],
ファクトリを使用したカスタムチャネルの作成
Monologのインスタンス化と設定を完全に制御できる完全にカスタムのチャンネルを定義する場合は、config/logging.php
設定ファイルにcustom
ドライバータイプを指定できます。設定には、Monologインスタンスを作成するために呼び出されるファクトリクラスの名前を含むvia
オプションを含める必要があります。
'channels' => [ 'example-custom-channel' => [ 'driver' => 'custom', 'via' => App\Logging\CreateCustomLogger::class, ],],
custom
ドライバーチャンネルを設定したら、Monologインスタンスを作成するクラスを定義できます。このクラスに必要なのは、Monologロガーインスタンスを返す単一の__invoke
メソッドだけです。このメソッドは、引数としてチャンネル設定配列を受け取ります。
<?php namespace App\Logging; use Monolog\Logger; class CreateCustomLogger{ /** * Create a custom Monolog instance. */ public function __invoke(array $config): Logger { return new Logger(/* ... */); }}
Pailを使用したログメッセージの追跡
アプリケーションのログをリアルタイムで確認する必要がある場合があります。たとえば、問題のデバッグ時や、特定の種類のエラーについてアプリケーションのログを監視する場合などです。
Laravel Pailは、コマンドラインから直接Laravelアプリケーションのログファイルに簡単にアクセスできるパッケージです。標準のtail
コマンドとは異なり、PailはSentryやFlareを含むあらゆるログドライバーで動作するように設計されています。さらに、Pailは、必要なものをすばやく見つけるのに役立つ便利なフィルターセットを提供します。

インストール
開始するには、Composerパッケージマネージャーを使用してプロジェクトにPailをインストールします。
composer require laravel/pail
使用方法
ログの追跡を開始するには、pail
コマンドを実行します。
php artisan pail
出力の詳細度を高め、切り詰め(…)を回避するには、-v
オプションを使用します。
php artisan pail -v
最大限の詳細度で、例外スタックトレースを表示するには、-vv
オプションを使用します。
php artisan pail -vv
ログの追跡を停止するには、いつでもCtrl+C
を押します。
ログのフィルタリング
--filter
--filter
オプションを使用して、種類、ファイル、メッセージ、スタックトレースの内容でログをフィルタリングできます。
php artisan pail --filter="QueryException"
--message
メッセージだけでログをフィルタリングするには、--message
オプションを使用できます。
php artisan pail --message="User created"
--level
--level
オプションを使用して、ログレベルでログをフィルタリングできます。
php artisan pail --level=error
--user
特定のユーザーが認証されている間に書き込まれたログのみを表示するには、ユーザーのIDを--user
オプションに指定できます。
php artisan pail --user=1