ホームページ >バックエンド開発 >PHPチュートリアル >【PHPライブラリ】モノログ
Monolog は PHP 用のロギング ライブラリです。他のロギング ライブラリと比較すると、次のような特徴があります:
最新バージョンをインストールします:
composer require monolog/monolog
PHP バージョン 5.3 以降が必要です。
php<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;// 创建日志频道$log = new Logger('name');$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));// 添加日志记录$log->addWarning('Foo');$log->addError('Bar');
各 Logger インスタンスには、チャネル名 (チャネル) とハンドラー スタックが含まれています。レコードを追加すると、そのレコードはハンドラー スタックを通じて処理されます。各ハンドラーは、次のスタック内の次のハンドラーにレコードを渡すかどうかを決定することもできます。
ハンドラーを通じて、いくつかの複雑なログ操作を実装できます。たとえば、StreamHandler をスタックの一番下に置くと、最終的にすべてのログ レコードがハードディスク ファイルに書き込まれます。同時に、MailHandler をスタックの最上位に配置し、ログ レベルを設定してエラー ログを電子メールで送信します。 Handler には $bubble 属性があります。この属性は、ハンドラーがレコードをインターセプトし、次のハンドラーに流れるのを防ぐかどうかを定義します。したがって、MailHandler の $bubble パラメータを false に設定すると、エラー ログが発生したときに、ログは StreamHandler を通じてハードディスクに書き込まれるのではなく、MailHandler を通じて送信されます。
複数のロガーを作成でき、それぞれが独自のチャネル名とハンドラー スタックを定義できます。ハンドラーは複数のロガー間で共有できます。チャネル名がログに反映されるため、ログ記録の表示とフィルタリングが容易になります。
ログ形式 (Formatter) が指定されていない場合、Handler はデフォルトの Formatter を使用します。
ログ レベルはカスタマイズできません。現在、RFC 5424 で定義されている 8 つのレベル (デバッグ、情報、通知、警告、エラー、クリティカル、アラート、緊急) が使用されます。ログ レコードに他のニーズがある場合は、Processo を通じてログ レコードにコンテンツを追加できます。
php<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;use Monolog\Handler\FirePHPHandler;// 创建Logger实例$logger = new Logger('my_logger');// 添加handler$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));$logger->pushHandler(new FirePHPHandler());// 开始使用$logger->addInfo('My logger is now ready');
最初のステップは、Logger インスタンスを作成し、チャネル名を渡すことです。このチャネル名は、複数の Logger インスタンスを区別するために使用できます。
インスタンス自体はロギングを処理する方法を知りません。それはハンドラーによって処理されます。たとえば、上記の例では 2 つのハンドラーを設定し、2 つの異なる方法でログ レコードを処理できます。
なお、ハンドラーはスタックに保存されるため、後から追加したハンドラーがスタックの一番上に位置し、最初に呼び出されます。
Monolog には、ログに追加情報を追加する 2 つの方法があります。
最初の方法は、$context パラメーターを使用し、配列で渡すことです。
php<?php$logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
2 番目の方法は、プロセッサを使用することです。プロセッサは、ログ レコードをパラメータとして受け取り、追加部分を処理して変更した後に戻る、呼び出し可能なメソッドであればどれでも使用できます。
php<?php$logger->pushProcessor(function ($record) { $record['extra']['dummy'] = 'Hello world!'; return $record;});
Processor は Logger インスタンスにバインドする必要はありませんが、特定のハンドラーにバインドすることもできます。ハンドラーインスタンスのpushProcessorメソッドを使用してバインドします。
ログはチャネル名を使用して分類でき、大規模なアプリケーションで非常に役立ちます。ログレコードはチャンネル名から簡単に選択できます。
たとえば、異なるモジュールのログを同じログ ファイルに記録したい場合、同じハンドラーを異なる Logger インスタンスにバインドでき、これらのインスタンスは異なるチャネル名を使用します。関数内 実用的なハンドラー。ほぼすべての種類の使用シナリオをカバーします。以下にその一部を示します。
StreamHandler: 主にログ ファイルに使用される、PHP ストリームにレコードを書き込みます。NativeMailerHandler: PHP の mail() 関数を使用してログ レコードを送信します。
SocketHandler: ソケット経由でログを書き込みます。
php<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;use Monolog\Handler\FirePHPHandler;// 创建handler$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);$firephp = new FirePHPHandler();// 创建应用的主要logger$logger = new Logger('my_logger');$logger->pushHandler($stream);$logger->pushHandler($firephp);// 通过不同的频道名创建一个用于安全相关的logger$securityLogger = new Logger('security');$securityLogger->pushHandler($stream);$securityLogger->pushHandler($firephp);
ElasticSearchHandler: ElasticSearch サービスにレコードを書き込みます。
BufferHandler: ログ レコードをキャッシュし、それらをすべて一度に処理できるようにします。
更多的Handler请看https://github.com/Seldaek/monolog#handlers。
同样的,这里介绍几个自带的Formatter:
LineFormatter:把日志记录格式化成一行字符串。
HtmlFormatter:把日志记录格式化成HTML表格,主要用于邮件。
JsonFormatter:把日志记录编码成JSON格式。
LogstashFormatter:把日志记录格式化成logstash的事件JSON格式。
ElasticaFormatter:把日志记录格式化成ElasticSearch使用的数据格式。
更多的Formatter请看https://github.com/Seldaek/monolog#formatters。
前面说过,Processor可以为日志记录添加额外的信息,Monolog也提供了一些很实用的processor:
IntrospectionProcessor:增加当前脚本的文件名和类名等信息。
WebProcessor:增加当前请求的URI、请求方法和访问IP等信息。
MemoryUsageProcessor:增加当前内存使用情况信息。
MemoryPeakUsageProcessor:增加内存使用高峰时的信息。
更多的Processor请看https://github.com/Seldaek/monolog#processors。
Monolog内置了很多handler,但是并不是所有场景都能覆盖到,有时需要自己去定制handler。写一个handler并不难,只需要实现Monolog\Handler\HandlerInterface这个接口即可。
下面这个例子实现了把日志记录写到数据库里。我们不需要把接口里的方法全部实现一次,可以直接使用Monolog提供的抽象类AbstractProcessingHandler进行继承,实现里面的write方法即可。
php<?phpuse Monolog\Logger;use Monolog\Handler\AbstractProcessingHandler;class PDOHandler extends AbstractProcessingHandler{ private $initialized = false; private $pdo; private $statement; public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true) { $this->pdo = $pdo; parent::__construct($level, $bubble); } protected function write(array $record) { if (!$this->initialized) { $this->initialize(); } $this->statement->execute(array( 'channel' => $record['channel'], 'level' => $record['level'], 'message' => $record['formatted'], 'time' => $record['datetime']->format('U'), )); } private function initialize() { $this->pdo->exec( 'CREATE TABLE IF NOT EXISTS monolog ' .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)' ); $this->statement = $this->pdo->prepare( 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)' ); }}
然后我们就可以使用它了:
php<?php$logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite'));// You can now use your logger$logger->addInfo('My logger is now ready');
https://github.com/Seldaek/monolog