Logger is a built-in function of NestJS. See how to use and customize logger.
Enable/disable logger display
- When we create an app, we can configure logger by adding a second parameter to the create parameter
const app = await NestFactory.create(ApplicationModule, {
logger: false});await app.listen(3000);
Copy the code
Source:
public async create<T extends INestApplication = INestApplication>(
module: any, serverOrOptions? : AbstractHttpAdapter | NestApplicationOptions, options? : NestApplicationOptions, ):Promise<T> {}
Copy the code
- NestApplicationContextOptions NestApplicationOptions inheritance
export class NestApplicationContextOptions { logger? : LoggerService | LogLevel[] | boolean; }Copy the code
The logger levels:
- ‘log’
- ‘error’
- ‘warn’
- ‘debug’
- ‘verbose.
// Level type
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose';
// Configure logger hierarchy when creating app
const app = await NestFactory.create(ApplicationModule, {
logger: ['error'.'warn']});await app.listen(3000);
Copy the code
LoggerService interface
To implement custom Logger we must implement LoggerService
export interface LoggerService {
log(message: any, context? :string);
error(message: any, trace? :string, context? :string);
warn(message: any, context? :string); debug? (message:any, context? :string); verbose? (message:any, context? :string);
}
import { LoggerService } from '@nestjs/common';
export class MyLogger implements LoggerService {
log(message: string) {}
error(message: string, trace: string) {}
warn(message: string) {}
debug(message: string) {}
verbose(message: string){}}Copy the code
Extending existing Loggers
A logger that extends nestJS needs to inherit the NestJS logger interface, which in turn inherits the LoggerService interface
import { Logger } from '@nestjs/common';
export class MyLogger extends Logger {
error(message: string, trace: string) {
super.error(message, trace); }}Copy the code
The source code
@Injectable(a)export class Logger implements LoggerService {
private static logLevels: LogLevel[] = [
'log'.'error'.'warn'.'debug'.'verbose',];private staticlastTimestamp? :number;
private staticinstance? :typeof Logger | LoggerService = Logger;
constructor(
@Optional(a)protectedcontext? :string.@Optional(a)private readonly isTimestampEnabled = false.) {}
error(message: any, trace = ' ', context? :string) {}
log(message: any, context? :string) {}
warn(message: any, context? :string) {}
debug(message: any, context? :string) {}
verbose(message: any, context? :string) {}
setContext(context: string) {}
static overrideLogger(logger: LoggerService | LogLevel[] | boolean) {}
static log(message: any, context = ' ', isTimeDiffEnabled = true) {}
static error(
message: any,
trace = ' ',
context = ' ',
isTimeDiffEnabled = true.) {}
static warn(message: any, context = ' ', isTimeDiffEnabled = true) {}
static debug(message: any, context = ' ', isTimeDiffEnabled = true) {}
static verbose(message: any, context = ' ', isTimeDiffEnabled = true) {}
private callFunction(
name: 'log' | 'warn' | 'debug' | 'verbose',
message: any, context? :string.) {}
private getInstance(): typeof Logger | LoggerService {}
private isLogLevelEnabled(level: LogLevel): boolean {}
private static printMessage(
message: any,
color: (message: string) = >string,
context = ' ', isTimeDiffEnabled? :boolean.) {}
private staticupdateAndGetTimestampDiff( isTimeDiffEnabled? :boolean,
): string {}
private static printStackTrace(trace: string){}}Copy the code
The logger module
import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Module({
providers: [MyLogger],
exports: [MyLogger],
})
export class LoggerModule {}
Copy the code
Inject LoggerModule into AppModule and get MyLogger instance through app get method. The app also provides a useLogger to use the Logger.
const app = await NestFactory.create(ApplicationModule, {
// Close the system log
logger: false}); app.useLogger(app.get(MyLogger))await app.listen(3000);
Copy the code
This may seem like a bit of a hassle, but we can just create an instance and inject it without using Module.
const app = await NestFactory.create(ApplicationModule, {
// Close the system log
logger: false});// Use custom logs
app.useLogger(new MyLogger());
await app.listen(3000);
Copy the code
Injection scope is specified by passing the Scope property to the @Injectable() decorator option object
Scope is an enumeration type
export enum Scope {
/** * Providers can be shared between multiple classes. Provider life cycle * is strictly related to the application life cycle. Once an application has * bootstrap, all providers are instantiated. * /
DEFAULT,
/** * each use instantiates the provider's new private instance. * /
TRANSIENT,
/** * instantiate a new instance */ for each request processing pipe
REQUEST,
}
Copy the code
The scope option acts as configuration metadata for the Logger class and specifies a temporary range,
// To ensure that Logger has a unique instance in each function module
import { Injectable, Scope, Logger } from '@nestjs/common';
@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends Logger {}
import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Module({
providers: [MyLogger],
exports: [MyLogger],
})
export class LoggerModule {}
import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
constructor(private myLogger: MyLogger) {
this.myLogger.setContext('CatsService');
}
findAll(): Cat[] {
this.myLogger.warn('About to return cats! ');
return this.cats; }}const app = await NestFactory.create(ApplicationModule, {
logger: false}); app.useLogger(new MyLogger());
await app.listen(3000);
Copy the code
With scope injection, we can have a Logger instance in each Module by defining a separate Module. When used, we use MyLogger in the service. Finally, we need to call useLogger in our app to instantiate MyLogger.
The third party logger
Production applications often have specific logging requirements, including advanced filtering, formatting, and centralized logging. Nest’s built-in logger is used to monitor the behavior of the Nest system and can also be used during development for basic formatted text recording in function modules, but production applications typically leverage dedicated recording modules such as Winston. As with any standard Node.js application, you can take full advantage of such modules in Nest.