ホームページ > バックエンド開発 > PHPチュートリアル > [ツール リソース] PHP パッケージのモノログに関する不完全ではあるが十分なガイド

[ツール リソース] PHP パッケージのモノログに関する不完全ではあるが十分なガイド

WBOY
リリース: 2016-06-23 13:03:17
オリジナル
1061 人が閲覧しました

Monolog は、ログをファイル、ソケット、受信箱、データベース、およびさまざまな Web サービス (クラウド) に送信します。モノログは 1 つ以上のストレージ メディアに同時に保存できます (スタック バブリング処理が続きます)。

インストール

$ composer require monolog/monolog
ログイン後にコピー

基本的な使い方(第一印象)

<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;// create a log channel$log = new Logger('name');$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));// add records to the log$log->warning('Foo');$log->error('Bar');
ログイン後にコピー

コアコンセプト¶公式説明

ロガーにレコードを追加するたびに、すべてのロガーインスタンスにはチャネル (名前) とハンドラーのスタックがあります。各ハンドラーは、レコードを完全に処理したかどうかを判断し、レコードの伝播はそこで終了します

各 Logger インスタンスには

channel

(つまり、一意の名前) と A

があります。 1 つ以上のハンドラーで構成されるスタック。 Logger にレコードを追加すると、レコードはハンドラー スタックを通過します。各ハンドラーはレコードを完全に処理するかどうかを決定し、完全に処理する場合はプロセスを終了します (バブリングを停止します)。ここでのフルとは、考えているか考えていないかを指します。考えたくない場合は、続けることができます。 これにより、ログを柔軟に設定できるようになります。たとえば、スタック

の一番下にあるStreamHandlerは、すべてのレコードをハードディスクに保存します。その上には、エラーメッセージが記録されたときに電子メールを送信するMailHandlerがあります。すべてのハンドラーには $bubble 属性があり、これは、レコードの処理時にハンドラーが処理をブロックするかどうかを定義するために使用されます (ブロックされた場合、レコードが到着後に処理されることを意味するため、バブルアップして処理しないでください)従順です)。この例では、MailHandler の $bubble を false に設定します。これは、レコードが MailHandler によって処理され、StreamHandler にバブルアップされないことを意味します。

追加: ここでスタックとバブリングについて言及されていますが、バブリングはボトムアップのプロセスであることが理解されているため、一見すると少し混乱するように思えます。下が StreamHandler、上が MailHandler、その結果、MailHandler が処理して StreamHandler へのバブリングを停止しました。666 というバブルが上から下に向かって泡立っているような印象を受けますが、これはバブリングと言えるでしょうか。

英雄的な瞬間:

スタック、時々混乱することがありますが、スタックは先入れ先出し (

First- In/ First- Out) であることをもう一度思い出してください。来てください] 水パイプ; スタックは先入れ、後出しです (F最初- In/ Last- Out)、カップの中にN層の色があるアイスクリームを考えてください、そして下は黄色、...、上はピンクなので、最初にピンクのもの (MailHandler) を食べ、次に黄色のもの (StreamHandler) を食べます。実際、このバブルは正しいです。正確には、このバブルです。逆さのカップ、この理解は鮮明です。 続行...

多くのロガーを作成でき、各ロガーはチャネル (例: db、リクエスト、ルーターなど) を定義し、各チャネルは複数のハンドラーと組み合わせることができ、ハンドラーは次のように記述できます。普遍的かどうか。チャンネルはログの日付と時刻と同じです。 ログには、おそらく次のような文字列が記録されます。 チャンネル名は内容を記録します。特定の形式は設定によって異なります。識別またはフィルタリングに使用できます。

各ハンドラーには、ログのフォーマットに使用されるフォーマッタがあります。詳細は不要です。

monolog では、カスタマイズされたログ レベルは利用できません。RFC 5424 レベルは、デバッグ、情報、通知、警告、エラー、クリティカル、アラート、緊急の 8 つだけです。ただし、分類などの特別なニーズが本当にある場合は、もちろんログ メッセージが処理される前に、プロセッサをロガーに追加できます。 私は、この人生で「プロセッサ」を追加することはないと考えています。

日志等级

  • DEBUG (100): Detailed debug information.详细的Debug信息
  • INFO (200): Interesting events. Examples: User logs in, SQL logs.感兴趣的事件或信息,如用户登录信息,SQL日志信息
  • NOTICE (250): Normal but significant events.普通但重要的事件信息
  • WARNING (300): Exceptional occurrences that are not errors. Examples: Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong.
  • ERROR (400): Runtime errors that do not require immediate action but should typically be logged and monitored.
  • CRITICAL (500): Critical conditions. Example: Application component unavailable, unexpected exception.
  • ALERT (550): Action must be taken immediately. Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up.
  • EMERGENCY (600): Emergency: system is unusable.

配置一个Logger

Here is a basic setup to log to a file and to firephp on the DEBUG level:

<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;use Monolog\Handler\FirePHPHandler;// Create the logger$logger = new Logger('my_logger');// Now add some handlers$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));$logger->pushHandler(new FirePHPHandler());// You can now use your logger$logger->addInfo('My logger is now ready');
ログイン後にコピー

我们来分析一下这个配置。 The first step is to create the logger instance which will be used in your code. The argument is a channel name, which is useful when you use several loggers (see below for more details about it). 第一步,创建 Logger实例,参数即通道名字。

The logger itself does not know how to handle a record. It delegates it to some handlers. The code above registers two handlers in the stack to allow handling records in two different ways. Logger本身不知道如何处理记录,它将处理委托给 Handler[s],上面的代码注册了两个 Handlers,这样就可以用两种方法来处理记录。

Note that the FirePHPHandler is called first as it is added on top of the stack. This allows you to temporarily add a logger with bubbling disabled if you want to override other configured loggers. 提示: FirePHPHandler最先被调用,因为它被添加在栈的顶部。这就允许你临时添加一个阻塞的 Logger,如果你想覆盖其他 Logger[s]的话。

添加额外的数据到记录

Monolog 提供两种方法来添加额外的信息到简单的文本信息(along the simple textual message)。

使用日志上下文

第一种,即当前日志上下文,允许传递一个数组作为第二个参数,这个数组的数据是额外的信息:

<?php$logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
ログイン後にコピー

简单的Handler(SteamHandler)会简单的将数组格式化为字符串,功能丰富点的Handler(FirePHP)可以搞得更好看。

使用 processors

Processors 可以是任何可调用的方法(回调)。它们接受 $record作为参数,然后返回它( $record),返回之前,即是我们添加 额外信息的操作,在这里,这个操作是改变 $record的 extrakey的值。像这样:

<?php$logger->pushProcessor(function ($record) {     $record['extra']['dummy'] = 'Hello world!';     return $record;});
ログイン後にコピー

Monolog 提供了一些内置的 processors。看 dedicated chapter收回我说的话,我可能很快就会用到 Processors的。

使用通道

通道是识别record记录的是程序哪部分的好方法(当然,关键词匹配啊),这在大型应用中很有用,如 MonologBundle in Symfony2。

想象一下,两个 Logger共用一个 Handler,通过这个 Handler将记录写入一个文件。这时使用通道能够让我们识别出是哪一个 Logger处理的。我们可简单的在这个文件中过滤这个或者那个通道。

<?phpuse Monolog\Logger;use Monolog\Handler\StreamHandler;use Monolog\Handler\FirePHPHandler;// Create some handlers$stream = new StreamHandler(__DIR__ . '/my_app.log', Logger::DEBUG);$firephp = new FirePHPHandler();// Create the main logger of the app$logger = new Logger('my_logger');$logger->pushHandler($stream);$logger->pushHandler($firephp);// Create a logger for the security-related stuff with a different channel$securityLogger = new Logger('security');$securityLogger->pushHandler($stream);$securityLogger->pushHandler($firephp);// Or clone the first one to only change the channel$securityLogger = $logger->withName('security');
ログイン後にコピー

自定义日志格式

在 Monolog 中个性化日志是很easy的。大部分 Handler 使用 $record['formatted']的值。这个值依赖于 formatter 的设置。我们可以选择预定义的 formatter 类或者编写自己的。

配置一个预定义的 formatter 类,只需要将其设置成 Handler 的字段(属性)即可:

// the default format is "Y-m-d H:i:s"$dateFormat = "Y n j, g:i a";// the default output format is [%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"$output = "%datetime% > %level_name% > %message% %context% %extra%\n";$formatter = new LineFormatter($output, $dateFormat);// Create a handler$stream = new StreamHandler(__DIR__ . 'my_app.log', Logger:DEBUG);$stream->setFormatter($formatter);// bind it to a logger object$securityLogger = new Logger('security');$securityLogger->pushHandler($stream);
ログイン後にコピー

formatter 是可以在N个 Handler 之间复用的,并且可在N个 Logger 之间共享 Handler。

ハンドラー

ファイルとシステムログ (syslog) へのログ記録

  • StreamHandler: 任意の PHP ストリームにログを記録し、ファイルへのログ記録に使用します。
  • RotatingFileHandler: 1 日あたり 1 つのファイル、$maxFiles より古いファイルは自動的に削除されますが、これは非常にカジュアルな解決策です。ただし、ハイプロファイルのセットアップには logrotate を使用する必要があります。
  • sysloghandler:phpのerror_log()関数に記録を記録します。
  • SwiftMailerHandler: Swift_Mailer インスタンスを使用して電子メールを送信します。
  • PushoverHandler: Pushover API を使用してレコードを HipChat チャット ルームに記録します。

FlowdockHandler: レコードを Flowdock アカウントに記録します。

SlackHandler: Slack アカウントにレコードを記録します。

MandrillHandler: Swift_Message インスタンスを使用して、Mandrill API 経由でメールを送信します。

FleepHookHandler: Webhook を使用して、レコードを Fleep 会話に記録します。

  • 指定されたサーバーとネットワークのログに記録します
  • 次を参照してください
  • SocketHandler: レコードをソケットに記録します。これを UNIX および TCP ソケットに使用します。 AmqpHandler: レコードを amqp 互換サーバーに記録します。 php-amqpextension (1.0 以降)。GelfHandler: Graylog2server にレコードをログします。CubeHandler: Cubeserver にレコードをログします。ZendMonitorHandler: NewRelicHandler にある Zend Monitor にレコードをログします。 LogglyHandler: Logglyaccount にレコードを記録します。 RollbarHandler: Rollbaraccount にレコードを記録します。
  • 開発環境では、ブラウザ拡張機能を使用します
  • FirePHPHandler: ハンドラーFirePHP 用、FireBug 内でインライン コンソール メッセージを提供する ChromePHP 用のハンドラー、Chrome 内でインライン コンソール メッセージを提供する BrowserConsoleHandler: コンソール API をサポートするほとんどのブラウザーがサポートされています。 PHP コンソールの場合、Chrome 内のインライン コンソールと通知ポップアップ メッセージを redisserver に提供します。 MongoDBHandler: Mongoextension 接続を介してレコードを CouchDB サーバーに記録します。 Doctrine CouchDB ODM: Elastic Search サーバーにレコードを記録します。 DynamoDbHandler: AWS SDK を使用してレコードを DynamoDB テーブルに記録します。 logger をパラメータとして使用し、レコードが定義された重大度レベルを超えるまで、すべてのレベルのログ レコードを蓄積します。その時点で、より低い重大度のレコードも含めて、実際にエラーが発生するまで、すべてのレコードがラップされることになります。ログには何も表示されませんが、ログが発生すると、デバッグや情報レコードを含む完全な情報が得られます。ただし、必要な場合にのみ提供されます。重大なエラーが発生したときに通知または電子メールを送信します。ロガーをパラメータとして受け取り、リクエストが終了するまで (または、flush() が呼び出されるまで)、すべてのレコードをラップするハンドラーに渡します。ただし、レコードが一定期間 (デフォルトでは 60 秒) にわたって一意である場合に限ります。レコードが重複している場合、これの主な用途は、データベースにアクセスできない場合など、すべてのリクエストが発生した場合です。このハンドラーを追加すると、通知の量が管理可能なレベルに減ります
  • WhatFailureGroupHandler: このハンドラーは、GroupHandler を拡張し、各子ハンドラーによって発生した例外を無視します。これにより、リモート TCP 接続が切断された可能性があるが、アプリケーション全体がクラッシュすることは望ましくなく、他のハンドラーへのログを継続したい場合の問題を無視できます。

    BufferHandler: このハンドラーは、close() が呼び出されるまで、受信したすべてのログ レコードをバッファリングします。close() が呼び出された時点で、すべてのログ メッセージを一度にラップするハンドラーの handleBatch() を呼び出します。これは、たとえば、ログ レコードごとに 1 つのメールを送信する代わりに、すべてのレコードを含む電子メールを一度に送信する場合に非常に便利です。

    GroupHandler: このハンドラーは他のハンドラーをグループ化します。受信したすべてのレコードは、構成されているすべてのハンドラーに送信されます。

    FilterHandler: このハンドラーは、指定されたレベルのレコードのみをラップされたハンドラーに渡します。

    SamplingHandler: 別のハンドラーをラップし、一部のみを保存したい場合にレコードをサンプリングできるようにします。

    NullHandler: 処理できるレコードはすべて破棄されます。これを使用して、既存のハンドラー スタックの上に置き、一時的に無効にすることができます。

    PsrHandler: ログ レコードを既存の PSR-3 ロガーに転送するために使用できます。

    TestHandler: テストに使用され、送信されたすべてのものを記録し、情報を読み出すアクセサーを備えています。

    HandlerWrapper: 独自のラッパーを簡単に作成するために継承できるシンプルなハンドラー ラッパー。

    Formatters

    ✪ として常用

    • LineFormatter: ログ レコードを 1 行の文字列にフォーマットします。 ✪
    • HtmlFormatter: ログ レコードを人間が判読できる HTML テーブルにフォーマットするために使用され、主に電子メールに適しています。✪
    • NormalizerFormatter: オブジェクト/リソースを文字列に正規化し、レコードを簡単にシリアル化/エンコードできるようにします。
    • ScalarFormatter: ログ レコードをスカラー値の連想配列にフォーマットするために使用されます。
    • JsonFormatter: ログ レコードを json にエンコードします。✪
    • WildfireFormatter: ログ レコードを Wildfire/FirePHP プロトコルにフォーマットするために使用され、FirePHPHandler でのみ役立ちます。
    • ChromePHPFormatter: ログ レコードを ChromePHP 形式にフォーマットするために使用され、ChromePHPHandler でのみ役立ちます。
    • GelfMessageFormatter: ログ レコードを Gelf メッセージ インスタンスにフォーマットするために使用され、GelfHandler でのみ役立ちます。
    • LogstashFormatter: ログ レコードを logstash イベント JSON にフォーマットするために使用され、ここの入力の下にリストされているハンドラーに役立ちます。
    • ElasticaFormatter: ログ レコードを ElasticaDocument オブジェクトにフォーマットするために使用され、ElasticSearchHandler でのみ役立ちます。
    • LogglyFormatter: ログ レコードを Loggly メッセージにフォーマットするために使用され、LogglyHandler でのみ役立ちます。
    • FlowdockFormatter: ログ レコードを Flowdock メッセージにフォーマットするために使用され、FlowdockHandler でのみ役立ちます。
    • MongoDBFormatter: DateTime インスタンスを MongoDate に変換し、オブジェクトを再帰的に配列に変換します。MongoDBHandler でのみ有効です。

    Processors

    • PsrLogMessageProcessor: PSR-3 ルールに従ってログ レコードのメッセージを処理し、{foo} を $context[‘foo’] の値に置き換えます。

    • IntrospectionProcessor: ログ呼び出しの元の行/ファイル/クラス/メソッドを追加します。

    • WebProcessor: 現在のリクエスト URI、リクエスト メソッド、およびクライアント IP をログ レコードに追加します。

    • MemoryUsageProcessor: 現在のメモリ使用量をログ レコードに追加します。

    • MemoryPeakUsageProcessor: ピーク メモリ使用量をログ レコードに追加します。

    • ProcessIdProcessor: プロセス ID をログ レコードに追加します。

    • UidProcessor: 一意の識別子をログ レコードに追加します。

    • GitProcessor: 現在の git ブランチを追加し、ログ レコードにコミットします。

    • TagProcessor: 事前定義されたタグの配列をログ レコードに追加します。

    Utilities

    • レジストリ: MonologRegistry クラスを使用すると、どこからでも静的にアクセスできるグローバル ロガーを構成できます。これは実際にはベスト プラクティスではありませんが、一部の古いコードベースや使いやすさに役立ちます。 MonologRegistry は、完全に構成されたロガーを許可し、完全に静的にアクセスすることができますが、これは最適な方法ではありませんが、特定の古いコード パッケージでいくつかの助けを提供することも、単に単独で使用することもできます。

    • ErrorHandler: The Monolog\ErrorHandlerclass allows you to easily register a Logger instance as an exception handler, error handler or fatal error handler. Monolog\ErrorHandler允许我们注册一个 Logger实例作为一个异常处理句柄,错误处理句柄或者致命错误处理句柄。

    • ErrorLevelActivationStrategy: Activates a FingersCrossedHandler when a certain log level is reached. 当达到某个日志等级的时候激活 FingersCrossedHandler。

    • ChannelLevelActivationStrategy: Activates a FingersCrossedHandler when a certain log level is reached, depending on which channel received the log record. 当达到某个日志等级的时候激活 FingersCrossedHandler,取决于哪个通道收到日志信息。

    Extending Monolog

    Monolog 是完全可以扩展的。可以轻松让logger适用于我们的需求。

    编写自己的 Handler

    虽然 Monolog 提供了很多内置的 Handler,但是我们依然可能没有找到我们想要的那个,这时我们就要来编写并使用自己的了。仅需 implement Monolog\Handler\HandlerInterface。

    来写个 PDOHandler,用来把日志存到数据库,我们继承 Monolog 提供的抽象类,以坚守 Don’t Rpeat Yourself原则。

        <?php    use 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 = false)        {            $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)'            );            $this->initialized = true;        }    }
    ログイン後にコピー

    现在就可以在Logger中使用这个Handler了:

    $logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')));// You can now use your logger$logger->addInfo('My logger is now ready');
    ログイン後にコピー

    Monolog\Handler\AbstractProcessingHandler提供了Handler需要的大部分逻辑,包括processors的使用以及record的格式化(which is why we use  $record['formatted']instead of  $record['message'])。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート