Structured, type-safe logging for Node.js with pluggable adapters.
npm install @jterrazz/loggerimport { PinoLoggerAdapter } from '@jterrazz/logger';
const logger = new PinoLoggerAdapter({
level: 'debug',
prettyPrint: true,
});
logger.info('Server started', { port: 3000 });
logger.error('Request failed', { error: new Error('Connection timeout') });Create scoped loggers with persistent context:
const requestLogger = logger.child({ requestId: 'abc-123' });
requestLogger.info('Processing request'); // Includes requestId in every logProduction-ready logging powered by Pino.
import { PinoLoggerAdapter } from '@jterrazz/logger';
const logger = new PinoLoggerAdapter({
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
prettyPrint: true, // Human-readable output for development
destination: stream, // Optional custom destination stream
});Zero-overhead adapter for environments where logging should be disabled.
import { NoopLoggerAdapter } from '@jterrazz/logger';
const logger = new NoopLoggerAdapter();The optional meta object provides contextual information:
| Mode | Output |
|---|---|
prettyPrint: true |
Keys spread at root level for readability |
prettyPrint: false |
Nested under meta key for structured ingestion |
logger.info('User login', { userId: 42 });
// prettyPrint: true → { level: 'info', msg: 'User login', userId: 42 }
// prettyPrint: false → { level: 'info', msg: 'User login', meta: { userId: 42 } }Errors in meta.error are automatically serialized with message and stack properties.
Use LoggerPort for dependency injection:
import type { LoggerPort } from '@jterrazz/logger';
class UserService {
constructor(private readonly logger: LoggerPort) {}
createUser(name: string) {
this.logger.info('Creating user', { name });
}
}MIT