Logger
@voltage/logger replaces the default NestJS logger with a Winston-backed implementation. It assigns a correlation ID to every HTTP request and propagates it automatically through async context, so all logs within a request are traceable without any manual wiring.
Installation
Section titled “Installation”yarn add @voltage/logger @voltage/async-context @voltage/event-manager @voltage/zod zodBasic usage
Section titled “Basic usage”register()
Section titled “register()”Import LoggerModule once in your root application module. Because it is registered as global, you do not need to import it in feature modules.
import { LoggerModule } from '@voltage/logger';
@Module({ imports: [ LoggerModule.register({ level: 'info', application: 'my-app', }), ],})export class AppModule {}registerAsync()
Section titled “registerAsync()”Use a factory to pull configuration from an injected provider — the typical approach when using a configuration class:
LoggerModule.registerAsync({ inject: [AppConfiguration], useFactory: (configuration: AppConfiguration) => ({ ...configuration.logger, application: 'my-app', }),})Inject Logger into any service:
import { Injectable } from '@nestjs/common';import { Logger } from '@voltage/logger';
@Injectable()export class OrderService { constructor(private readonly logger: Logger) {}
async create(order: Order) { void this.logger.push('info', 'order.create', { type: 'order.create', order: { id: order.id }, }); }}In main.ts, connect LoggerFacade as the NestJS application logger so framework-internal logs (bootstrapping, route registration) also go through Winston:
import { LoggerFacade } from '@voltage/logger';
const app = await NestFactory.create(AppModule);app.useLogger(app.get(LoggerFacade));app.flushLogs();Log levels
Section titled “Log levels”Levels in order from most to least verbose: verbose, debug, info, warn, error, fatal.
You can change the active level at runtime:
this.logger.setLevel('warn');Metadata conventions
Section titled “Metadata conventions”Pass a metadata object as the third argument to push(). Use type as a dot-namespaced identifier for the event, and group contextual data under a named key matching the domain:
void this.logger.push('debug', 'Processing export', { type: 'exporter.write', exporter: { path, writeCount: results.length, },});Pass an error key to attach exception information. The logger normalizes the error to message and stack only:
void this.logger.push('error', 'Export failed', { type: 'exporter.write', error, exporter: { path },});HTTP request logging
Section titled “HTTP request logging”LoggerModule registers middleware on all routes automatically. For every request it:
- Assigns a UUID v7 correlation ID and attaches it to
req.correlationId - Emits an
http.beginlog with request metadata (method, URL, IP, headers) - Emits an
http.endlog on response with status code, matched route, and duration
You do not need to configure this — it is active as soon as you import the module.
Console output format
Section titled “Console output format”[MM-DD-YYYY HH:mm:ss][CORRELATION_ID][LEVEL][+DELTA_MS] message+DELTA_MS is the time elapsed since the previous log within the same request, useful for spotting slow steps without external tooling.
Additional transports
Section titled “Additional transports”Pass any Winston-compatible transport via the transports option. Additional transports receive all metadata as JSON, independent of the logMetadata console setting:
import { transports } from 'winston';
LoggerModule.register({ level: 'info', application: 'my-app', transports: [ new transports.File({ filename: 'app.log' }), ],})Configuration
Section titled “Configuration”interface LoggerConfiguration { /** Minimum log level */ level: 'verbose' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' /** Application name included in every log entry */ application: string /** Additional Winston transports appended to the default console transport */ transports?: Transport[] /** Metadata inspection depth in console output. true for full depth, a number for a specific limit */ logMetadata?: boolean | number}