typescriptbeginner
Structured JSON Logger
Build a structured logger with log levels, context, child loggers, and JSON output for Node.js services.
typescriptPress ⌘/Ctrl + Shift + C to copy
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
const LEVELS: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };
interface LogEntry {
level: LogLevel;
message: string;
timestamp: string;
[key: string]: unknown;
}
class Logger {
private context: Record<string, unknown>;
private minLevel: number;
constructor(
private level: LogLevel = 'info',
context: Record<string, unknown> = {},
) {
this.minLevel = LEVELS[level];
this.context = context;
}
private log(level: LogLevel, message: string, data?: Record<string, unknown>) {
if (LEVELS[level] < this.minLevel) return;
const entry: LogEntry = {
level,
message,
timestamp: new Date().toISOString(),
...this.context,
...data,
};
const output = JSON.stringify(entry);
if (level === 'error') console.error(output);
else if (level === 'warn') console.warn(output);
else console.log(output);
}
debug(message: string, data?: Record<string, unknown>) { this.log('debug', message, data); }
info(message: string, data?: Record<string, unknown>) { this.log('info', message, data); }
warn(message: string, data?: Record<string, unknown>) { this.log('warn', message, data); }
error(message: string, data?: Record<string, unknown>) { this.log('error', message, data); }
// Child logger inherits context
child(context: Record<string, unknown>): Logger {
return new Logger(this.level, { ...this.context, ...context });
}
// Timer utility
time(label: string) {
const start = performance.now();
return {
end: (data?: Record<string, unknown>) => {
const duration = Math.round(performance.now() - start);
this.info(`${label} completed`, { ...data, durationMs: duration });
},
};
}
}
// Usage
const logger = new Logger('debug', { service: 'api' });
logger.info('Server starting', { port: 3000 });
const reqLogger = logger.child({ requestId: 'req-123', method: 'GET', path: '/users' });
reqLogger.info('Request received');
const timer = reqLogger.time('db-query');
// ... do work
timer.end({ rows: 42 });
reqLogger.warn('Slow response', { latencyMs: 1500 });
reqLogger.error('Failed', { error: 'Connection refused' });Use Cases
- Application logging for production
- Request tracing with context
- Performance measurement
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalabeginner
Structured Logging Patterns
Implement structured logging in Scala: MDC context, log levels, JSON formatting, and async logging.
Best for: Application observability
#scala#logging
typescriptadvanced
Application Metrics Collection
Collect and expose application metrics like request counts, latency histograms, and custom gauges.
Best for: Prometheus metrics endpoint
#nodejs#monitoring
typescriptbeginner
Structured Request Logger Middleware
Express middleware that logs request/response details as structured JSON with timing information.
Best for: API monitoring
#express#logging
pythonintermediate
Structured Logging with structlog
Configure structlog for JSON-formatted structured logging with request context, timestamps, and log levels.
Best for: Application logging
#logging#structlog