Logger
Structured logging configuration
Better-Notify logs internally through a structural LoggerLike interface. Every createClient instance accepts an optional logger — if omitted, it defaults to consoleLogger({ level: 'warn' }), which stays silent on success and surfaces errors.
import { createClient, consoleLogger } from '@betternotify/core';
const mail = createClient({
catalog,
transportsByChannel: { email: transport },
logger: consoleLogger({ level: 'debug' }),
});The LoggerLike interface
Any object that implements these methods works as a logger — no base class or dependency required:
Prop
Type
consoleLogger
The built-in logger. Outputs colored, human-readable lines with timestamps, level tags, and structured payload formatting. Errors under the err key get special treatment — stack traces are indented and cause chains are rendered recursively.
import { consoleLogger } from '@betternotify/core';
const logger = consoleLogger({ level: 'info' });Prop
Type
Pino integration
If you use pino, wrap it with fromPino — it adapts pino's (obj, msg) signature to Better-Notify's (msg, obj) convention:
import pino from 'pino';
import { fromPino } from '@betternotify/core/logger';
const logger = fromPino(pino({ level: 'info' }));
const mail = createClient({
catalog,
transportsByChannel: { email: transport },
logger,
});fromPino also forwards child() calls, so per-send bindings (route, messageId, component) flow through to pino child loggers.
Bring your own logger
Any object matching LoggerLike works — Winston, Bunyan, or a custom wrapper:
import type { LoggerLike } from '@betternotify/core';
const customLogger: LoggerLike = {
debug: (msg, payload) => myLogger.log('debug', msg, payload),
info: (msg, payload) => myLogger.log('info', msg, payload),
warn: (msg, payload) => myLogger.log('warn', msg, payload),
error: (msg, payload) => myLogger.log('error', msg, payload),
child: (bindings) => customLogger,
};Error key convention
Errors are always passed under the err key in payloads — this matches pino's stdSerializers.err convention. The console logger serializes err values with type, message, code, stack, and nested causes. If you're building a custom logger, handle the err key to get structured error output.