メインコンテンツまでスキップ
バージョン: 9.x

ロギング (Logging)

導入 (Introduction)

アプリケーション内で何が起こっているかを詳しく知るために、Laravel はメッセージをファイル、システム エラー ログ、さらには Slack に記録してチーム全体に通知できる堅牢なログ サービスを提供します。

Laravelのロギングは「チャネル」に基づいています。各チャネルは、ログ情報を書き込む特定の方法を表します。たとえば、single チャネルはログ ファイルを 1 つのログ ファイルに書き込みますが、slack チャネルはログ メッセージを Slack に送信します。ログ メッセージは、重大度に基づいて複数のチャネルに書き込まれる場合があります。

Laravel は内部で、さまざまな強力なログ ハンドラーのサポートを提供する Monolog ライブラリを利用します。 Laravel を使用すると、これらのハンドラーの設定が簡単になり、それらを組み合わせてアプリケーションのログ処理をカスタマイズできるようになります。

構成 (Configuration)

アプリケーションのロギング動作の構成オプションはすべて、config/logging.php 構成ファイルに格納されています。このファイルを使用すると、アプリケーションのログ チャネルを構成できるため、使用可能な各チャネルとそのオプションを必ず確認してください。以下でいくつかの一般的なオプションを確認します。

デフォルトでは、Laravel はメッセージをログに記録するときに stack チャネルを使用します。 stack チャネルは、複数のログ チャネルを 1 つのチャネルに集約するために使用されます。スタックの構築の詳細については、以下のドキュメント を確認してください。

チャンネル名の設定

デフォルトでは、Monolog は、productionlocal など、現在の環境に一致する「チャネル名」でインスタンス化されます。この値を変更するには、チャネルの構成に name オプションを追加します。

'stack' => [
'driver' => 'stack',
'name' => 'channel-name',
'channels' => ['single', 'slack'],
],

利用可能なチャネルドライバ

各ログ チャネルは「ドライバ」によって駆動されます。ドライバは、ログ メッセージが実際にどのように、どこに記録されるかを決定します。次のログ チャネル ドライバは、すべての Laravel アプリケーションで利用できます。これらのドライバのほとんどのエントリはアプリケーションの config/logging.php 構成ファイルにすでに存在しているため、必ずこのファイルを確認してその内容を理解してください。

名前説明
custom指定されたファクトリを呼び出してチャネルを作成するドライバ
daily毎日ローテーションする RotatingFileHandler ベースの Monolog ドライバ
errorlogErrorLogHandler ベースの Monolog ドライバ
monologサポートされている Monolog ハンドラーを使用できる Monolog ファクトリ ドライバ
nullすべてのログメッセージを破棄するドライバ
papertrailSyslogUdpHandler ベースの Monolog ドライバ
single単一のファイルまたはパスベースのロガーチャネル (StreamHandler)
slackSlackWebhookHandler ベースの Monolog ドライバ
stack「マルチチャネル」チャネルの作成を容易にするラッパー
syslogSyslogHandler ベースの Monolog ドライバ

注記 monolog および custom ドライバの詳細については、高度なチャネルのカスタマイズ のドキュメントを参照してください。

チャネルの前提条件

単一チャネルと日次チャネルの構成

single および daily チャネルには、bubblepermission、および locking の 3 つのオプション構成オプションがあります。

名前説明デフォルト
bubbleメッセージが処理された後に他のチャネルにバブルアップする必要があるかどうかを示しますtrue
lockingログ ファイルに書き込む前にログ ファイルをロックしようとしますfalse
permissionログファイルの権限0644

さらに、daily チャネルの保持ポリシーは、days オプションを使用して構成できます。

名前説明デフォルト
days毎日のログ ファイルを保持する日数7

Papertrail チャネルの構成

papertrail チャネルには、host および port 構成オプションが必要です。これらの値は、Papertrail から取得できます。

Slack チャネルの構成

slack チャネルには、url 構成オプションが必要です。この URL は、Slack チーム用に構成した 受信 Webhook の URL と一致する必要があります。

デフォルトでは、Slack は critical レベル以上のログのみを受信します。ただし、Slack ログ チャネルの構成配列内の level 構成オプションを変更することで、config/logging.php 構成ファイルでこれを調整できます。

非推奨の警告のログ記録

PHP、Laravel、およびその他のライブラリは、機能の一部が非推奨になり、将来のバージョンで削除されることをユーザーに通知することがよくあります。これらの非推奨の警告をログに記録したい場合は、アプリケーションの config/logging.php 構成ファイルで優先する deprecations ログ チャネルを指定できます。

'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),

'channels' => [
...
]

または、deprecations という名前のログ チャネルを定義することもできます。この名前のログ チャネルが存在する場合は、非推奨のログを記録するために常に使用されます。

'channels' => [
'deprecations' => [
'driver' => 'single',
'path' => storage_path('logs/php-deprecation-warnings.log'),
],
],

ログスタックの構築 (Building Log Stacks)

前述したように、stack ドライバを使用すると、便宜上、複数のチャネルを 1 つのログ チャネルに結合できます。ログ スタックの使用方法を説明するために、運用アプリケーションで見られる構成例を見てみましょう。

'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 オプションを介して他の 2 つのチャネル (syslog および slack) を集約していることに注目してください。したがって、メッセージをログに記録する場合、これらのチャネルの両方にメッセージをログに記録する機会があります。ただし、以下で説明するように、これらのチャネルが実際にメッセージをログに記録するかどうかは、メッセージの重大度/「レベル」によって決定される場合があります。

ログレベル

上記の例の syslog および slack チャネル構成に存在する level 構成オプションに注目してください。このオプションは、チャネルによってログに記録されるメッセージの最小「レベル」を決定します。 Laravel のロギング サービスを強化する Monolog は、RFC 5424仕様 で定義されたすべてのログ レベルを提供します。これらのログ レベルは、重大度の降順で、緊急アラート重大エラー警告*、通知情報デバッグです。

そこで、debug メソッドを使用してメッセージをログに記録するとします。

Log::debug('An informational message.');

この構成では、syslog チャネルはメッセージをシステム ログに書き込みます。ただし、エラーメッセージはcritical以上ではないため、Slackには送信されません。ただし、emergency メッセージをログに記録すると、emergency レベルが両方のチャネルの最小レベルしきい値を超えているため、メッセージはシステム ログと Slack の両方に送信されます。

Log::emergency('The system is down!');

ログメッセージの書き込み (Writing Log Messages)

Log facade を使用して、ログに情報を書き込むことができます。前述したように、ロガーは、RFC 5424仕様 で定義された 8 つのログ レベル (緊急アラートクリティカルエラー*、警告通知情報デバッグ) を提供します。

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;

class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
Log::info('Showing the user profile for user: '.$id);

return view('user.profile', [
'user' => User::findOrFail($id)
]);
}
}

コンテキスト情報

コンテキスト データの配列をログ メソッドに渡すことができます。このコンテキスト データはフォーマットされて、ログ メッセージとともに表示されます。

use Illuminate\Support\Facades\Log;

Log::info('User failed to login.', ['id' => $user->id]);

場合によっては、特定のチャネルの後続のすべてのログ エントリに含める必要があるコンテキスト情報を指定したい場合があります。たとえば、アプリケーションへの各受信リクエストに関連付けられたリクエスト ID をログに記録したい場合があります。これを実現するには、Log ファサードの withContext メソッドを呼び出します。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class AssignRequestId
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$requestId = (string) Str::uuid();

Log::withContext([
'request-id' => $requestId
]);

return $next($request)->header('Request-Id', $requestId);
}
}

すべてのロギング チャネル間でコンテキスト情報を共有したい場合は、Log::shareContext() メソッドを呼び出すことができます。このメソッドは、作成されたすべてのチャネルとその後に作成されるすべてのチャネルにコンテキスト情報を提供します。通常、shareContext メソッドは、アプリケーション サービスプロバイダの boot メソッドから呼び出す必要があります。

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class AppServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Log::shareContext([
'invocation-id' => (string) Str::uuid(),
]);
}
}

特定のチャネルへの書き込み

場合によっては、アプリケーションのデフォルト チャネル以外のチャネルにメッセージを記録したい場合があります。 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 Channel Customization)

チャンネルのモノログのカスタマイズ

場合によっては、既存のチャネルに対して Monolog を構成する方法を完全に制御する必要がある場合があります。たとえば、Laravel の組み込み single チャネルに対してカスタム Monolog FormatterInterface 実装を構成することができます。

まず、チャネルの構成で tap 配列を定義します。 tap 配列には、Monolog インスタンスの作成後にカスタマイズ (または「利用」) する機会を持つクラスのリストが含まれている必要があります。これらのクラスを配置する従来の場所はないため、アプリケーション内にこれらのクラスを含むディレクトリを自由に作成できます。

'single' => [
'driver' => 'single',
'tap' => [App\Logging\CustomizeFormatter::class],
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],

チャネルで tap オプションを構成したら、Monolog インスタンスをカスタマイズするクラスを定義する準備が整います。このクラスには、Illuminate\Log\Logger インスタンスを受け取る 1 つのメソッド __invoke のみが必要です。 Illuminate\Log\Logger インスタンスは、すべてのメソッド呼び出しを基になる Monolog インスタンスにプロキシします。

<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
/**
* Customize the given logger instance.
*
* @param \Illuminate\Log\Logger $logger
* @return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new LineFormatter(
'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
));
}
}
}

注記 すべての「タップ」クラスは サービスコンテナ によって解決されるため、必要なコンストラクターの依存関係は自動的に挿入されます。

モノログ ハンドラー チャネルの作成

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 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 のインスタンス化と構成を完全に制御できる完全なカスタム チャネルを定義したい場合は、config/logging.php 構成ファイルで custom ドライバ タイプを指定できます。構成には、Monolog インスタンスを作成するために呼び出されるファクトリ クラスの名前を含む via オプションが含まれている必要があります。

'channels' => [
'example-custom-channel' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
],
],

custom ドライバ チャネルを構成したら、Monolog インスタンスを作成するクラスを定義する準備が整います。このクラスには、Monolog ロガー インスタンスを返す __invoke メソッドが 1 つだけ必要です。このメソッドは、チャネル構成配列を唯一の引数として受け取ります。

<?php

namespace App\Logging;

use Monolog\Logger;

class CreateCustomLogger
{
/**
* Create a custom Monolog instance.
*
* @param array $config
* @return \Monolog\Logger
*/
public function __invoke(array $config)
{
return new Logger(/* ... */);
}
}