Логирование объектов

В приложениях, где используются временные данные, библиотека Luxon предоставляет структуры DateTime, Duration и Interval, которые существенно отличаются от стандартного Date. При попадании таких объектов в систему логирования возникают проблемы сериализации, потери контекста и неконсистентного отображения в консоли и лог-файлах.

Природа объектов Luxon и влияние на логирование

Объекты Luxon являются иммутабельными структурами, содержащими внутреннее представление времени и метаданных локали, таймзоны и формата. При прямом логировании через console.log или при сериализации через JSON.stringify поведение отличается от примитивных типов.

Основная особенность заключается в том, что:

  • DateTime не является обычным объектом Date
  • поля экземпляра скрыты и не предназначены для прямого сериализованного вывода
  • результат логирования часто теряет смысл без явного форматирования

Прямое логирование DateTime

При выводе объекта Luxon в консоль происходит отображение служебной структуры, а не человекочитаемого времени:

import { DateTime } from "luxon";

const dt = DateTime.now();

console.log(dt);

Результат зависит от среды выполнения и обычно не является стабильным для логирования или анализа.

Для получения стабильного представления используются методы преобразования.

Основные методы приведения к логируемому виду

ISO-формат

console.log(DateTime.now().toISO());

Метод toISO() формирует стандартную строку:

  • включает дату и время
  • сохраняет таймзону
  • подходит для хранения в логах и базах данных

Числовое представление времени

console.log(DateTime.now().toMillis());

Метод toMillis() возвращает UNIX-время в миллисекундах.

Используется в случаях:

  • сортировки событий
  • корреляции логов
  • высокочастотных систем

Альтернативой является:

DateTime.now().valueOf()

который возвращает тот же временной штамп.

Проблема JSON-сериализации Luxon объектов

При попытке сериализации объекта напрямую:

const dt = DateTime.now();

console.log(JSON.stringify({ time: dt }));

результатом становится:

{}

или потеря полезных данных.

Это связано с тем, что внутренние поля Luxon не перечисляемые.

Явное преобразование для логирования

Стратегия приведения к строке

const logEntry = {
  event: "user_login",
  time: DateTime.now().toISO()
};

console.log(JSON.stringify(logEntry));

Данный подход обеспечивает стабильность логов и их переносимость.

Использование toObject для структурного логирования

Luxon предоставляет метод toObject(), возвращающий разложенное представление времени:

const dt = DateTime.now().toObject();

console.log(dt);

Результат:

{
  year: 2026,
  month: 5,
  day: 24,
  hour: 12,
  minute: 30,
  second: 15,
  millisecond: 123
}

Такое представление полезно при:

  • аналитике временных данных
  • построении кастомных логов
  • интеграции с системами мониторинга

Логирование с учетом временной зоны

Одной из ключевых особенностей Luxon является поддержка таймзон.

import { DateTime } from "luxon";

const dt = DateTime.now().setZone("Europe/Paris");

console.log(dt.toISO());

Для логов важно фиксировать:

  • значение времени
  • таймзону
  • UTC-эквивалент

Пример структурированного объекта:

const logEntry = {
  event: "payment_received",
  timeLocal: dt.toISO(),
  timeUTC: dt.toUTC().toISO(),
  zone: dt.zoneName
};

Interval и Duration в логах

Duration

Объект Duration требует явного преобразования:

import { Duration } from "luxon";

const duration = Duration.fromObject({ minutes: 5 });

console.log(duration.toISO());

Результат:

PT5M

Для расширенного логирования:

console.log(duration.toObject());

Interval

import { DateTime, Interval } from "luxon";

const start = DateTime.now();
const end = start.plus({ hours: 2 });

const interval = Interval.fromDateTimes(start, end);

console.log(interval.toISO());

Результат:

2026-05-24T10:00:00.000Z/2026-05-24T12:00:00.000Z

Кастомная сериализация через JSON.stringify

Для систем логирования часто применяется кастомный replacer:

function luxonReplacer(key, value) {
  if (value?.toISO) {
    return value.toISO();
  }
  return value;
}

const logEntry = {
  event: "session_start",
  time: DateTime.now()
};

console.log(JSON.stringify(logEntry, luxonReplacer));

Такой подход обеспечивает:

  • автоматическое преобразование DateTime
  • сохранение читаемости логов
  • минимизацию ручной обработки

Интеграция со структурированным логированием

В системах вроде Pino или Winston Luxon-объекты требуют нормализации перед передачей в логгер.

Пример подготовки записи:

import { DateTime } from "luxon";

const createLog = (event, meta = {}) => ({
  event,
  time: DateTime.now().toISO(),
  meta
});

Использование:

logger.info(createLog("cache_miss", { key: "user:123" }));

Типичные ошибки при логировании Luxon объектов

Потеря времени при прямой сериализации

JSON.stringify({ time: DateTime.now() });

Результат не содержит полезного значения.

Смешивание форматов

Смешивание ISO, timestamp и объектов Luxon в одном логе приводит к:

  • усложнению парсинга
  • некорректной агрегации
  • ошибкам в мониторинге

Игнорирование таймзоны

Отсутствие явного указания зоны приводит к неоднозначности при распределенных системах.

Рекомендованные форматы хранения

Для логирования временных данных с Luxon используются три базовых формата:

  • ISO 8601 (toISO) — основной человекочитаемый формат
  • Unix timestamp (toMillis) — для вычислений
  • Object representation (toObject) — для аналитики

Комбинация этих форматов обеспечивает совместимость между системами хранения и обработки логов.