프로젝트를 진행하면서 터지는 버그나, 프론트가 테스트하면서 보내는 로그를 들어가서 매번 직접 확인하는 것은 능률이 매우 떨어지며... 비효율적인 방법이다.
때문에 우리 서비스의 동작 과정, 서비스 기록, 에러 기록을 위한 로깅이 필수적이었다.
프로젝트의 규모가 커질수록 에러가 난 코드를 추적하는 것은 어려우며, 시간과 노력이 많이 든다
먼저 필요한 모듈을 설치해준다.
moment-timezone : 한국 시간으로 로그를 찍기 위해
npm ci moment-timezone winston-daily-rotate-file winston
로깅 설정을 해둔다.
로그 파일이 저장될 폴더를 지정해주었다.
로그가 찍히는 시간을 아시아/서울로 지정해주었다.
import * as winston from 'winston';
import { utilities as nestWinstonModuleUtilities } from 'nest-winston';
import * as winstonDaily from 'winston-daily-rotate-file';
import * as moment from 'moment-timezone';
const appendTimestamp = winston.format((info, opts) => {
if (opts.tz) info.timestamp = moment().tz(opts.tz).format(' YYYY-MM-DD HH:mm:ss ||');
return info;
});
export const winstonConfig = {
transports: [
new winston.transports.Console({
level: process.env.NODE_ENV === 'production' ? 'info' : 'silly',
format: winston.format.combine(
appendTimestamp({ tz: 'Asia/Seoul' }),
nestWinstonModuleUtilities.format.nestLike('MyApp', {
prettyPrint: true,
}),
),
}),
new winstonDaily({
dirname: `./logs/`,
format: winston.format.combine(
appendTimestamp({ tz: 'Asia/Seoul' }),
nestWinstonModuleUtilities.format.nestLike('Hy-fes', {
prettyPrint: true,
}),
),
}),
],
};
최상위 모듈에 winstonModul을 import한다
import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston';
import { winstonConfig } from './config/winston.config';
@Module({
imports: [
...
WinstonModule.forRoot(winstonConfig),
...
],
controllers: [AppController],
})
export class AppModule {}
import { WinstonModule } from 'nest-winston';
@Module({
imports: [
WinstonModule,
],
providers: [UserService],
controllers: [UserController],
})
export class UserModule {}
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger as WinstonLogger } from 'winston';
@ApiTags('User')
@Controller('user')
export class UserController {
constructor(
private readonly userService: UserService,
@Inject(WINSTON_MODULE_PROVIDER)
private readonly logger: WinstonLogger,
) {}
@Get()
async getHello(): Promise<GetClubOverviewDTO[]> {
this.logger.info(`[User Controller - getHello]`);
return await this.userService.getHello();
}
}
위 컨트롤러처럼 주입을 받아서 사용하면 된다.

이렇게 날짜 이름으로 로그 파일이 생성되며,
[MyApp] Info 2023-09-02 19:49:06 || [User Controller - getHello]
로그 파일 내부에 로그가 찍혀있는 것을 확인할 수 있다.
앱의 필요에 따라, DTO의 핵심 정보 같은 것이나, 에러 메시지를 함께 출력하도록 하자.