NestJS에서 기본 Logger는 로그의 수준별 관리와 특정 상황에서만 기록되도록 설정할 수 있는 강력한 기능을 제공합니다.
이와 관련해 기본 Logger 사용법과 커스텀 방법, 그리고 외부 라이브러리인 Winston을 활용하는 방법까지 순서대로 포스팅 할려고합니다.
NestJS의 Logger 클래스는 애플리케이션 로그를 기록하는데 사용되는 내장 로깅 기능을 제공합니다.
기본적으로 로그의 수준별로 관리가 가능하며, log, error, warn, debug, verbose 메서드를 제공하여 필요에 따라 다른 수준의 로그를 기록할 수 있습니다.
import { Logger } from '@nestjs/common';
export class AppService {
private readonly logger = new Logger(AppService.name);
someMethod() {
this.logger.log('This is a log message');
this.logger.error('This is an error message');
this.logger.warn('This is a warning message');
this.logger.debug('This is a debug message');
this.logger.verbose('This is a verbose message');
}
}
환경에 따라 로그 레벨을 설정할 수 있으며, 프로덕션 환경에서는 log와 error 레벨만 사용하고, 개발 환경에서는 모든 레벨을 사용하는 식으로 관리할 수 있습니다.
NestJS는 로깅을 커스텀할 수 있도록 LoggerService 인터페이스를 제공합니다.
이를 활용해 커스텀 Logger를 생성하고, 애플리케이션에서 사용할 수 있습니다.
LoggerService 인터페이스를 상속하여 필요한 기능을 오버라이드하는 방식으로 커스텀 로거를 작성할 수 있습니다.
import { LoggerService } from '@nestjs/common';
export class CustomLogger implements LoggerService {
log(message: string) {
console.log(`Custom Log: ${message}`);
}
error(message: string, trace: string) {
console.error(`Custom Error: ${message}`, trace);
}
warn(message: string) {
console.warn(`Custom Warn: ${message}`);
}
debug(message: string) {
console.debug(`Custom Debug: ${message}`);
}
verbose(message: string) {
console.info(`Custom Verbose: ${message}`);
}
}
main.ts 파일에서 app.useLogger(new CustomLogger())로 커스텀 Logger를 설정할 수 있습니다.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { CustomLogger } from './custom-logger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useLogger(new CustomLogger()); // 커스텀 Logger 사용
await app.listen(3000);
}
bootstrap();
Winston은 다양한 로깅 기능과 확장성을 제공하는 인기 있는 Node.js 로깅 라이브러리입니다. NestJS에서 Winston을 사용하려면, winston 및 @nestjs/winston 패키지를 설치해야 합니다.
npm install winston @nestjs/winston
Winston을 사용하려면 WinstonModule을 AppModule에 설정하여 전체 애플리케이션에 적용할 수 있습니다.
import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
@Module({
imports: [
WinstonModule.forRoot({
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} [${level}]: ${message}`;
})
),
}),
],
}),
],
})
export class AppModule {}
transports: Winston에서 로그가 기록되는 위치를 정의하며, Console, File, Http 등 다양한 옵션이 있습니다.
format: 로그의 형식을 설정하며, timestamp, printf 등의 옵션을 통해 메시지를 커스텀할 수 있습니다.
NestJS의 LoggerService 인터페이스를 구현하여 Winston을 기반으로 커스텀 Logger를 작성할 수 있습니다.
import { Injectable, LoggerService } from '@nestjs/common';
import * as winston from 'winston';
@Injectable()
export class WinstonLogger implements LoggerService {
private readonly logger: winston.Logger;
constructor() {
this.logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' }),
],
});
}
log(message: string) {
this.logger.info(message);
}
error(message: string, trace: string) {
this.logger.error(message, { trace });
}
warn(message: string) {
this.logger.warn(message);
}
debug(message: string) {
this.logger.debug(message);
}
verbose(message: string) {
this.logger.verbose(message);
}
}
이제 main.ts 파일에서 Winston 기반 커스텀 Logger를 애플리케이션에 설정할 수 있습니다.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { WinstonLogger } from './winston-logger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useLogger(new WinstonLogger());
await app.listen(3000);
}
bootstrap();
NestJS에서 Winston을 활용한 커스텀 Logger를 완벽하게 구성할 수 있습니다.