A logging interceptor helps you see what happens inside your app by recording requests and responses. It makes debugging and monitoring easier.
Logging interceptor in NestJS
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const request = context.switchToHttp().getRequest(); const method = request.method; const url = request.url; const now = Date.now(); return next .handle() .pipe( tap(() => console.log(`${method} ${url} took ${Date.now() - now}ms`)), ); } }
The intercept method runs before and after the request handler.
Use context.switchToHttp().getRequest() to access request details.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const req = context.switchToHttp().getRequest(); console.log(`Incoming request: ${req.method} ${req.url}`); return next.handle(); } }
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const now = Date.now(); return next.handle().pipe( tap(() => console.log(`Request processed in ${Date.now() - now}ms`)), ); } }
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const req = context.switchToHttp().getRequest(); const method = req.method; const url = req.url; const now = Date.now(); return next.handle().pipe( tap(() => console.log(`${method} ${url} took ${Date.now() - now}ms`)), ); } }
This is a complete logging interceptor that logs the HTTP method, URL, and how long the request took to process.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const req = context.switchToHttp().getRequest(); const method = req.method; const url = req.url; const now = Date.now(); return next.handle().pipe( tap(() => console.log(`${method} ${url} took ${Date.now() - now}ms`)), ); } }
Make sure to register the interceptor globally or in the controller to activate it.
Logging too much data can slow down your app, so log only what you need.
You can customize the interceptor to log request body, headers, or response data if needed.
Logging interceptors help track requests and responses easily.
They run code before and after your request handlers.
Use them to measure request time and log useful info for debugging.
Practice
LoggingInterceptor in a NestJS application?Solution
Step 1: Understand the role of interceptors
Interceptors in NestJS run code before and after request handlers, often used for logging or modifying requests/responses.Step 2: Identify the purpose of LoggingInterceptor
A LoggingInterceptor specifically tracks and logs request and response details for debugging and monitoring.Final Answer:
To log details about incoming requests and outgoing responses -> Option CQuick Check:
LoggingInterceptor = logs requests/responses [OK]
- Confusing interceptors with middleware
- Thinking interceptors handle authentication
- Assuming interceptors serve static files
intercept method in a NestJS LoggingInterceptor?Solution
Step 1: Recall the intercept method signature
The intercept method receives two parameters:contextandnext. It must returnnext.handle()to continue the request lifecycle.Step 2: Check each option for correct syntax
intercept(context, next) { return next.handle(); } correctly uses both parameters and returnsnext.handle(). Options A, C, and D either miss parameters or do not return the observable.Final Answer:
intercept(context, next) { return next.handle(); } -> Option AQuick Check:
intercept(context, next) returns next.handle() [OK]
- Omitting return statement
- Missing one of the parameters
- Calling handle on wrong object
intercept(context, next) {
const now = Date.now();
return next.handle().pipe(
tap(() => console.log(`Request took ${Date.now() - now}ms`))
);
}Solution
Step 1: Analyze the timing logic
The code records the current time before the request is handled, then logs the difference after the response is sent.Step 2: Understand the logged message
The console.log outputs "Request took Xms" where X is the elapsed time in milliseconds.Final Answer:
Logs the time taken to process the request in milliseconds -> Option AQuick Check:
LoggingInterceptor measures request duration [OK]
- Assuming it logs request URL or body
- Thinking it logs errors only
- Ignoring the timing calculation
intercept(context, next) {
const now = Date.now();
next.handle().pipe(
tap(() => console.log(`Request took ${Date.now() - now}ms`))
);
}Solution
Step 1: Check the intercept method return
The intercept method must return the observable fromnext.handle()to continue the request lifecycle.Step 2: Identify missing return
The code callsnext.handle().pipe(...)but does not return it, so the request will not proceed properly.Final Answer:
Missing return statement before next.handle() -> Option DQuick Check:
intercept must return next.handle() observable [OK]
- Forgetting to return the observable
- Misusing Date.now() for timing
- Ignoring required parameters
Solution
Step 1: Access request object correctly
Usecontext.switchToHttp().getRequest()to get the HTTP request object in NestJS interceptors.Step 2: Use tap operator for side effects
Thetapoperator is used to perform logging without altering the response stream. Usingmaporconsole.erroris incorrect here.Final Answer:
intercept(context, next) { const req = context.switchToHttp().getRequest(); const now = Date.now(); return next.handle().pipe( tap(() => console.log(`${req.method} ${req.url} - ${Date.now() - now}ms`)) ); } -> Option BQuick Check:
Use switchToHttp(), tap, and return next.handle() [OK]
- Not returning next.handle()
- Using map instead of tap
- Using console.error instead of console.log
- Incorrect request object access
Ready to prove it?
Pass the test and this pattern moves unknown
