개발/Node & Javascript
Nest.js 탐험기 - logging을 winston과 함께 사용해보자.
말고기
2021. 2. 12. 16:22
728x90
반응형
개요
- 이번 시간에는 logging을 적용해보려고 한다.
- winston을 사용해보려고 한다.
Setup
우선 logging을 적용하기 위해 다음과 같이 설치해준다.
yarn add winston winston-daily-rotate-file;
winston
- Node 진영의 대표적인 로깅 라이브러리이다.
- 다양한 transport layer를 사용할 수 있고, 또한 custom하게 implementation이 가능하다.
- winston-daily-rotate-file의 경우에는 logrotate를 설정하기 위해서 사용했다.
코드를 작성해보자!
1. configuration 등록
우선적으로 winston을 먼저 셋팅해두자.
import * as winston from 'winston';
import 'winston-daily-rotate-file';
import { Logger, format } from 'winston';
const { combine, timestamp, prettyPrint, colorize, errors, json } = format;
let logger: Logger;
const createLogger = () => {
if (logger) {
logger.error('Logger instance already defined. So ignore it.');
return;
}
logger = winston.createLogger({
level: process.env.NODE_ENV === 'production' ? 'warn' : 'info',
format: combine(
errors({ stack: true }), // <-- use errors format
timestamp(),
json(),
...(process.env.NODE_ENV !== 'production' ? [prettyPrint()] : []),
),
defaultMeta: { service: 'pie' },
transports: [],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(
new winston.transports.Console({
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
}),
);
}
// 절대로 production에 이 파일 넣으면 안됩니다. maxSize를 보세여!!
if (process.env.NODE_ENV === 'production') {
logger.add(
new winston.transports.DailyRotateFile({
level: 'error',
filename: 'log/error-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '1k',
maxFiles: '14d',
}),
);
logger.add(
new winston.transports.DailyRotateFile({
filename: 'log/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '1k',
maxFiles: '14d',
}),
);
}
};
export { logger, createLogger }
위는 logger를 셋팅해주고 있다.
기본적인 형식을 따르고 있는데, 주목해야 되는 부분은 크게 transports
, format
, level
과 같다.
- transports
- 해당 log를 어디로 보낼지를 결정할 수 있다.
- 여러개를 지정할 수 있다.
- format
- 해당 log의 format을 설정할 수 있는데, color나 out format을 json으로 할지 등등을 결정할 수 있다.
- 직접 custom format을 작성할 수 있는데, 해당 부분은 아래에서 다루도록 한다.
- level
- log level을 설정할 수 있다.
2. nest logging moudle implementation
- 크게 두 가지 방식으로 implementation이 가능한데, implements를 통해서 logging module을 delegate하거나, 또는 자체 logging을 직접 implementation 하는 방식이 있다.
- nest.js default loggingService
- 위의 해당 코드를 보면 알 수 있는데, 자체적으로 implementation된 logging service가 존재하는데, 완전히 커스텀하게 구현하는 것보다 필요한 부분만 구현하는 것이 좋아보여서 ( = 귀찮아서... ) 다음과 같이 구현하도록 한다.
- logging service를 작성한다.
// ... file 이름 이쁘게 지어주세요.
export class AppLoggingService implements LoggerService {
log(message: string, context?: string) {
logger.info(message, {
from: context,
});
}
error(message: string, trace: string, context?: string) {
logger.error(message, { stack: trace, context });
}
warn(message: string, context?: string) {
logger.warn(message, context);
}
debug(message: string, context?: string) {
logger.debug(message, context);
}
verbose(message: string, context?: string) {
logger.verbose(message, context);
}
}
- boostrap에 logger를 inject한다.
// main.ts
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
logger: new AppLoggingService(),
});
// ... other code
}
후기
- nest.js에서 쉽게 logging을 적용할 수 있게 해두어서, 쉽게 적용할 수 있었다.
- child-logger에 관련된 방식이 있는데, 해당 부분은 어떤 방식으로 수행되는지 좀 더 잘 살펴봐야겠다.
- 간단하게 내용을 정리했지만, format쪽을 좀 더 다듬어서, 쉽게 error를 tracking하거나, transport를 file, console이 아닌 외부에 전달하는 부분도 살펴봐야한다. (이 것도 부록으로...)
출처
728x90
반응형