【Laravel】 ログの出力と設定の方法

Laravelでは、簡単にログを出力することができます。デバッグ用ログ、エラーログといった分類も備えており、slackへの通知などもすぐに作ることができます。

ログ出力の方法

ログを出力するには、Logファサードを使用し、Log::debug('内容');のようにして出力します。

use Illuminate\Support\Facades\Log;

class UserController extends Controller
{
    public function index()
    {
        Log::debug('hoge');
        Log::info('fuga');
        Log::error('hige');
        return view('settings', compact('user')); 
    }
}

出力したログは、デフォルトではstorage/logs/laravel.logに保存されます。

ログの段階

ログには、debug、info、error等の段階があります。下のリストの上の方が緊急度が高いログです。

  1. emergency
  2. alert
  3. critical
  4. error
  5. warning
  6. notice
  7. info
  8. debug

ログのコンテキスト

ログの第2引数に配列を渡すと、それもjson形式で出力してくれます。このとき、クラス名も一緒に出力してくれます。

$user = Auth::user();
Log::debug('hoge', ['user' => $user]);
Log::debug($user);
出力
[2022-03-27 13:12:14] local.DEBUG: hoge {"user":{"App\\Models\\User":{"id":1,"name":"mhgm","email":"xxxxx@yyyyy.com","email_verified_at":"2022-03-26T13:27:10.000000Z","created_at":"2022-03-17T10:24:46.000000Z","updated_at":"2022-03-26T13:27:10.000000Z","tel":"hogehoge"}}} 
[2022-03-27 13:12:14] local.DEBUG: {"id":1,"name":"mhgm","email":"xxxxx@yyyyy.com","email_verified_at":"2022-03-26T13:27:10.000000Z","created_at":"2022-03-17T10:24:46.000000Z","updated_at":"2022-03-26T13:27:10.000000Z","tel":"hogehoge"}  

後続のログに同じ情報を含める

例えばアクセスしたユーザIDなど、同じ情報を複数のログに含めたいことはよくあります。その場合、Log::withContextを用います。

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Log::withContext(['requestUri' => $_SERVER['REQUEST_URI']]);
    }
}
class SettingsController extends Controller
{
    public function index()
    {
        $user = Auth::user();
        Log::debug('hoge');
        Log::debug('fuga');
        return view('settings', compact('user')); 
    }
}
ログ
[2022-03-27 13:22:59] local.DEBUG: hoge {"requestUri":"/settings"} 
[2022-03-27 13:22:59] local.DEBUG: fuga {"requestUri":"/settings"} 

チャンネルドライバ

デフォルトでは、storage/logs/laravel.logの1つのファイルにログが出力されます。日毎にファイルを切り替える、slackに通知するなど、他のログ出力の方法を使用することもできます。

設定は、config/logging.phpにあり、最初からいくつかのチャンネルが設定されています。これらの設定をこのあと見ていきましょう。

ここで、.envを見るとstackがデフォルトになっていることが分かります。

stack

stackでは、複数のチャンネルにログを飛ばすことができます。例えば、

config/logging.php
return [
    // ...
    'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['single', 'slack'],
        'ignore_exceptions' => false,
    ],
    // ...
];

のようにstack.channelsを設定すると、普通のログに加えてslackチャンネルにも飛ばすことができます。

ignore_exceptionsは、

いくつかの設定

channelsの設定を見ると、いくつか共通している設定があります。

driver

driverは使用するドライバーです。

'single' => [
    // これ
    'driver' => 'single',

    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
],

ドライバーにはいくつかの種類がありますが、この種類はLaravelのドキュメントを参照することを推奨します。

https://readouble.com/laravel/9.x/ja/logging.htmlの”利用可能なチャンネルドライバ”にあります。

level

levelは、ログを出力する基準です。

'single' => [
    'driver' => 'single',
    'path' => storage_path('logs/laravel.log'),

    // これ
    'level' => env('LOG_LEVEL', 'debug'),
],

例えばdebugと設定すれば、debug以上のレベルのログの場合にログ出力を行います。

Log::debug('hoge');

'level' => 'warning'の設定にすれば、noticeinfodebugの場合はログ出力されません。本番環境などではinfoに設定すると、ログが適度にスッキリします。

single

singleは、普通のログ出力です。デフォルトの設定では、storage/logs/laravel.logに全てのログが出力されます。

'single' => [
    'driver' => 'single',
    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
],

daily

dailyでは、ログ出力に使用するファイルを毎日切り替えます。ログの出力ファイルにはlogs/laravel-2022-03-28.logのように、日付が付与されます。

'daily' => [
    'driver' => 'daily',
    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
    'days' => 14,
],

daysは、ログを保持する日数です。14の場合は14日分のログを保持します。それより古いものは自動的に削除されます。0に設定した場合、ログは破棄されません

slack

slackでは、slackにデータを送信します。特にcritical以上のログが出力された際に素早く気が付き、対処するために用います。

'slack' => [
    'driver' => 'slack',
    'url' => env('LOG_SLACK_WEBHOOK_URL'),
    'username' => 'Laravel Log',
    'emoji' => ':boom:',
    'level' => env('LOG_LEVEL', 'critical'),
],

slackへのデータ送信となるため、ログのファイルは指定しません。

papertrail

papertrailは、Papertrailというログ管理システムに出力するためのものです。特にherokuとの組み合わせが多いです。

'papertrail' => [
    'driver' => 'monolog',
    'level' => env('LOG_LEVEL', 'debug'),
    'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
    'handler_with' => [
        'host' => env('PAPERTRAIL_URL'),
        'port' => env('PAPERTRAIL_PORT'),
        'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
    ],
],

Papertrailにデータを渡すために必要なのは、URLとポートの2つだけです。アカウント作成後に表示される画面か、画面左上のAdd SystemsをクリックするとYour logs will go to URL:portが表示されます。URLはドメインです。

あとはphp artisan optimizeしてキャッシュをクリアし、Papertrailに送信されるかチェックしましょう。

stderr

stderrは、標準出力への出力です。docker-compose upで起動している場合は色々なログが流れていますが、その流れているログに混ざって出力が行われます。

'stderr' => [
    'driver' => 'monolog',
    'level' => env('LOG_LEVEL', 'debug'),
    'handler' => StreamHandler::class,
    'formatter' => env('LOG_STDERR_FORMATTER'),
    'with' => [
        'stream' => 'php://stderr',
    ],
],
Dockerのログ出力例
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47404 [200]: GET /js/app.js
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47404 Closing
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47408 Accepted
laravel.test_1  | [2022-03-28 12:56:58] local.DEBUG: hoge
laravel.test_1  | [2022-03-28 12:56:58] local.DEBUG: fuga
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47408 Closing
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47412 Accepted
laravel.test_1  | [Mon Mar 28 12:56:58 2022] 172.20.0.1:47412 [200]: GET /favicon.ico

Laravel Sailを用いてDockerで動かしている場合、Dockerの標準出力に表示されます。

syslog

syslogは、その名の通りsyslogで、Linux/UNIXに標準で備わっているログのシステムです。OSのログなどと一緒にLaravelのログが出力されることになります。多くの場合、/var/log内に出力されます。

'syslog' => [
    'driver' => 'syslog',
    'level' => env('LOG_LEVEL', 'debug'),
],

errorlog

errorlogは、PHPのerror_log()を使用したログ出力です。標準的なシステムなら/var/log/php/php.logですが、実際の場所はcat /etc/php.ini | grep error_logなどでPHPの設定を確認することをおすすめします。

'errorlog' => [
    'driver' => 'errorlog',
    'level' => env('LOG_LEVEL', 'debug'),
],

Laravel Sailを用いてDockerで動かしている場合、Dockerの標準出力に表示されます。

null

全てのログメッセージを破棄するものです。ログを出力したくない場合に使用します。

'null' => [
    'driver' => 'monolog',
    'handler' => NullHandler::class,
],

emergency

emergencyは、この設定だけでは動かないので、driverなどを追加する必要があります。

'emergency' => [
    'path' => storage_path('logs/laravel.log'),
],

特定のチャンネルで出力

一部のログだけ別の出力先にしたいなどの場合、logs(channel)->debug('..')のようにします。

logs('stderr')->debug('aaaa');

まとめ

ログの出力では、特定のレベルのログだけを出力するという設定が可能です。また、slackやpapertrailとの連携も簡単に行えます。

環境に応じてログの出力レベルの基準を変え、スムーズに開発やバグ検証などができる環境を整えましょう。

laravel logging thumb

役に立ったらシェアしよう!