Установка и настройка логирования Monolog в Symfony

Во-первых нам надо установить библиотеку для логгирования Monolog. В большинстве случаев он уже установлен, но если нет, воспользуемся composer:


composer require monolog/monolog

Теперь нам надо подключить логгер в нужный класс: контроллер, сервис, консольная команда, в общем куда угодно. Для этого есть 3 варианта:

1. Передать как аргумент в конструктор или нужный метод, например:

class SiteService
{
/** @var LoggerInterface */
private $logger;

/** После присваивания можем использовать логгер в любом методе через свойство класса */
public function __construct(LoggerInterface $logger) {
	$this->logger = $logger;
}

public function index() {
       $this->logger->info('It works!');
}
}

class SiteController extends AbstractController
{
/** Таким образом можем использовать логгер в этом конкретном методе */
public function index(LoggerInterface $logger) {
	$logger->info('It works!');
}
}

Недостатками этого метода является то, что вам постоянно надо передавать логгер в каждый метод, либо объявлять свойство и подключать его в конструкторе для каждого класса.

2. Использовать LoggerAwareTrait:

Работает следующим образом: используем трейт в нужном классе, это создает свойство $logger в классе, а затем через конфигурацию services.yaml присваиваем свойству объект логгера. Пример ниже:


class SiteController extends AbstractController
{
	use LoggerAwareTrait;
	
	public function index() {
		$this->logger->info('It works!');
	}
}

#services.yaml
App\Controller\SiteController:
	calls:
		- setLogger: ['@logger']

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

3. Создать собственный trait

С моей точки зрения лучший вариант, т к достаточно будет только подключения трейта, конфигурацию править не придется. Это достигается за счет того, что мы может сделать вызов метода setLogger, которое присваивает свойству объект логгера автоматически. Это возможно благодоря аннотации required перед методом. Пример ниже:


declare(strict_types=1);

namespace App\Traits;

use Psr\Log\LoggerInterface;

trait LoggerTrait
{
	/** @var LoggerInterface */
	private $logger;

	/**
	 * @required
	 */
	public function setLogger(LoggerInterface $logger): void
	{
		$this->logger = $logger;
	}

	private function getLogger(): LoggerInterface
	{
		return $this->logger;
	}
}

class SiteController extends AbstractController
{
	use App\Traits\LoggerTrait;
	
	public function index() {
		$this->logger->info('It works!');
	}
}

Вот такие варианты, а что использовать решать вам.

Теги: Symfony
Новости