winston으로 로깅을 해보자
로그를 수집하고, 일정 날자가 지나면 압축하고, 너무 오래된 로그는 삭제하는 등의 log rotate 세팅은 중요합니다.
그런데 morgan은 http 메서드로 특정 URL을 방문할 때만 로깅을 합니다.
서버가 시작되었을 때, 에러가 발생했을 때 등에 대한 로깅은 winston을 사용해야 합니다.
사용법은 간단합니다.
(1) 포맷과 winstonDaily 구성을 하여 로거를 생성하고,
(2) 추가적인 세팅을 한 다음,
(3) logger.error("...") 꼴로 사용하면 됩니다.
- winston: https://github.com/winstonjs/winston
- winston-daily-rotate-file: https://github.com/winstonjs/winston-daily-rotate-file
- winton 포매팅
공식문서에 따른 기본 내용은 다음과 같습니다.
const logger = winston.createLogger({
// 로거의 포맷을 세팅합니다.
format: winston.format.json(),
})
// 출력
{"message":"NODE_ENV : development, server on : http://localhost:5000","level":"info"}
좀 더 알아보기 쉽게 다음과 같이 구성할 수 있습니다.
// winston format
const { combine, timestamp, printf } = winston.format;
// Define log format
// 타임스탬프, level(info, error, warn...), 메세지 순으로 출력됩니다.
const logFormat = printf(({ timestamp, level, message }) => `${timestamp} ${level}: ${message}`);
// 로거를 생성합니다.
const logger = winston.createLogger({
// 로거의 포맷을 세팅합니다.
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
logFormat,
),
... 중략
})
// 출력
// 2021-02-27 16:07:44 info: NODE_ENV : development, server on : http://localhost:5000
- winston-daily-rotate-file
하루 간격으로 로그 파일을 저장하기 위한 방법이다.
www.npmjs.com/package/winston-daily-rotate-file
level의 위계는 info ~ warn ~ error이다. 아래의 경우 warn을 지정하지 않았기 때문에 info에 들어가게 된다.
그러나 대개는 info와 error만 사용하게 된다.
// 로거를 생성합니다.
const logger = winston.createLogger({
... 포맷 관련 설정 생략
// 하루 간격 로그 파일
transports: [
// info log setting
new winstonDaily({
level: 'info', // info 레벨의 경우
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/info', // 로그 파일이 저장될 경로
filename: `%DATE%.log`, // 생성될 파일 이름
maxFiles: 30, // 30 Days saved
json: false,
zippedArchive: true,
}),
// error log setting
new winstonDaily({
level: 'error',
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/error', // 로그 파일이 저장될 경로
filename: `%DATE%.error.log`, // 생성될 파일 이름
maxFiles: 30, // 30 Days saved
handleExceptions: true,
json: false,
zippedArchive: true,
}),
],
});
- logger 사용법
winston 로거는 다음과 같이 사용하면 됩니다.
logger.[method](message) 꼴이고, logger를 생성할 때 지정한 포맷대로 로깅됩니다.
logger.info(`NODE_ENV : ${this.env}, server on : http://localhost:${this.port}`);
logger.error('anyhing');
logger.warn('warning');
오늘 날짜로 생성된 /logs/error/xxxx.error.log를 열어보면, error가 발생한 부분이 가지런히 정리된 것을 확인할 수 있습니다.
2021-02-27 15:49:49 error: anyhing
2021-02-27 15:50:15 error: anyhing
2021-02-27 15:51:01 error: anyhing
- logger 추가적인 작업
transport를 추가하거나, 지울 수 있습니다.
logger
.clear() // Remove all transports
.add(console) // Add console transport
.add(files) // Add file transport
.remove(console); // Remove console transport
콘솔에 컬러를 하고, 다듬는 등의 작업을 해줄 수 있습니다.
logger.add(
new winston.transports.Console({
format: winston.format.combine(winston.format.splat(), winston.format.colorize(), winston.format.simple()),
}),
);
- morgan과 같이 사용하기
// winston
const stream = {
write: (message: string) => {
logger.info(message.substring(0, message.lastIndexOf('\n')));
},
};
// morgan
this.app.use(morgan('dev', { stream }));
morgan의 두번 째 인자로 stream을 넘길 수 있습니다.
Output stream for writing log lines, defaults to process.stdout.
www.npmjs.com/package/morgan#stream
// 기본 출력
GET /v1/ 304 4.908 ms - -
// winston 포맷으로
info: GET /v1/ 304 8.683 ms - - {"timestamp":"2021-02-27 16:39:59"}