Умное логирование больших данных с Effect.logWhenTrace
В разработке часто возникают ситуации, когда нужно залогировать большой объем данных (например, JSON-объекты для отладки), но делать это постоянно нерационально из-за высоких затрат на сериализацию. Решение — логировать такие данные только при активном уровне Trace.
Проблема
При использовании стандартного подхода:
Effect.logTrace(JSON.stringify(bigData, null, 2))
Сериализация в JSON будет выполняться при каждом вызове, даже если уровень трассировки отключен.
Решение: Effect.whenLogLevel
Библиотека Effect предоставляет инструмент для условного выполнения эффектов:
pipe(
  bigData,
  Effect.tap((res) =>
    Effect.whenLogLevel(
      Effect.suspend(() => 
        Effect.logTrace("Данные:", JSON.stringify(res, null, 2))
      ),
      LogLevel.Trace
    )
  )
)
Как это работает:
- Effect.suspendоткладывает выполнение кода до момента активации эффекта
- Effect.whenLogLevelпроверяет текущий уровень логирования
- Сериализация и логирование происходят только при активном уровне Trace
Упрощаем с помощью logWhenTrace
Создаем универсальный хелпер для удобства:
import { Effect, LogLevel, Function } from "effect";
export const logWhenTrace = (...message: ReadonlyArray<any | (() => any)>) =>
  Effect.whenLogLevel(
    Effect.suspend(() =>
      Effect.logTrace(
        ...message.map((item) => 
          Function.isFunction(item) ? item() : item
        )
      )
    ),
    LogLevel.Trace
  );
Особенности реализации:
- Поддерживает как значения, так и функции для ленивых вычислений
- Автоматически определяет тип переданных аргументов
- Сохраняет семантику стандартного Effect.logTrace
Использование
pipe(
  bigData,
  Effect.tap((res) =>
    logWhenTrace(
      "Полученные данные:",
      () => JSON.stringify(res, null, 2) // Выполнится только при Trace
    )
  )
)
Преимущества
- Производительность — избегаем ненужной сериализации
- Чистота кода — лаконичный и выразительный синтаксис
- Безопасность — строгая типизация и контроль уровня логирования
- Гибкость — поддерживает разные форматы данных и логирования
Заключение
Использование условного логирования через logWhenTrace помогает соблюдать баланс между детальностью отладки и производительностью приложения. Этот подход особенно полезен при работе с большими объектами данных и в высоконагруженных приложениях.
Осталось создать аналогичные хелперы для других уровней логирования (Debug, Error) для сохранения консистентности кода.
