====== PSR-3: Logger Interface ======
--- //[[http://www.y2sunlight.com|y2sunlight]] 2020-04-28//
本章は、若干の補足を加筆してはいるものの単に[[https://www.php-fig.org/psr/|PSRのサイト]]を日本語に翻訳したものに過ぎません。英語が堪能な方は原文をご参照下さい。翻訳に当たっては、基本的に機械翻訳を使い、理解できない部分は独断で意訳しております。拙い訳では御座いますが恥を忍んで投稿しておりますので、ご指摘など御座いましたらコメントを頂ければ幸いです。
関連記事
* [[psr:top|PSR - PHP標準勧告]]
* [[psr:psr1|PSR-1: Basic Coding Standard - 基本コーディング規約]]
* PSR-3: Logger Interface - ロガーインターフェイス
* [[psr:psr4|PSR-4: Autoloading Standard - オートローディング規約]]
* [[psr:psr5|PSR-5: PHPDoc Standard(Draft) - PHPDoc規約]]
* [[psr:psr6|PSR-6: Caching Interface - キャッシングインターフェイス]]
* [[psr:psr7|PSR-7: HTTP Message Interface - HTTPメッセージインターフェイス]]
* [[psr:psr11|PSR-11: Container Interface - コンテナインターフェイス]]
* [[psr:psr12|PSR-12: Extended Coding Style - 拡張コーディングスタイル]]
* [[psr:psr13|PSR-13: Link definition interfaces - リンク定義インターフェース]]
* [[psr:psr14|PSR-14: Event Dispatcher - イベントディスパッチャー]]
* [[psr:psr15|PSR-15: HTTP Server Request Handlers - HTTPサーバーリクエストハンドラー]]
* [[psr:psr16|PSR-16: Common Interface for Caching Libraries - キャッシングライブラリのための共通インターフェース]]
* [[psr:psr17|PSR-17: HTTP Factories - HTTPファクトリー]]
* [[psr:psr18|PSR-18: HTTP Client - HTTPクライアント]]
* [[psr:psr19|PSR-19: PHPDoc tags(Draft) - PHPDocタグ]]
-----
====== PSR-3: ロガーインターフェイス ======
--- // 原文より翻訳 [[https://www.php-fig.org/psr/psr-3/|PSR-3: Logger Interface]] 2020-04-28 現在 //
このドキュメントでは、ロギングライブラリの一般的なインターフェースについて説明します。
主な目標は、ライブラリが **Psr\Log\LoggerInterface**オブジェクトを受け取り、シンプルで普遍的な方法でそれにログを書き込むことを可能にすることです。カスタムニーズを持つフレームワークとCMSは、独自の目的のためにインターフェイスを拡張することができますが(''MAY'')、このドキュメントとの互換性を維持する必要があります (''SHOULD'')。 これによって、アプリケーションが使用するサードパーティのライブラリが、一元化されたアプリケーションログを書き込むことが出来るようになります。
このドキュメントのキーワード ''MUST'' , ''MUST NOT'' , ''REQUIRED'' , ''SHALL'' , ''SHALL NOT'' , ''SHOULD'' , ''SHOULD NOT'' , ''RECOMMENDED'' , ''MAY'' 及び ''OPTIONAL'' は、 [[https://www.ietf.org/rfc/rfc2119.txt|RFC 2119]]で説明されているように解釈して下さい。
> **RFC 2119の説明**
> ''MUST'', ''REQUIRED'', ''SHALL'' --- 絶対必要
> ''MUST NOT'', ''SHALL NOT'' --- 絶対禁止
> ''SHOULD'', ''RECOMMENDED'' --- 推奨(但し、無視できる特定の正当な理由が存在するかもしれない)
> ''SHOULD NOT'' --- 推奨できない(但し、許可できる特定の正当な理由が存在するかもしれない)
> ''MAY'', ''OPTIONAL'' --- オプション
このドキュメントの **実装者** という言葉は、**LoggerInterface** をログ関連のライブラリまたはフレームワークに実装する人と解釈して下さい。また、ロガーのユーザーのことは **ユーザー** と呼びます。
\\
===== 1. 仕様 ======
==== 1.1 基本 =====
* **LoggerInterface** は、ログを8つのRFC 5424レベル( **debug**, **info**, **notice**, **warning**, **error**, **critical**, **alert**, **emergency** )に書き込むための8つのメソッドを公開しています。
> [[https://tools.ietf.org/html/rfc5424|RFC 5424]]はイベント通知メッセージの伝達に使用されるsyslog Protocolについて規定されています。
* 9番目のメソッド **log** は、最初の引数としてログレベルを受け入れます。ログレベル定数の1つを使用してこのメソッドを呼び出すと、レベル固有のメソッドを呼び出す場合と同じ結果になる必要があります (''MUST'')。この仕様で定義されていないレベルでメソッドが呼び出された場合、実装がそのレベルを認識していない場合は、**Psr\Log\InvalidArgumentException** をスローする必要があります (''MUST'')。 ユーザーは、現在の実装でサポートされていることを確認せずに、カスタムレベルを使用しないでください (''SHOULD NOT)''。
\\
==== 1.2 メッセージ =====
* すべてのメソッドは、メッセージとして文字列、または **__toString()** メソッドを持つオブジェクトを受け入れます。実装者は、オブジェクトが渡された場合は特別な処理を行う場合があります (''MAY'')。そうでない場合は、文字列にキャストする必要があります (''MUST'')。
* メッセージには、実装者がコンテキスト配列の値で置き換えることができるプレースホルダーが含まれる場合があります (''MAY'')。 \\ \\ プレースホルダー名は、コンテキスト配列のキーに対応している必要があります (''MUST'')。\\ \\ プレースホルダー名は、1つの開始中括弧 **{** および 終了中括弧 **}** で 区切る必要があります (''MUST'')。区切り文字とプレースホルダー名の間に空白があってはいけません (''MUST NOT'')。 例:{name} \\ \\ プレースホルダー名は、**A〜Z**、**a〜z**、**0〜9**、下線( **_** )、および ピリオド( **.** ) の文字だけで構成する必要があります (''SHOULD'')。\\ \\ 実装者は、プレースホルダーを使用して、さまざまなエスケープ方法を実装し、ログを表示用に変換できます (''MAY'')。ユーザはプレースホルダー値を事前にエスケープしないでください (''SHOULD NOT'')。というのは、データはどのコンテキストで表示されるかがわからないからです。\\ \\ 以下は、参照のみを目的として提供されているプレースホルダー挿入の実装例です。\\ \\
$val) {
// check that the value can be casted to string
// 値を文字列にキャストできることを確認する
if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
$replace['{' . $key . '}'] = $val;
}
}
// interpolate replacement values into the message and return
// 置換値をメッセージに挿入して返す
return strtr($message, $replace);
}
// a message with brace-delimited placeholder names
// 中括弧で区切られたプレースホルダー名を含むメッセージ
$message = "User {username} created";
// a context array of placeholder names => replacement values
// コンテキスト配列(プレースホルダー名=>置換値)
$context = array('username' => 'bolivar');
// echoes "User bolivar created"
// "User bolivar created" をエコーする
echo interpolate($message, $context);
\\
==== 1.3 コンテキスト =====
* すべてのメソッドは、コンテキストデータとして配列を受け入れます。これは、文字列にうまく適合しない異質な情報(extraneous information)を保持するためのものです。配列には何でも含めることができます。実装者は、コンテキストデータをできる限り緩やかに扱う必要があります (''MUST'')。コンテキスト内で与えられた値によって、例外をスローしたり、php error、warning、または notice を発生させてはなりません (''MUST NOT'')。
* **Exception** オブジェクトがコンテキストデータで渡される場合、それは **'exception'** キーがなければなりません (''MUST'')。 例外のロギングは一般的なパターンであり、これにより、実装者はログのバックエンドでサポートされている場合、例外からスタックトレースを抽出することができます。実装者は、何かが含まれている可能性があるため、使用する前に **'exception'** キーが実際に例外であることを確認する必要があります (''MUST'')。
\\
==== 1.4 ヘルパークラスとインターフェイス =====
* **Psr\Log\AbstractLogger** クラスを使用すると、**LoggerInterface** を拡張して 一般的な **log()** メソッドを実装することで、**LoggerInterface** を非常に簡単に実装できます。他の8つのメソッドは、メッセージとコンテキストを このlog() に転送しています。
* 同様に、**Psr\Log\LoggerTrait** を使用しても、一般的な log() メソッドを実装するだけで済みます。但し、トレイトはインターフェースを実装できないため、この場合でも **LoggerInterface** を実装する必要があります。
* **Psr\Log\NullLogger** は、インターフェイスと共に提供されます。それは、ロガーが与えられていない時に、フォールバックとして「ブラックホール」実装を提供するために、インターフェイスのユーザによって使用されます (''MAY'')。ただし、コンテキストデータの作成にコストがかかる場合は、条件付きロギングの方が良いアプローチかもしれません。
> ''上記の原文'' \\ The Psr\Log\NullLogger is provided together with the interface. It MAY be used by users of the interface to provide a fall-back “black hole” implementation if no logger is given to them. However, conditional logging may be a better approach if context data creation is expensive. \\ \\ --- 曖昧な翻訳 ---\\ 特に、最後のセンテンスの意味が良く分かりませんでした。conditional logging とは何を意味するのか? それがなぜコンテキストデータ作成と関係しているのか?
* **Psr\Log\LoggerAwareInterface** には **setLogger(LoggerInterface $logger)** メソッドのみが含まれており、フレームワークが任意のインスタンスにロガーを Auto Wiring するために使用できます。
* **Psr\Log\LoggerAwareTrait** トレイトを使用すると、**LoggerAwareInterface** と同等のインターフェイスを任意のクラスに簡単に実装できます。それは **$this->logger** へのアクセスを提供します。
* **Psr\Log\LogLevel** クラスは、8つのログレベルの定数を保持します。
\\
===== 2. パッケージ ======
説明されているインターフェースとクラス、関連する例外クラス、および実装を検証するためのテストスイートは、[[https://packagist.org/packages/psr/log|psr/log]] パッケージの一部として提供されます。
\\
===== 3. Psr\Log\LoggerInterface ======
{{tablelayout?colwidth="20em"}}
^メソッド^要約^
|emergency\\ ($message, array $context = array())|システムが使用できない|
|alert\\ ($message, array $context = array())|すぐに行動を起こす必要がある|
|critical\\ ($message, array $context = array())|危機的な状態|
|error\\ ($message, array $context = array())|すぐに対処する必要はないが、通常はログに記録して監視する必要がある実行時エラー|
|warning\\ ($message, array $context = array())|エラーではない例外的な出来事|
|notice\\ ($message, array $context = array())|正常だが重要なイベント|
|info\\ ($message, array $context = array())|興味深いイベント|
|debug\\ ($message, array $context = array())|詳細なデバッグ情報|
|log($level,\\ $message, array $context = array()|任意のレベルのロギング|
\\
===== 4. Psr\Log\LoggerAwareInterface ======
\\
===== 5. Psr\Log\LogLevel ======
\\