Bird
Raised Fist0
NestJSframework~10 mins

Logging with Winston or Pino in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Logging with Winston or Pino
Start Application
↓
Initialize Logger (Winston or Pino)
↓
Application Runs
↓
Log Event Occurs
↓
Logger Formats Message
↓
Logger Outputs to Console/File
↓
Continue Application or Exit
The app starts, sets up the logger, then logs messages during runtime, formatting and outputting them as configured.
Execution Sample
NestJS
import { Logger } from '@nestjs/common';
const logger = new Logger('App');
logger.log('App started');
logger.error('Error happened');
logger.warn('Warning issued');
This code creates a NestJS logger and logs messages of different levels.
Execution Table
StepActionLogger MethodMessageOutput FormatOutput Destination
1Initialize LoggerN/AN/ADefault NestJS formatConsole
2Log info messagelogApp started[LOG] [App] App startedConsole
3Log error messageerrorError happened[ERROR] [App] Error happenedConsole
4Log warning messagewarnWarning issued[WARN] [App] Warning issuedConsole
5Application continues runningN/AN/AN/AN/A
💡 Logging completes for these messages; application continues running.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
loggerundefinedLogger instance createdLogger instance usedLogger instance usedLogger instance used
Key Moments - 2 Insights
Why do different logger methods like log, error, and warn produce different output formats?
Each method corresponds to a log level that prefixes the message with its level (e.g., [LOG], [ERROR]), as shown in execution_table rows 2, 3, and 4.
Does the logger stop the application after logging an error?
No, logging an error only outputs the message; the application continues running as shown in step 5 of the execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the output format when logger.warn is called?
A[WARN] [App] Warning issued
B[ERROR] [App] Warning issued
C[INFO] [App] Warning issued
DWarning issued
💡 Hint
Check row 4 under Output Format in the execution_table.
At which step does the logger instance get created?
AStep 3
BStep 2
CStep 1
DStep 4
💡 Hint
Look at the Action column in the execution_table for initialization.
If you add a logger.debug('Debug info') call, what would change in the execution_table?
AThe existing rows would change their output format
BA new row with Logger Method 'debug' and output format '[DEBUG] [App] Debug info' would appear
CThe logger instance would be recreated
DNo change would happen
💡 Hint
Adding a new log call adds a new row with that method and message.
Concept Snapshot
NestJS logging uses Logger class.
Create logger with new Logger('Context').
Use methods: log(), error(), warn(), debug() for levels.
Messages show level and context.
Outputs go to console or files if configured.
Logging does not stop app execution.
Full Transcript
This visual execution shows how NestJS logging works with Winston or Pino. First, the application starts and initializes a logger instance. Then, during runtime, the logger logs messages at different levels: info, error, and warning. Each log method formats the message with a level prefix and context name. The output goes to the console by default. Logging messages do not stop the application from running. This trace helps beginners see how logging calls translate into formatted outputs step-by-step.

Practice

(1/5)
1.

What is the main purpose of using Winston or Pino in a NestJS application?

easy
A. To handle HTTP requests and responses
B. To log application events and errors for monitoring and debugging
C. To manage database connections efficiently
D. To compile TypeScript code into JavaScript

Solution

  1. Step 1: Understand logging role

    Logging tools like Winston or Pino record app events and errors to help developers monitor and debug the app.
  2. Step 2: Identify unrelated options

    Database management, HTTP handling, and code compilation are unrelated to logging.
  3. Final Answer:

    To log application events and errors for monitoring and debugging -> Option B
  4. Quick Check:

    Logging = Monitoring and debugging [OK]
Hint: Logging tools track app events and errors [OK]
Common Mistakes:
  • Confusing logging with database or HTTP handling
  • Thinking logging compiles code
  • Assuming logging manages app logic
2.

Which of the following is the correct way to import and use Logger from @nestjs/common for basic logging?

?
easy
A. import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started');
B. import Logger from 'nestjs'; const logger = Logger(); logger.log('App started');
C. const Logger = require('@nestjs/common'); const logger = new Logger(); logger.info('App started');
D. import { Logger } from 'winston'; const logger = new Logger(); logger.log('App started');

Solution

  1. Step 1: Check correct import syntax

    Correct import is from '@nestjs/common' using named import: import { Logger } from '@nestjs/common';
  2. Step 2: Verify usage

    Logger is instantiated with a context string, then log method is called. import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); matches this.
  3. Final Answer:

    import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); -> Option A
  4. Quick Check:

    Correct import and usage = import { Logger } from '@nestjs/common'; const logger = new Logger('App'); logger.log('App started'); [OK]
Hint: Use named import from '@nestjs/common' for Logger [OK]
Common Mistakes:
  • Using default import instead of named import
  • Calling wrong method like info instead of log
  • Importing Logger from wrong package
3.

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');
medium
A. {"level":30,"msg":"Server started"} followed by {"level":50,"msg":"Failed to connect"}
B. Plain text logs: 'Server started' and 'Failed to connect' without JSON
C. SyntaxError due to missing import from '@nestjs/common'
D. No output because logger is not instantiated correctly

Solution

  1. Step 1: Understand Pino output format

    Pino logs output JSON strings with level numbers (30=info, 50=error) and message keys.
  2. Step 2: Analyze code behavior

    Logger instance calls info and error methods, producing JSON logs with messages.
  3. Final Answer:

    {"level":30,"msg":"Server started"} followed by {"level":50,"msg":"Failed to connect"} -> Option A
  4. Quick Check:

    Pino logs JSON with level and msg [OK]
Hint: Pino logs JSON with level numbers and message keys [OK]
Common Mistakes:
  • Expecting plain text logs instead of JSON
  • Confusing Pino with NestJS Logger
  • Assuming no output due to import confusion
4.

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');
medium
A. Incorrect transport name; should be winston.Console instead of winston.transports.Console
B. Missing import of Logger from '@nestjs/common'
C. The logger instance does not have an error method directly; it returns a module, not a logger
D. Level 'info' is invalid for Console transport

Solution

  1. Step 1: Understand WinstonModule.forRoot return

    This method returns a NestJS module, not a direct logger instance with methods like error.
  2. Step 2: Identify correct usage

    To log, you must inject the logger service or use winston.createLogger directly, not call error on the module.
  3. Final Answer:

    The logger instance does not have an error method directly; it returns a module, not a logger -> Option C
  4. Quick Check:

    WinstonModule.forRoot returns module, not logger instance [OK]
Hint: WinstonModule.forRoot returns module, not logger instance [OK]
Common Mistakes:
  • Calling error method on module instead of logger instance
  • Confusing transport names
  • Assuming level 'info' is invalid
5.

You want to configure NestJS to use Pino for logging with JSON output and also log HTTP requests. Which setup is correct?

?
hard
A. import * as pino from 'pino'; const logger = pino({ prettyPrint: true }); logger.info('HTTP request logged');
B. import { WinstonModule } from 'nest-winston'; WinstonModule.forRoot({ transports: [new winston.transports.File({ filename: 'log.json' })] });
C. import { Logger } from '@nestjs/common'; const logger = new Logger(); logger.log('HTTP request logged');
D. import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } });

Solution

  1. Step 1: Identify Pino module usage in NestJS

    Use LoggerModule from 'nestjs-pino' with forRoot and pinoHttp config for HTTP logging and JSON output.
  2. 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.
  3. Final Answer:

    import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } }); -> Option D
  4. Quick Check:

    nestjs-pino with pinoHttp config = import { LoggerModule } from 'nestjs-pino'; LoggerModule.forRoot({ pinoHttp: { level: 'info' } }); [OK]
Hint: Use nestjs-pino LoggerModule with pinoHttp config for HTTP logs [OK]
Common Mistakes:
  • Using WinstonModule instead of nestjs-pino for Pino logging
  • Using Logger from '@nestjs/common' for HTTP logs
  • Using pino directly without NestJS integration
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard