Implementing Advanced Logging in NestJS with Pino
Pino Logging Integration
Pino is a high-performance logging library that can be seamlessly integrated into NestJS applications. For implementation details, visit:
To begin, install the NestJS Pino adapter:
npm install nestjs-pino
Module Configuration
Register the LoggerModule in your application's root module:
import { LoggerModule } from 'nestjs-pino';
@Module({
controllers: [AppController],
imports: [LoggerModule.forRoot()]
})
export class AppModule {}
Controller Implementation
Inject the Logger service into your controllers:
import { Controller, Logger } from 'nestjs-pino';
@Controller('user')
export class UserController {
private readonly applicationLogger: Logger;
constructor() {
// The logger automatically handles request/response cycles
// No need for manual initialization calls
}
}
Note that Pino operates automatically without requiring manual log calls for basic functionality. However, the default output format may not be optimal for readability in development environments.
Enhancing Pino Output Readability
To improve log readability, install additional formatting and rolling file plugins:
npm install pino-pretty pino-roll
Environment-Specific Configuration
Configure different logging behaviors for development and production environments:
import { LoggerModule } from 'nestjs-pino';
import { join } from 'path';
const isDevelopment = process.env.NODE_ENV === 'development';
@Module({
imports: [
LoggerModule.forRoot({
pinoHttp: {
transport: isDevelopment ? {
target: 'pino-pretty',
level: 'info',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
}
} : {
target: 'pino-roll',
level: 'info',
options: {
file: join('logs', 'application.log'),
frequency: 'daily',
size: '10m',
mkdir: true
}
}
}
})
]
})
export class AppModule {}
Advanced Multi-Target Configuration
Pino supports outputting to multiple targets simultaneously. This configuration allows logs to be displayed in the console during development and written to files in production:
LoggerModule.forRoot({
pinoHttp: {
transport: {
targets: [
{
level: 'info',
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
}
},
{
target: 'pino-roll',
level: 'info',
options: {
file: join('logs', 'application.log'),
frequency: 'daily',
size: '10m',
mkdir: true
}
}
]
}
}
})
Conditional targets can also be implemented based on environment variables:
LoggerModule.forRoot({
pinoHttp: {
transport: {
targets: [
isDevelopment ? {
level: 'debug',
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
}
} : {
target: 'pino-roll',
level: 'info',
options: {
file: join('logs', 'application.log'),
frequency: 'daily',
size: '10m',
mkdir: true
}
}
]
}
}
})