PHP PSR-3 でロガーを最短実装!
いままで、あるクラスにログ出力を実装する場合、手動で LoggerInterface を読み込む処理を書いていました。
ところが最近、sabre/dav という OSS WebDAV サーバープロダクトのソースコードを読んでいると、LoggerAwareInterface や LoggerAwareTrait など、自分では普段使用しない単語が飛び込んできました。そしてコードを読み進めるうちに、その実装が正しいロギング実装であることに気づいてしまったのでした。。。
コード
https://github.com/sabre-io/dav/blob/master/lib/DAV/Server.php
ロガー実装のところだけを抜粋してみます。
<?php use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; class Server implements LoggerAwareInterface { use LoggerAwareTrait; /** * Returns the PSR-3 logger object. * * @return LoggerInterface */ public function getLogger() { if (!$this->logger) { $this->logger = new NullLogger(); } return $this->logger; } }
以上です。なんとシンプル!そして美しい!!
解説
LoggerInterface について
PSR-3 に準拠したロガーは LoggerInterface の実装(振る舞い)を強要されます。
なので実際のロガーが Monolog でも Log4PHP でも LoggerInterface さえ実装していれば種類は気にする必要がない、ということになります。
https://github.com/php-fig/log/blob/master/src/LoggerInterface.php
LoggerAwareInterface について
このインターフェースは外部からロガーをインジェクションできるように setLogger() を実装するためだけのインターフェースです。
インジェクションするロガーは当然 LoggerInterface を実装したものです。
https://github.com/php-fig/log/blob/master/src/LoggerAwareInterface.php
LoggerAwareTrait について
この Trait は上記 LoggerAwareInterface を実装します。つまり、LoggerAwareInterface の実装を自分で書かなくてもいいんです!なんと至れり尽くせり。。。
使い方
これらを実装したクラスは、インスタンス生成後に外部から $instance->setLogger($logger) で Monolog などのロガーをインジェクションし、内部で $this->logger->debug() や $this->logger->error() など、自由にロガーを呼び出せばいいのです。
こんなに簡単にロギング対応の実装ができるとは、今まで書いていたロギング対応のコードが情けなくなります。
気を付けたいのは、これらはインスタンスメソッドであるため、スタテックなメソッドでは使用できないということです。
スタティックメソッドがメインのクラスには、自前でロガーをインジェクションできるような実装をしましょう!
まとめ
- ロギングは簡単に実装できる!
- よいプロダクトのコードを沢山読み、気づきの機会を得よう。
- 判ったつもりで書いていると、学びの機会を失ってしまう。