이번엔 서버에서 발생하는 모든 요청,에러 등에 대한 log를 기록하는 logger를 만들어 보았다.
winton - npm
log를 기록하는데에 여러가지 라이브러리를 사용할 수 있지만, 다운로드 조회수도 많고 용량도 적은 winston을 사용하기로 하였다.
class WinstonLogger {
private static instance: WinstonLogger;
private readonly logger: Logger;
static getInstance(): WinstonLogger {
if (!WinstonLogger.instance) {
WinstonLogger.instance = new WinstonLogger();
}
return WinstonLogger.instance;
}
}
logger는 모든 api에서 쓰이고 사용처도 다양하기 때문에 각 파일에서 인스턴스를 한번만 생성하도록 싱글턴 방식으로 제작하였다.
private constructor() {
const infoLog = new WinstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD', // 파일 날짜 형식
dirname: `/tmp/logs/info`, // 파일 경로
filename: `%DATE%.info.log`, // 파일 이름 형식 2020-05-28.info.log
});
const httpLog = new WinstonDaily({
level: 'http', // http 보다 낮은애들은 모두 파일에 저장
datePattern: 'YYYY-MM-DD',
dirname: `/tmp/logs/http`,
filename: `%DATE%.info.log`,
});
const errorLog = new WinstonDaily({
level: 'error',
datePattern: 'YYYY-MM-DD',
dirname: `/tmp/logs/error`,
filename: `%DATE%.error.log`,
});
const exceptionLog = new WinstonDaily({
level: 'error',
datePattern: 'YYYY-MM-DD',
dirname: `/tmp/logs/exception`,
filename: `%DATE%.exception.log`,
});
const terminalLog = new transports.Console({
level: 'debug',
format: format.combine(format.colorize(), format.timestamp(), logFormat),
});
let transport;
let exceptionHandler;
if (process.env.NODE_ENV === 'production') {
transport = [infoLog, errorLog, httpLog];
exceptionHandler = exceptionLog;
} else if (process.env.NODE_ENV === 'development') {
transport = [infoLog, errorLog, httpLog];
exceptionHandler = exceptionLog;
} else {
transport = terminalLog;
exceptionHandler = terminalLog;
}
this.logger = createLogger({
format: format.combine(format.timestamp(), logFormat),
transports: transport,
exceptionHandlers: exceptionHandler,
});
}
또한 환경변수에 따라 나누어 local개발 환경에선 로그가 터미널에만 찍히도록하고, production과 development시에는 파일에 저장되도록 수정하였다.
app.use((req, res, next) => {
logger.http(`[${req.method}] ${req.url}`);
next();
});
app.use를 app.ts 상단에 두어 들어오는 요청에 대해 모두 log가 남도록 하였다.
이렇게 하면 요청마다 method와 api경로가 기록되게 된다.
실서버에서는 이렇게 저장된 로그 파일을 다른 곳으로 서빙할 것인데, 그건 다음에 알아보자.