よっしー
こんにちは。よっしーです(^^)
今日は、Monologのログ出力をカスタマイズする方法についてご紹介します。
背景
Dockerで構築したWebアプリの開発環境において、Monologのログ出力をカスタマイズしたときの方法を備忘として残しました。
開発環境のソースは下記のリポジトリにあります。
修正ファイル
下記のファイルを修正もしくは作成しました。
modified: app/php-fpm/slim_app/app/dependencies.php
modified: app/php-fpm/slim_app/app/routes.php
app/php-fpm/slim_app/app/dependencies.php
@@ -4,9 +4,15 @@ declare(strict_types=1);
use App\Application\Settings\SettingsInterface;
use DI\ContainerBuilder;
+use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
+use Monolog\Processor\IntrospectionProcessor;
+use Monolog\Processor\MemoryPeakUsageProcessor;
+use Monolog\Processor\MemoryUsageProcessor;
+use Monolog\Processor\ProcessIdProcessor;
use Monolog\Processor\UidProcessor;
+use Monolog\Processor\WebProcessor;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
@@ -18,12 +24,20 @@ return function (ContainerBuilder $containerBuilder) {
$loggerSettings = $settings->get('logger');
$logger = new Logger($loggerSettings['name']);
- $processor = new UidProcessor();
- $logger->pushProcessor($processor);
+ $logger->pushProcessor(new UidProcessor());
+ $logger->pushProcessor(new WebProcessor());
+ $logger->pushProcessor(new ProcessIdProcessor());
+ $logger->pushProcessor(new IntrospectionProcessor());
+ $logger->pushProcessor(new MemoryPeakUsageProcessor());
+ $logger->pushProcessor(new MemoryUsageProcessor());
$handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']);
$logger->pushHandler($handler);
+ $format = "%datetime%\t%extra.uid%\t%level_name%\t%extra.http_method%\t%extra.server%%extra.url%\t%extra.process_id%\t%extra.class%%extra.callType%%extra.function%(%extra.line%)\t%message%\t%context%\t%extra%" . PHP_EOL;
+ $formatter = new LineFormatter($format);
+ $handler->setFormatter($formatter);
+
return $logger;
},
app/php-fpm/slim_app/app/routes.php
@@ -6,6 +6,7 @@ use App\Application\Actions\User\ListUsersAction;
use App\Application\Actions\User\ViewUserAction;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Log\LoggerInterface;
use Slim\App;
use Slim\Interfaces\RouteCollectorProxyInterface as Group;
use SlopeIt\ClockMock\ClockMock;
@@ -17,6 +18,8 @@ return function (App $app) {
});
$app->get('/', function (Request $request, Response $response) {
+ $logger = $this->get(LoggerInterface::class);
+ $logger->debug('Hello world!');
$response->getBody()->write('Hello world!');
return $response;
});
検証環境の起動
下記のコマンドを実施します。
# ビルド
make build
# 起動
make up
# 起動確認
make test_req
下記のような出力になっていればOKです。
% make test_req
curl -k https://localhost
Hello world!
ログ出力の確認
下記のコマンドを実施します。
tail app/php-fpm/slim_app/logs/app.log
下記のような出力されていれば成功です。
2023-09-03T14:27:16.510530+00:00 b81b282 DEBUG GET localhost/ 22 Closure->{closure}(22) Hello world! [] {"memory_usage":"4 MB","memory_peak_usage":"4 MB","file":"/var/www/slim_app/app/routes.php","ip":"172.19.0.1","referrer":null}
解説
app/php-fpm/slim_app/app/dependencies.php
$logger->pushProcessor(new UidProcessor());
$logger->pushProcessor(new WebProcessor());
$logger->pushProcessor(new ProcessIdProcessor());
$logger->pushProcessor(new IntrospectionProcessor());
$logger->pushProcessor(new MemoryPeakUsageProcessor());
$logger->pushProcessor(new MemoryUsageProcessor());
PHPのログ処理に関連するプロセッサをロガーに追加する部分です。各プロセッサは、ログエントリに特定の情報や属性を追加したり、整形したりするために使用されます。以下に、それぞれのプロセッサの役割を説明します。
UidProcessor
:- このプロセッサは、一意の識別子(UUIDなど)を生成し、各ログエントリに追加します。これにより、ログエントリごとに一意の識別子が含まれ、ログエントリのトレースと監視が容易になります。
WebProcessor
:WebProcessor
は、ウェブアプリケーションのコンテキストに関する情報をログエントリに追加します。例えば、HTTPリクエストのメソッドやURLなどの情報が含まれます。これにより、ログエントリがどのHTTPリクエストに関連しているかを識別できます。
ProcessIdProcessor
:- このプロセッサは、プロセスのID(PID)をログエントリに追加します。これは、どのプロセスがログエントリを生成したかを特定するのに役立ちます。
IntrospectionProcessor
:IntrospectionProcessor
は、実行中のコードや関数に関する情報をログエントリに追加します。これにより、ログエントリがどの部分のコードで生成されたかを追跡できます。
MemoryPeakUsageProcessor
:- このプロセッサは、ログエントリにメモリのピーク使用量に関する情報を追加します。システムのメモリ使用状況に関するデータを含めることで、リソースの使用状況を監視できます。
MemoryUsageProcessor
:MemoryUsageProcessor
は、ログエントリにメモリの現在の使用量に関する情報を追加します。メモリの現在の状態をログに含めることで、アプリケーションのパフォーマンスやリソースの使用状況を監視できます。
これらのプロセッサは、ログエントリに関連情報を追加して、ログをより詳細で有用なものにするのに役立ちます。プロセッサは、特定のアプリケーションや環境に合わせてカスタマイズできます。
$format = "%datetime%\t%extra.uid%\t%level_name%\t%extra.http_method%\t%extra.server%%extra.url%\t%extra.process_id%\t%extra.class%%extra.callType%%extra.function%(%extra.line%)\t%message%\t%context%\t%extra%" . PHP_EOL;
$formatter = new LineFormatter($format);
$handler->setFormatter($formatter);
ログエントリのフォーマットを設定し、フォーマッタをハンドラに割り当てる部分です。これにより、ログエントリの出力が特定のフォーマットに整形されます。
ここで使用されている主要な要素は以下です:
$format
: ログエントリのフォーマットを定義します。この文字列には、特定のプレースホルダとテキストが含まれています。各プレースホルダは、実際のログエントリに対応する情報を埋め込むために使用されます。$formatter
:$format
で定義されたフォーマット文字列を使用して新しいフォーマッタ(LineFormatter
)インスタンスを作成します。$handler->setFormatter($formatter)
: 作成したフォーマッタをログハンドラに割り当てます。これにより、ハンドラがログエントリを指定されたフォーマットで処理し、出力します。
具体的なプレースホルダとそれらの意味は以下の通りです:
%datetime%
: ログエントリの日時%extra.uid%
: 一意の識別子(例: UUID)%level_name%
: ログレベルの名前(例: INFO, ERROR)%extra.http_method%
: HTTPリクエストのメソッド(例: GET, POST)%extra.server%
: サーバー情報(例: ホスト名)%extra.url%
: リクエストのURL%extra.process_id%
: プロセスID(PID)%extra.class%
: 関連するクラス名%extra.callType%
: 関数呼び出しのタイプ(例: static, method, function)%extra.function%
: 関数名%extra.line%
: ソースコードの行番号%message%
: ログメッセージ%context%
: ログコンテキスト(追加情報)%extra%
: すべての追加情報
このフォーマット文字列を使用することで、ログエントリが特定の形式で整形され、出力されます。ログの形式は、システムの要件や目的に合わせてカスタマイズできます。
おわりに
今日は、Monologのログ出力をカスタマイズする方法についてご紹介しました。
よっしー
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント