Winston을 이용한 logger

0

이번엔 서버에서 발생하는 모든 요청,에러 등에 대한 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경로가 기록되게 된다.
실서버에서는 이렇게 저장된 로그 파일을 다른 곳으로 서빙할 것인데, 그건 다음에 알아보자.

profile
https://www.youtube.com/watch?v=__9qLP846JE

0개의 댓글