Что лучше: передавать логгер в качестве параметра функции или объявить его на уровне модуля и использовать напрямую?

Как лучше организовать передачу логгера в вашем коде: передавать его в качестве параметра каждой функции или объявить его в главном модуле (например, в main или app) и обращаться к нему напрямую? Я беспокоюсь, что при обращении к API несколько обработчиков запросов могут работать с логгером одновременно. Какой из этих подходов вы считаете более целесообразным для использования с логгером slog?
  • 5 ноября 2024 г. 12:12
Ответы на вопрос 2
При выборе подхода к организации логирования в вашем коде важно учитывать несколько факторов, таких как доступность, гибкость, удобочитаемость и тестируемость. Рассмотрим оба варианта:

### 1. Передача логгера в качестве параметра функции:

**Преимущества:**
- **Явность:** Логгер передается как аргумент, что делает его использование явным для каждого вызова функции. Легче понять, какой логгер используется в конкретной функции.
- **Тестируемость:** Упрощает написание модульных тестов, поскольку можно легко подменить логгер на "мок" или другой пример для тестирования.
- **Гибкость:** Позволяет использовать разные логгеры или настройки для разных частей приложения. Например, вы можете иметь различные конфигурации логгера для разработки и продакшн-среды.

**Недостатки:**
- **Шумный код:** В каждой функции придется добавлять параметр логгера, что делает подпись функций более громоздкой и может усложнить чтение кода.

### 2. Объявление логгера на уровне модуля:

**Преимущества:**
- **Простота:** Логгер доступен везде без лишних аргументов в функциях. Код может быть более чистым и легким для чтения.
- **Удобство:** Всякий раз, когда вам нужен логгер, вы просто используете его, что может сделать код менее запутанным.

**Недостатки:**
- **Неявность:** Использование глобального состояния может привести к потере контроля, и становится труднее видеть, какие функции используют какой логгер.
- **Проблемы с тестированием:** Глобальный логгер затрудняет использование моков или подмены логгера при тестировании.
- **Проблемы с многопоточностью:** Если ваше приложение многопоточное, следует заботиться о потокобезопасности общего логгирования. Хотя большинство современных логгеров, как правило, потокобезопасны, это может все же вызвать трудности, если не учитывать взаимодействия.

### Рекомендация

Если ваше приложение небольшое или логика не слишком сложная, использование глобального логгера может быть удобным. Однако, если ваше приложение достаточно сложное или вы планируете его расширять, лучше отдать предпочтение передаче логгера как параметра. 

Это повысит гибкость вашего кода, упростит тестирование и способствует более явному и чистому дизайну. Также, если вы беспокоитесь о многопоточности, убедитесь, что ваш логгер (например, slog) потокобезопасен, или рассмотрите использование контекста для передачи логгера и управления состоянием.
Насчёт параллельных обращений. slog очень гибкий и продуманный логгер. Не стоит беспокоиться насчёт параллельных обращений, там всё отлично с этим. 

Насчёт того, использовать ли логгер глобально...
На этот вопрос трудно ответить, не зная, какой у вас проект.

Лично я предпочитаю пользоваться принципом "Бритвы Оккама" и не вводить новых сущностей без необходимости.

Сначала надо задаться вопросом: а нужны ли мне разные варианты логгера в одном и том же окружении? Что я такого буду логгировать в разные места и разным образом, чтобы мне надо было иметь кучу разных логгеров и передавать их как зависимость в каждую функцию или в каждый ваш синглтончик. И если не нужны, то зачем городить огород?

Тем более, что даже для тестов вы можете написать для slog какой-то особый хэндлер, который будет работать так, как надо в тестах.

Поэтому я последнее время всегда использую глобальный slog. В начале программы загружаю конфиг, переменные окружения, определяю, какой мне в этом окружении будет нужен логгер, и конфигурирую дефолтный slog с нужным мне хендлером.

Вот вам крайне увлекательное и крайне полезное видео, как из глобального slog можно сделать просто монстра логгирования на все случаи жизни.
https://www.youtube.com/watch?v=p9XiOOU52Qw
Похожие вопросы