Package Exports
- @arv-bedrock/logger
Readme
NestJS Trace Logger
A lightweight request tracing and logging middleware for NestJS microservices with beautiful colored console output using Winston.
Features
- Simple middleware-based setup
- Request tracing with unique IDs
- Colored console output using Winston
- Automatic request/response logging
- Error tracking with stack traces
- Performance monitoring
- Structured JSON logging
- Loki-compatible output format
Installation
npm install @your-org/nest-trace-logger
Usage
Add the middleware in your main.ts
:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TraceLoggerMiddleware } from '@your-org/nest-trace-logger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Initialize with custom configuration
const logger = TraceLoggerMiddleware.getInstance({
serviceName: 'your-service-name',
level: 'info',
timestampFormat: 'YYYY-MM-DD HH:mm:ss'
});
// Use as global middleware
app.use(logger.use.bind(logger));
// Use logger directly for application logs
logger.info('Application starting');
await app.listen(3000);
}
bootstrap();
Usage with NestJS
- Configure the middleware in your
AppModule
:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { TraceLoggerMiddleware } from '@your-org/nest-trace-logger';
@Module({
imports: [],
controllers: [],
providers: [],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
// Configure the logger
TraceLoggerMiddleware.configure({
serviceName: 'your-service-name',
level: 'info',
timestampFormat: 'YYYY-MM-DD HH:mm:ss'
});
// Apply the middleware to all routes
consumer
.apply(TraceLoggerMiddleware)
.forRoutes('*');
}
}
- To use the logger in your services or controllers:
import { Injectable } from '@nestjs/common';
import { TraceLoggerMiddleware } from '@your-org/nest-trace-logger';
@Injectable()
export class YourService {
private logger = TraceLoggerMiddleware.getInstance();
async someMethod() {
this.logger.info('Custom log message', {
customField: 'value'
});
}
}
Microservice Support
This library supports distributed tracing across microservices. Here's how to use it:
HTTP Module Example
// app.module.ts
import { Module } from '@nestjs/common';
import { HttpModule } from '@nestjs/axios';
import { TraceLoggerMiddleware } from '@your-org/nest-trace-logger';
@Module({
imports: [
HttpModule.registerAsync({
useFactory: () => ({
// Add trace ID to outgoing requests
baseURL: 'http://other-service',
headers: {
[TraceLoggerMiddleware.TRACE_ID_HEADER]: TraceLoggerMiddleware.getCurrentTraceId()
}
})
})
]
})
export class AppModule {}
// users.service.ts
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { TraceLoggerMiddleware } from '@your-org/nest-trace-logger';
@Injectable()
export class UsersService {
private readonly logger = TraceLoggerMiddleware.getInstance({
serviceName: 'users-service'
});
constructor(private readonly httpService: HttpService) {}
async getOrders(userId: string) {
try {
// Trace ID will be automatically propagated
const response = await firstValueFrom(
this.httpService.get(`/orders/${userId}`)
);
return response.data;
} catch (error) {
this.logger.error('Failed to fetch orders', {
userId,
targetService: 'orders-service',
error
});
throw error;
}
}
}
Key Features for Microservices
- Automatic Trace ID Propagation: Trace IDs are automatically passed between services via headers
- Service Attribution: Logs include source and target service names
- Distributed Tracing: Track requests across multiple services
- Error Handling: Captures errors with service context
Headers
The following headers are used for tracing:
x-trace-id
: Unique identifier for the request chainx-source-service
: Name of the calling service
Configuration
The middleware accepts these configuration options:
interface LoggerConfig {
serviceName?: string; // Default: process.env.SERVICE_NAME || 'unknown-service'
level?: string; // Default: 'info'
timestampFormat?: string; // Default: 'YYYY-MM-DD HH:mm:ss'
}
Log Format
All logs are output with color-coded levels and structured data:
2025-02-11 20:42:18 [your-service-name] INFO: Incoming request
{
"traceId": "123e4567-e89b-12d3-a456-426614174000",
"path": "/api/users",
"method": "GET",
"params": {},
"query": {"page": "1"},
"headers": {
"user-agent": "curl/7.64.1"
}
}
Request Tracing
The middleware automatically:
- Generates a unique trace ID for each request
- Adds the trace ID to response headers (
x-trace-id
) - Makes trace ID available in request object (
req.traceId
) - Includes trace ID in all log entries
Log Types
Request Logs:
{ traceId: string; path: string; method: string; params: object; query: object; body: object; headers: object; }
Response Logs:
{ traceId: string; path: string; method: string; statusCode: number; duration: number; }
Error Logs:
{ traceId: string; path: string; method: string; statusCode: number; duration: number; error: { message: string; stack: string; code: string | number; status: number; } }
Direct Logger Usage
You can use the logger directly for custom logging:
const logger = TraceLoggerMiddleware.getInstance();
// Info level
logger.info('Processing payment', {
traceId: '123',
userId: '456',
amount: 100
});
// Error level
logger.error('Payment failed', {
traceId: '123',
error: new Error('Insufficient funds')
});
// Warning level
logger.warn('High CPU usage', {
usage: '85%'
});
// Debug level
logger.debug('Cache miss', {
key: 'user:123'
});
Best Practices
Set a meaningful service name:
const logger = TraceLoggerMiddleware.getInstance({ serviceName: 'payment-service' });
Use environment variables:
export SERVICE_NAME=payment-service
Include trace IDs in custom logs:
logger.info('Custom event', { traceId: req.traceId });
Set appropriate log levels:
const logger = TraceLoggerMiddleware.getInstance({ level: process.env.NODE_ENV === 'production' ? 'info' : 'debug' });