いままで、あるクラスにログ出力を実装する場合、手動で 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;
    }
}
以上です。なんとシンプル!そして美しい!!
PSR-3 に準拠したロガーは LoggerInterface の実装(振る舞い)を強要されます。
なので実際のロガーが Monolog でも Log4PHP でも LoggerInterface さえ実装していれば種類は気にする必要がない、ということになります。
https://github.com/php-fig/log/blob/master/src/LoggerInterface.php
このインターフェースは外部からロガーをインジェクションできるように setLogger() を実装するためだけのインターフェースです。
インジェクションするロガーは当然 LoggerInterface を実装したものです。
https://github.com/php-fig/log/blob/master/src/LoggerAwareInterface.php
この Trait は上記 LoggerAwareInterface を実装します。つまり、LoggerAwareInterface の実装を自分で書かなくてもいいんです!なんと至れり尽くせり。。。
これらを実装したクラスは、インスタンス生成後に外部から $instance->setLogger($logger) で Monolog などのロガーをインジェクションし、内部で $this->logger->debug() や $this->logger->error() など、自由にロガーを呼び出せばいいのです。
こんなに簡単にロギング対応の実装ができるとは、今まで書いていたロギング対応のコードが情けなくなります。
気を付けたいのは、これらはインスタンスメソッドであるため、スタテックなメソッドでは使用できないということです。
スタティックメソッドがメインのクラスには、自前でロガーをインジェクションできるような実装をしましょう!