Умное логирование больших данных с 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) для сохранения консистентности кода.