Logging helps you see what your app is doing. Winston and Pino are tools that make logging easy and organized.
Logging with Winston or Pino in NestJS
import { LoggerModule } from 'nestjs-pino'; @Module({ imports: [ LoggerModule.forRoot({ pinoHttp: { level: 'info', prettyPrint: true }, }), ], }) export class AppModule {}
Use LoggerModule.forRoot() to set up Pino logging in NestJS.
You can change level to control log detail (e.g., 'error', 'debug').
import { WinstonModule } from 'nest-winston'; import * as winston from 'winston'; @Module({ imports: [ WinstonModule.forRoot({ transports: [ new winston.transports.Console({ level: 'debug' }), ], }), ], }) export class AppModule {}
import { Logger } from '@nestjs/common'; const logger = new Logger('MyService'); logger.log('This is an info message'); logger.error('This is an error message');
import { LoggerModule } from 'nestjs-pino'; @Module({ imports: [ LoggerModule.forRoot({ pinoHttp: { level: 'error', redact: ['req.headers.authorization'], }, }), ], }) export class AppModule {}
This NestJS app uses Pino for logging. When you call the root URL, it logs an info message and returns 'Hello World!'.
import { Module, Injectable } from '@nestjs/common'; import { LoggerModule } from 'nestjs-pino'; import { Controller, Get } from '@nestjs/common'; import { Logger as PinoLogger } from 'nestjs-pino'; @Injectable() class AppService { constructor(private readonly logger: PinoLogger) {} getHello(): string { this.logger.info('Hello endpoint was called'); return 'Hello World!'; } } @Controller() class AppController { constructor(private readonly appService: AppService) {} @Get() getHello(): string { return this.appService.getHello(); } } @Module({ imports: [ LoggerModule.forRoot({ pinoHttp: { level: 'info', prettyPrint: true }, }), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
Winston is very flexible and supports many transports (console, files, remote servers).
Pino is very fast and produces JSON logs by default, good for machines to read.
Always avoid logging sensitive data like passwords or tokens.
Logging helps track app behavior and errors.
Winston and Pino are popular logging tools in NestJS.
Choose Winston for flexibility, Pino for speed and structured logs.
Practice
What is the main purpose of using Winston or Pino in a NestJS application?
Solution
Step 1: Understand logging role
Logging tools like Winston or Pino record app events and errors to help developers monitor and debug the app.Step 2: Identify unrelated options
Database management, HTTP handling, and code compilation are unrelated to logging.Final Answer:
To log application events and errors for monitoring and debugging -> Option BQuick Check:
Logging = Monitoring and debugging [OK]
- Confusing logging with database or HTTP handling
- Thinking logging compiles code
- Assuming logging manages app logic
Which of the following is the correct way to import and use Logger from @nestjs/common for basic logging?
?Solution
Step 1: Check correct import syntax
Correct import is from '@nestjs/common' using named import:import { Logger } from '@nestjs/common';Step 2: Verify usage
Logger is instantiated with a context string, thenlogmethod is called. import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); matches this.Final Answer:
import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); -> Option AQuick Check:
Correct import and usage = import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); [OK]
- Using default import instead of named import
- Calling wrong method like info instead of log
- Importing Logger from wrong package
Given this NestJS code using Pino logger, what will be the output in the console?
import { Logger } from 'nestjs-pino';
const logger = new Logger();
logger.info('Server started');
logger.error('Failed to connect');Solution
Step 1: Understand Pino output format
Pino logs output JSON strings with level numbers (30=info, 50=error) and message keys.Step 2: Analyze code behavior
Logger instance calls info and error methods, producing JSON logs with messages.Final Answer:
{"level":30,"msg":"Server started"} followed by {"level":50,"msg":"Failed to connect"} -> Option AQuick Check:
Pino logs JSON with level and msg [OK]
- Expecting plain text logs instead of JSON
- Confusing Pino with NestJS Logger
- Assuming no output due to import confusion
Identify the error in this NestJS Winston logger setup:
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
const logger = WinstonModule.forRoot({
transports: [
new winston.transports.Console({ level: 'info' })
]
});
logger.error('Error occurred');Solution
Step 1: Understand WinstonModule.forRoot return
This method returns a NestJS module, not a direct logger instance with methods like error.Step 2: Identify correct usage
To log, you must inject the logger service or use winston.createLogger directly, not call error on the module.Final Answer:
The logger instance does not have an error method directly; it returns a module, not a logger -> Option CQuick Check:
WinstonModule.forRoot returns module, not logger instance [OK]
- Calling error method on module instead of logger instance
- Confusing transport names
- Assuming level 'info' is invalid
You want to configure NestJS to use Pino for logging with JSON output and also log HTTP requests. Which setup is correct?
?Solution
Step 1: Identify Pino module usage in NestJS
Use LoggerModule from 'nestjs-pino' with forRoot and pinoHttp config for HTTP logging and JSON output.Step 2: Check options for JSON and pretty printing
import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } }); configures nestjs-pino LoggerModule with pinoHttp for HTTP request logging at info level, producing JSON output by default, matching requirements.Final Answer:
import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } }); -> Option DQuick Check:
nestjs-pino with pinoHttp config = import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } }); [OK]
- Using WinstonModule instead of nestjs-pino for Pino logging
- Using Logger from '@nestjs/common' for HTTP logs
- Using pino directly without NestJS integration
Ready to prove it?
Pass the test and this pattern moves unknown
