Manual:ログ記録の構造化

This page is a translated version of the page Manual:Structured logging and the translation is 48% complete.
MediaWiki バージョン:
1.25

ログ記録の構造化とは運用上の(バグ修正用)ログ記録で、ポストプロセスに役立つ構造化データで構成されています。 It is distinct from Manual:Special:Log 用に記録を登録する which is logging for the benefit of wiki editors; structured logging is for the benefit of developers.

MediaWiki 1.25 以降、MediaWiki コアと拡張機能ではPSR-3 ログ標準を使用できるようになり、時代遅れのデバッグ記録呼び出しである wfDebug および wfDebugLog が置き換えられました。 PSR-3 標準ではログ メッセージ単位で一連のコンテキスト データを添付でき、構造化されたキー値のペアが提供されます。

LoggerFactory からロガーを取得

use MediaWiki\Logger\LoggerFactory;

$logger = LoggerFactory::getInstance( 'MyCoolLoggingChannel' );

The parameter passed to LoggerFactory::getInstance (here MyCoolLoggingChannel) is the log channel name. How the channel name is used depends on the logging configuration (see below) but typically separate log channels can be directed to separate files or such. You should use something unique (typically the name of your extension) as the channel name to make it easier to separate unrelated log entries.

Send log messages

Once you have a logger object, you can use its method corresponding to PSR-3 severity levels to log messages:

$logger->debug( 'Entered ' . __METHOD__ )
ローカルの開発には便利でも、製品版ウィキに出力するには一般的に「スパムに近似」するメッセージです。 一般的に現状でwfDebugを利用してログ記録したものを網羅します。
$logger->info( 'Restoring page' )
Valuable state change information. This level is a great place to record information that would be useful in a production environment when tracing the path of a request that eventually had an error. wfDebugLog 呼び出しを PSR-3 標準でマッピングすると、現状では自動でこのレベルを付与します。
$logger->warning( 'Page is protected' )
A soft error condition such as a recoverable error or another condition that typically should not happen but isn't halting for the operation in process.
$logger->error( 'Page not found' )
A hard error such as a caught exception with no recovery path.

PSR-3標準に含まれる緊急度は他にもありますが、MediaWikiでの使用は非推奨です。

ログ記録コンテキストに構造化データを付加する

ログ方式に関わらず、どれも以下のようなオプションでコンテキスト オブジェクトがあります:

$logger->warning( 'page not found', [ 'user' => $user->getName(), 'title' => $page->getPrefixedText() ] );

他の利用者が関連メッセージ、関連するデータベース レコードの検索、エラーの原因追跡に使用できるように、ログ メッセージのコンテキスト オブジェクトには有用な構造化データを付加する必要があります。 特にwarningerrorのメッセージについて、ウィキの運用者がコードパスをよく知らなくても良質なバグ報告を書くには、これが重要で有効です。

  • コンテキスト引数で例外オブジェクトを渡すには、必ず「exception」キーに書きます (例: $logger->error( 'got exception', [ 'exception' => $e ] )) [1]
    • You can also generate an exception object on the fly, which is a good way of attaching a stack trace e.g. when logging an error in a utility function that's invoked in many places: $logger->warning( 'called with a user which does not exist', [ 'user' => $user->getName(), 'exception' => new RuntimeException() ] )
  • Attach parameters or other interesting state to messages.

It's best to make sure the items in the context array are strings. (Other types might be allowed, depending on the logging service the wiki uses, but the behavior for non-string values is often unintuitive.) Many MediaWiki core classes have a __toString method which generates some debugging-friendly description of the object so you can just use things like (string)$titleValue.

    • If you do pass non-string values, try to use reasonably unique field names. This is mainly needed for Wikimedia production which sends the context data to Logstash, which requires all context data using same key to be of the same type (globally, across all log channels).
  • 標準の引数 (ウィキ名、サーバ名など) の追加は自動処理されます。ご利用のログ記録サービスによって詳細は異なっても、結局はMediaWiki\Logger\Monolog\WikiProcessorを使うことがありえます。
  • Replace faux structure such as tab-separated items, label=value/label:value pairs, or json serialization.

Many log aggregators try to deduplicate logs by message, so try to keep mutable details out of the message and move them into the context. The logger will replace any tokens inside curly braces with the corresponding value from the context. For example, the code

$logger->error( 'Caught exception while trying to create user {user}: {exception}', [
    'user' => $user->getName(),
    'exception' => $e,
] );

その出力結果の例。

Caught exception while trying to create user Foo: exception DatabaseException with message 'Unique constraint violation' in /srv/mediawiki/includes/Database.php:123
#0 /srv/mediawiki/includes/Database.php(456): Database::query()
...

さまざまなログ記録バックエンドとの互換性を最大にするため、コンテキスト データに下記のキーは使用しないでください:

  • message
  • channel
  • host
  • level
  • type
  • @timestamp
  • @version

Use PSR-3 compatible objects

Throw exceptions which implement INormalizedException (or, if you don't need a custom exception class, use NormalizedException) so that related exception messages can be grouped together in the logs.

You can convert Status and StatusValue objects into PSR-3 logging with:

$statusFormatter = MediaWikiServices::getInstance()->getFormatterFactory()->getStatusFormatter( RequestContext::getMain() );
[ $message, $context ] = $statusFormatter->getPsr3MessageAndContext( $status );
$logger->error( $message, $context );

This is a best effort - Status has a messy internal structure so sometimes this will just end up with something like [ '{message}', 'message' => '...the error message in the Status object' ]. But for statuses holding a single message, it results in nice message strings that are easy to group.

ウィキをログの構造化用に設定する

警告 警告: The default legacy logging implementation in MediaWiki drops most context information!

For backwards compatibility, if you are using the default MediaWiki configuration and have configured basic logging, then whether you supply a context object to these logger methods or to MediaWiki's global functions such as wfDebugLog( 'myChannel', $someMessage, 'private', $someContext ), the information in the context object does not appear in the log files you've configured. monologなど、もっと質のよいログ記録器を「サービスプロバイダ・インターフェース」として採用しなければなりません。 $wgMWLoggerDefaultSpi および Manual:MonologSpi を参照してください。

関連項目