2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ログファイル名を動的に変更する

Last updated at Posted at 2024-10-30

初出ではMonologのログ書式でしたが、laravel.logと同じログ書式にするため、tapオプションを利用するよう改稿しました。


laravel.log に何でもいれるな

原則として laravel.log はエラーログだけにしたい。エラーが発生しないなら常に空っぽの状態というのが心休まる。
開発時に Debug ログの出力を仕込んだなら、コミットするときに削除(せめてコメントアウト)してもらいたい。

デバックが必要な事態が起きたときに Debug ログを仕込んで laravel.log を監視しても、全然関係ないデバッグ情報が延々と流れてきては辟易する。

定期実行タスクの実行ログや特定機能のデバッグログは、それぞれの機能や目的に応じてログファイル名を変えて保存したい。……ということで、ログファイル名を指定できるカスタムヘルパー logger_to を作ってみた。

カスタムログの設定

まずは config/logging.php にカスタムログ用のチャンネルを追加する。
ドライバーが single なのは、ログローテションは logrotate でおこなうので、Laravel 側で日付毎ログにするのは余計なお世話だから。

'channels' => [
    
    // logger_to 用カスタムチャンネル
    'custom_file' => [
        'driver' => 'single',
        'path' => storage_path('logs/custom.log'),
        'level' => 'debug',
        'tap' => [App\Logging\CustomizeLogFormat::class], // カスタムフォーマッタ
    ],

aa/Logging/CustomizeLogFormat.php

<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;

class CustomizeLogFormat
{
    /**
     * カスタムログの設定
     *
     * @param  \Monolog\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            if ($handler instanceof StreamHandler) {
                $handler->setFormatter(new LineFormatter(
                    null, // デフォルトのフォーマット
                    null, // デフォルトの日付フォーマット
                    true, // マルチラインサポート
                    true  // 末尾の改行を削除しない
                ));
            }
        }
    }
}

カスタムヘルパーを作成

app/Helpers/custom.php

<?php

use Illuminate\Support\Facades\Log;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

if (!function_exists('logger_to')) {
    /**
     * 名前をつけてログを保存
     *
     * @param string $fileName : ファイル名(拡張子不要): 区切りでログレベルを指定可
     *    ログレベル(debug (default), info, notice, warning, error, critical, alert, emergency)
     * @param string $message  : ログメッセージ
     * @param array  $context  : コンテキスト情報
     * @return void
     */
    function logger_to(string $fileName, string $message, array $context = []): void
    {
        if (preg_match('/(.+):(.+)/', $fileName, $m)) {
            $fileName = $m[1];
            $level = $m[2];
        }
        $level = $level ?? 'debug';

        // ファイル名に拡張子があれば削除して .log に置換
        $fileName = preg_replace(['/\.[^.]+$/', '/$/'], ['', '.log'], $fileName);

        // カスタムログチャネルを一時的に構築
        $logger = Log::build([
            'driver' => 'single',
            'path' => storage_path('logs/'. $fileName),
            'level' => $level,
            'tap' => [App\Logging\CustomizeLogFormat::class],
        ]);

        // 指定されたログレベルでメッセージを出力
        $logger->{$level}($message, $context);
    }
}

オートロード設定

composer.json に追加

// composer.json
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "files": [
        "app/Helpers/custom.php"
    ]
}

オートロードのリフレッシュ

composer dump-autoload

使用例

  • mydebug.logに変数$userの配列をDEBUG出力
    logger_to('mydebug', 'user', $user->toArray())
    
  • mytask.logにタスクの開始をINFO出力
    logger_to('mytask:info', 'start task command');
    
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?