@philiprehberger/logger
v0.4.0
Published
Structured JSON logger with child loggers, redaction, and pretty dev output
Readme
@philiprehberger/logger
Structured JSON logger with child loggers, redaction, and pretty dev output
Installation
npm install @philiprehberger/loggerUsage
Basic
import { createLogger } from '@philiprehberger/logger';
const logger = createLogger({ name: 'api', level: 'info' });
logger.info('Server started', { port: 3000 });
// {"level":"info","name":"api","msg":"Server started","port":3000,"ts":"2026-03-09T..."}
logger.error('Request failed', { status: 500, path: '/api/users' });Log Levels
trace → debug → info → warn → error → fatal → silent
Messages below the configured level are silently dropped. Use silent to disable all output (useful in tests)
Child Loggers
const reqLogger = logger.child({ requestId: 'abc-123' });
reqLogger.info('Processing request');
// {"level":"info","name":"api","msg":"Processing request","requestId":"abc-123","ts":"..."}
const dbLogger = reqLogger.child({ service: 'database' });
// Inherits requestId + adds serviceAuto-Redaction
Sensitive fields are automatically masked:
logger.info('Auth', { token: 'secret123', user: 'alice' });
// {"level":"info","name":"api","msg":"Auth","token":"[REDACTED]","user":"alice","ts":"..."}Default redacted patterns: password, token, secret, authorization, cookie, key, credential, api_key, access_token, refresh_token, private_key.
Custom patterns:
const logger = createLogger({
name: 'app',
redact: ['ssn', 'credit_card', 'password'],
});Arrays are redacted recursively:
logger.info('Users', { users: [{ name: 'alice', token: 'abc' }] });
// token is redacted inside the array elementCircular references are handled safely:
const obj: any = { name: 'test' };
obj.self = obj;
logger.info('Circular', obj);
// self becomes "[Circular]"Disable redaction:
const logger = createLogger({ name: 'app', redact: false });Pretty Mode
Auto-detected in development (NODE_ENV=development), or set manually:
const logger = createLogger({ name: 'app', pretty: true });
// INFO [app] Server started {"port":3000}Runtime Level Changes
const logger = createLogger({ name: 'app', level: 'info' });
logger.debug('hidden'); // dropped
logger.setLevel('debug');
logger.debug('now visible'); // logged
// Child loggers inherit the parent's level unless they set their own
const child = logger.child({ req: '123' });
logger.setLevel('error'); // child also uses 'error' now
child.setLevel('debug'); // child overrides to 'debug'Sampling
Reduce log volume in noisy environments by emitting only a fraction of calls. A gated call returns without writing.
Single global rate (between 0 and 1):
import { createLogger } from '@philiprehberger/logger';
// Keep ~10% of all log calls
const logger = createLogger({ name: 'app', sampling: 0.1 });
logger.info('hello'); // ~90% of the time this is droppedPer-level rates:
import { createLogger } from '@philiprehberger/logger';
const logger = createLogger({
name: 'app',
sampling: {
trace: 0.01, // 1% of trace
debug: 0.1, // 10% of debug
info: 1, // all info (any unspecified level defaults to 1)
warn: 1,
error: 1,
fatal: 1,
},
});Default is 1 (no sampling). Child loggers inherit the parent's sampling config:
const logger = createLogger({ name: 'app', sampling: 0.5 });
const reqLogger = logger.child({ requestId: 'abc' });
// reqLogger also samples at 50%Environment Variables
LOG_LEVEL— sets the log level (overrides constructor option, case-insensitive)NODE_ENV=development— enables pretty mode by default
Custom Colors
import { consoleTransport } from '@philiprehberger/logger';
const transport = consoleTransport({
pretty: true,
colors: { error: '\x1b[41m', info: '\x1b[36m' },
});API
| Export | Type | Description |
|--------|------|-------------|
| createLogger(options) | Function | Create a logger instance with structured JSON output |
| consoleTransport(options?) | Function | Create a console transport (default); supports pretty mode and custom colors |
| createRedactor(patterns) | Function | Create a custom redaction function for sensitive fields |
| LOG_LEVELS | Object | Level name to numeric priority mapping |
Logger Instance Methods
| Method | Description |
|--------|-------------|
| trace(msg, data?) | Log at trace level |
| debug(msg, data?) | Log at debug level |
| info(msg, data?) | Log at info level |
| warn(msg, data?) | Log at warn level |
| error(msg, data?) | Log at error level |
| fatal(msg, data?) | Log at fatal level |
| child(bindings) | Create a child logger with inherited context |
| setLevel(level) | Change log level at runtime |
LoggerOptions
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| name | string | required | Logger name attached to every entry |
| level | LogLevel | 'info' | Minimum level to emit (or LOG_LEVEL env var) |
| pretty | boolean | NODE_ENV==='development' | Pretty-print human-readable output |
| redact | string[] \| boolean | true | Field patterns to redact, false to disable, true for defaults |
| transports | Transport[] | [consoleTransport(pretty)] | Custom output sinks |
| sampling | number \| Record<LogLevel, number> | 1 | Sample rate (0–1) globally or per level |
Types
| Type | Description |
|------|-------------|
| Logger | Logger instance interface |
| LoggerOptions | Options accepted by createLogger |
| LogLevel | 'trace' \| 'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal' \| 'silent' |
| LogEntry | Shape of a structured log entry |
| Transport | Transport function signature |
| SamplingRate | number or per-level { trace?, debug?, info?, warn?, error?, fatal? } map |
| ConsoleTransportOptions | Options for consoleTransport |
Development
npm install
npm run build
npm testSupport
If you find this project useful:
