Implementing logging services in NestJS can be achieved through various methods, with the most common approach being the use of NestJS's built-in Logger service or integrating third-party logging libraries such as Winston or Pino. Below are the basic steps for using the built-in Logger service in NestJS and integrating Winston as the logging service.
Using NestJS's Built-in Logger Service
- Import the Logger Service: NestJS offers a built-in
Loggerclass that can be directly utilized within services or controllers.
typescriptimport { Logger } from '@nestjs/common';
- Instantiate the Logger: Create a Logger instance within your service or controller.
typescriptprivate readonly logger = new Logger(MyService.name);
- Use the Logger: Now you can use this logger to record log messages in any method of the class.
typescriptsomeMethod() { this.logger.log('Some informative message'); this.logger.error('An error occurred', error.stack); this.logger.warn('A warning message'); this.logger.debug('Some debug information'); }
- Customize the Logger: To change log levels or customize logging behavior, extend the
Loggerclass and override its methods.
typescriptimport { Logger, Injectable, Scope } from '@nestjs/common'; @Injectable({ scope: Scope.TRANSIENT }) class MyLogger extends Logger { // Custom logging logic }
Integrating Third-Party Logging Libraries (Using Winston as an Example)
- Install Winston-related Dependencies:
shnpm install winston @nestjs/common @nestjs/core
- Create a Winston Module: Create a module to encapsulate Winston's configuration and providers.
typescriptimport { Module } from '@nestjs/common'; import { WinstonModule } from 'nest-winston'; import * as winston from 'winston'; @Module({ imports: [ WinstonModule.forRoot({ // Winston configuration transports: [ new winston.transports.Console(), // Other transports like file or remote logging services ], }), ], exports: [WinstonModule], }) export class LoggerModule {}
- Use Winston in the Application: Import
LoggerModulein other modules and injectWINSTON_MODULE_PROVIDERas the logger.
typescriptimport { Inject, Injectable } from '@nestjs/common'; import { Logger } from 'winston'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; @Injectable() class MyService { constructor( @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger ) {} someMethod() { this.logger.info('Some informative message'); this.logger.error('An error occurred'); } }
Using Custom Log Levels and Formats
NestJS's built-in logger or third-party logging libraries allow you to define custom log levels and formats. This can be achieved by modifying the configuration; for example, when using Winston, customize the transports and format options to alter the output format and destination of logs.
typescripttransports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`) ), }), // Other transports ]
In production environments, you may also need to consider advanced features such as persistent log storage, log analysis, and monitoring alerts, which typically require integration with relevant infrastructure and services, such as the ELK stack (Elasticsearch, Logstash, Kibana), AWS CloudWatch, and GCP Stackdriver.
The above are some basic steps and practices for using logging services in NestJS, of course depending on specific business requirements and system context.