Laravel 9.x ログ

イントロダクション

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

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

内部的にLaravelはMonologライブラリを利用しており、強力なログハンドラを多種に渡りサポートしています。Laravelでは、こうしたハンドラを簡単に設定できるため、ハンドラを組み合わせてアプリケーションのログ処理をカスタマイズできます。

設定

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

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

チャンネル名の設定

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

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

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

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

名前 説明
custom 指定ファクトリを呼び出してチャンネルを作成するドライバ
daily 日毎にファイルを切り替えるRotatingFileHandlerベースのMonologドライバ
errorlog ErrorLogHandlerベースのMonologドライバ
monolog Monologがサポートしているハンドラを使用するMonologファクトリドライバ
null すべてのログメッセージを破棄するドライバ
papertrail SyslogUdpHandlerベースのMonologドライバ
single 単一のファイルまたはパスベースのロガーチャンネル(StreamHandler)
slack SlackWebhookHandlerベースのMonologドライバ
stack 「マルチチャンネル」チャンネルの作成を容易にするラッパー
syslog SyslogHandlerベースのMonologドライバ

Note: 高度なチャンネルのカスタマイズのドキュメントをチェックして、monologおよびcustomドライバの詳細を確認してください。

チャンネルの事前設定

singleチャンネルとdailyチャンネルの設定

singleチャンネルとdailyチャンネルは、bubblepermissionlockingの3オプションの設定オプションがあります。

名前 説明 デフォルト
bubble メッセージが処理された後、他のチャンネルにバブルアップする必要があるかを示す true
locking ログファイルに書き込む前に、ログファイルのロックを試みるかを示す false
permission ログファイルのパーミッション 0644

さらに、dailyチャンネルの保存ポリシーは、daysオプションで設定できます。

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

Papertrailチャンネルの設定

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

Slackチャンネルの設定

slackチャンネルにはurl設定オプションが必要です。このURLは、皆さんのSlackチーム用に設定した受信WebフックののURLと一致する必要があります。

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

廃止ワーニングのログ

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

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

'channels' => [
    ...
]

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

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

ログスタックの構築

前述のように、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つのチャンネルsyslogslackを集約している点に注目してください。したがって、メッセージをログに記録するとき、これらのチャンネルの両方にメッセージをログに記録する機会があります。ただし、以降で説明するように、これらのチャンネルが実際にメッセージをログに記録するかどうかは、メッセージの重大度/「レベル」によって決定されます。

ログレベル

上記の例のsyslogおよびslackチャンネル設定に存在するlevel設定オプションに注意してください。このオプションは、チャンネルによってログに記録されるためにメッセージが必要とする最小の「レベル」を決定します。Laravelのログサービスを強化するMonologは、RFC5424仕様で定義されているすべてのログレベルを提供しています。これらのログレベルは、重要度の高い順に、emergencyalertcriticalerrorwarningnoticeinfodebugです。

では、debugメソッドを使用してメッセージをログに記録してみましょう。

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

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

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

ログメッセージの書き込み

Logファサードを使用してログに情報を書き込むことができます。前述のように、ロガーはRFC5424仕様で定義されている8つのログレベルを提供しますemergencyalertcriticalerrorwarningnoticeinfodebug

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
{
    /**
     * 特定のユーザーのプロファイルの表示
     *
     * @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)
        ]);
    }
}

コンテキスト情報

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

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
{
    /**
     * 受信リクエストの処理
     *
     * @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
{
    /**
     * 全アプリケーションサービスの初期起動処理
     *
     * @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チャンネルカスタマイズ

チャンネル向けMonologカスタマイズ

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

このためには、チャンネルの設定でtap配列を定義します。tap配列には、Monologインスタンスの作成後にカスタマイズする(またはtap into:入れ込む)機会が必要なクラスのリストを含める必要があります。これらのクラスを配置する決まった場所はないため、アプリケーション内にこれらのクラスを含むディレクトリを自由に作成できます。

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

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

<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * 指定するロガーインスタンスをカスタマイズ
     *
     * @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%'
            ));
        }
    }
}

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

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ドライバを使用する場合、MonologLineFormatterがデフォルトのフォーマッターとして使用されます。ただし、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メソッドのみが必要です。このメソッドは、チャンネル設定配列を唯一の引数として受け取ります。

<?php

namespace App\Logging;

use Monolog\Logger;

class CreateCustomLogger
{
    /**
     * カスタムMonologインスタンスの生成
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        return new Logger(/* ... */);
    }
}

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる