# 16. Логирование (PSR-3)

[← Оглавление](./index.md)

---

Инжектируйте PSR-3 `LoggerInterface`. Глобальные функции `AddMessage2Log()` — устаревший подход без уровней и контекста.

## PSR-3 логирование через App\Logger

**ПЛОХО — УСТАРЕВШИЕ ФУНКЦИИ БЕЗ УРОВНЕЙ**
```php
AddMessage2Log('Ошибка создания лида: ' . $message, 'my_module');
// нет уровней severity, нет структурированного контекста, сложно искать
```

**ХОРОШО — PSR-3 С УРОВНЯМИ И КОНТЕКСТОМ**
```php
$logger->info('Lead created', ['leadId' => $lead->getId(), 'userId' => \CUser::GetID()]);

$logger->error('Lead creation failed', [
    'message' => $e->getMessage(),
    'code' => $e->getCode(),
    'trace' => $e->getTraceAsString(),
]);
```

---

## Инжектируйте LoggerInterface, а не конкретную реализацию

**ПЛОХО — КОНКРЕТНАЯ РЕАЛИЗАЦИЯ В КОНСТРУКТОРЕ**
```php
class LeadCreationService {
    private $logger;
    
    public function __construct() {
        // нельзя подменить в тестах, привязка к реализации
        $this->logger = ServiceLocator::getInstance()
			->get('da.main.logger')
			->getLogger($channel, $module);;
    }
}
```

**ХОРОШО — PSR-3 ИНТЕРФЕЙС ЧЕРЕЗ DI**
```php
use Psr\Log\LoggerInterface;

class LeadCreationService {
    public function __construct(
        private \Bitrix\Crm\Service\Factory $factory,
        private LoggerInterface $logger,
    ) {}
    
    public function create(CreateLeadDto $dto): \Bitrix\Main\Result {
        $this->logger->debug('Creating lead', ['title' => $dto->title]);
        // ...
    }
}

// Регистрация в ServiceLocator:
ServiceLocator::getInstance()->addInstanceLazy(
    LoggerInterface::class,
    fn() => ServiceLocator::getInstance()
			->get('da.main.logger')
			->getLogger($channel, $module);
);
```