@swarmmachina/swm-logs v0.1.1

swm-logs

Структурированный JSON-логгер

Структурированный JSON-логгер для Node.js без runtime-зависимостей. Каждый вызов записывает одну NDJSON-строку в stdout, stderr, файловый дескриптор, writable destination или lifecycle-aware transport.

Выбирайте swm-logs, если нужны стабильный формат событий, совместимые с pino уровни, безопасная сериализация и редакция секретов, дешёвые дочерние логгеры и явное управление доставкой без встроенных сетевых клиентов.

ПриложениеLoggerNDJSONDestination / transport
0
runtime-зависимостей
22 / 24
Node.js
NDJSON
формат вывода
ESM
package surface

Установка и быстрый старт

Shellinstall
npm install @swarmmachina/swm-logs
JavaScriptquick-start.js
import Logger from '@swarmmachina/swm-logs'

const logger = new Logger({
  bindings: { service: 'gateway' },
  redact: ['req.headers.authorization']
})

const requestLogger = logger.child({ requestId: 'r1' })

requestLogger.info({ port: 3000 }, 'listening')
requestLogger.error(new Error('request failed'))

await logger.close()
  • По умолчанию logger пишет в stdout немедленно и не создаёт собственную очередь.
  • Каждая запись содержит numeric level и epoch-millisecond time и завершается ровно одним переводом строки.
  • Поля приложения level и time игнорируются; msg используется как сообщение, только если отдельный аргумент message не передан.
  • Нативный ESM является единственной поддерживаемой package surface; CommonJS require() не поддерживается.
  • Пакет имеет экспериментальный статус. Зафиксируйте версию и проверяйте release notes перед обновлением.

Что предоставляет логгер

Стабильный NDJSON envelope
Numeric level, epoch-millisecond time, optional msg, предварительно сериализованные bindings и поля вызова.
Дешёвые child loggers
child() сериализует bindings один раз и делит уровни, output state и delivery counters с root logger.
Конечная сериализация
Circular references, BigInt, Error.cause и ограничение depth/edge обрабатываются без бесконечного обхода.
Скомпилированная редакция
Точные, wildcard, dot и bracket paths с заменой значения или удалением поля без мутации входных данных.
Расширения по запросу
Keyed serializers, before/after hooks, formatter, transports и обратимый ConsoleBridge включаются явно.
Явная доставка
Immediate output по умолчанию, ограниченная opt-in буферизация, flushSync для crash path и async close для transport owners.
Наблюдаемые потери
Ошибки destination изолируются, а deliveryStats() и onDestinationError сообщают количество ошибок и потерянных данных.

Runtime и направления доставки

СредаСтатусПримечание
Node.js 22 / 24ПоддерживаетсяДругие major-версии отклоняются engines constraint.
Native ESMПоддерживаетсяDefault и named Logger exports с TypeScript declarations.
CommonJS require()Не поддерживаетсяИспользуйте import в ESM-приложении.
Runtime-зависимости0Сетевые клиенты, rotation и vendor exporters не входят в пакет.
stdout / stderr / fd / writableПоддерживаетсяВыбирается через destination; immediate output включён по умолчанию.
Пользовательские transportsПоддерживаетсяTransport владеет очередью, retry, backpressure, persistence и метриками.
Встроенные сетевые transportsНе поставляютсяHTTP, БД и vendor delivery остаются в приложении.

Карта API

Log methods

Одинаковые call shapes для встроенных и пользовательских уровней.

trace()debug()info()warn()error()fatal()log(level, ...args)isLevelEnabled(level)

Logger context

Порог, дочерние bindings и снимок эффективного контекста.

levelchild(bindings, options)bindings()

Delivery lifecycle

Операции общего output state root logger и его children.

flush()flushSync()close()deliveryStats()

Configuration

Уровни, сериализация, редакция, расширения и направления вывода.

customLevelsserializersredacthooksformatterbufferingdestinationtransports

Exports

Основной класс, уровни, console bridge и TypeScript contracts.

LoggerNamedLoggerConsoleBridgeLEVELSLoggerOptionsLogTransportDeliveryStats

Полные сигнатуры, типы и примеры находятся в README и TypeScript declarations исходного репозитория.

Доставка, backpressure и shutdown

Логгер разделяет форматирование события и владение доставкой. Приложение должно явно выбрать границы памяти, durability и момент закрытия root logger.

Immediate mode не ограничивает stream queue

Если process.stdout.write() возвращает false, pending bytes принадлежат Node.js stream, а логирование продолжается. Для строгого лимита используйте transport с ограниченной очередью.

Transport владеет политикой

write(line, level) должен быстро принять запись. Очередь, batching, retry, overflow, persistence, timeout и asynchronous failure metrics принадлежат реализации transport.

Закрывайте root один раз

Child loggers делят lifecycle с root. Сначала остановите приём работы, дождитесь in-flight операций, затем вызовите await rootLogger.close().

Crash path остаётся синхронным

Для fatal exception вызовите flushSync(). Гарантированная durability требует regular file или numeric descriptor; generic writer подтверждает её самостоятельно.

Буфер имеет явную границу

buffering по умолчанию использует 64 КиБ, 1000 мс и flushLevel warn. Один oversized record может временно превысить maxBytes; после попытки записи буфер сбрасывается.

Ошибки доставки изолированы

Destination и synchronous transport failures не выходят из log method. Экспортируйте onDestinationError и deliveryStats() в отдельный канал наблюдаемости.

Редактируйте до доставки

Используйте точные redact paths для известных схем и wildcard только там, где структура действительно динамическая. Caller-owned данные не мутируются.

Миграция с pino

Числовые уровни совместимы с pino, но surface намеренно меньше: base становится bindings, custom levels вызываются через log(), а workers, pretty printing и vendor transports не включены.

JavaScriptlogger.js
// pino
const previous = pino({ level: 'info', base: { service: 'gateway' } })

// swm-logs
const logger = new Logger({
  level: 'info',
  bindings: { service: 'gateway' }
})
Нужен HTTP/WebSocket-сервер с явными лимитами и graceful shutdown?Открыть swm-core