Как правильно конфигурировать логгер и внедрять зависимость?
==============================================================

 Всем привет!  

У меня в проекте много классов, которые выполняют определенные задачи.  

Возникла необходимость логировать.  

Какие-то классы должны писать логи в файл, другие - отправлять по определенному протоколу, или одновременно в несколько источников.  

  

Для этого я выбрал библиотеку Monolog, которая решает мои задачи с записью в логи.  

  

Проблема возникла архитектурная:  

  

т.к. перед использованием класса логгера, его нужно конфигурировать (устанавливать уровень ошибок для логирования, файл или иное хранилище для логов, формат логов и т.д.),  

и это все занимает примерно 20-50 строк кода.  

  

Варианты, которые я хотел реализовать:  

  

1. Изначально, я думал в каждый класс добавить метод - *createLogger*, где бы конфигурировал логгер и возвращал объект. В реализации это очень просто, но это нарушение принципа SRP.   

Т.к. каждый раз нужно будет лезть в класс и изменять метод, если нужно изменить формат лога, или добавить новое хранилище для лога.  

  

2. Создать фабрику, которая будет создавать эти логгеры.  

Но в этом случае, фабрика должна иметь кучу настроек, чтобы можно было сконфигурировать разные логгеры.  

Этот вариант тоже отпадает, т.к. в результате будет очередной класс, который также нужно конфигурировать из десятка строк кода.  

  

3. Внедрять зависимость логгера, через конструктор, а перед использованием класса конфигурировать логгер, и передавать через конструктор.  

Вроде вариант норм. Но почти все классы проекта должны иметь логирование. Неужели у всех классов по умолчанию конструктор должен быть завален аргументами для зависимости-логгера ?  

  

4. Какие есть варианты ? Как это правильно реализовать с точки зрения архитектуры ? 

 5. внедрять логер в зависимости от интерфейса. В DI есть возможность вызвать метод setLogger в зависимости от интерфейса.  

Например вы создаете интерфейсы:   

```
FileLoggerAware extends LoggerAwareInterface 
MysqlLoggerAware extends LoggerAwareInterface
```
  

  

теперь конфигурирует DI   

```
$container->share(FileLogger::class,function(){
       return new NullLogger;//тут реализация file логера
});
$container->share(MysqlLogger::class,function(){
      return new NullLogger;//тут реализация Mysql логера
});
$container
    ->inflector(FileLoggerAware::class)
    ->invokeMethod('setLogger', [FileLogger::class]) 
;
$container
    ->inflector(MysqlLoggerAware::class)
    ->invokeMethod('setLogger', [MysqlLogger::class]) 
;
```
  

  

и все в нужном классе делаешь, (но все классы должны работать через awaring di, прилетать автоматом через конструктор)  

```
class MyClass implements FileLoggerAware
{

use LoggerAwareTrait;

}
```
  

  

ссылки:  

[https://github.com/php-fig/log/blob/master/Psr/Log...](https://github.com/php-fig/log/blob/master/Psr/Log/LoggerAwareInterface.php)  

<https://container.thephpleague.com/3.x/inflectors/>