Javascript/Node.js

[ Node.js ] - winson이용하여 로그 남기기

algml0703 2022. 8. 14. 09:26
반응형

winston

로그 관리를 위해 사용되는 모듈의 일종이다.

사용법

> npm i winston winston-daily-rotate-file
- winston이 실질적인 로그를 남기는 모듈이고,
- winston-daily-rotate-file 모듈을 로그를 일자별로 파일로 관리할 수 있도록 해주는 모듈이다.

기본 틀

import winston from "winston";
import wistonDaily from "winston-daily-rotate-file";

const { combine, printf, label, timestamp } = winston.format;

const logFormat = printf((level, message, label, timestamp) => {
  return `${timestamp} [${label}] ${level} : ${timestamp}`;
});

const logDir = "logs";

const logger = winston.createLogger({
  format: combine(),
  // 각 로그가 출력되는 포맷을 설정해주는 부분이다.
  transports: [],
  // 로그를 어떤 식으로 기록을 남길 지 설정해주는 부분이다.
  exceptionHandlers: [],
  // 설정된 로그를 벗어난 경우에 어떤 식으로 log를 남길 것인지 설정하는 부분이다.
});

export default logger;

 

전체 코드

import winston from 'winston'
import wistonDaily from "winston-daily-rotate-file";
// 로그를 일자별로 생성하여 준다.
import process from "process";

const { level, message, label, timestamp } = winston.format;
// level 로그의 종류

const logFormat = print(({ level, message, label, timestamp }) => {
  return `${timestamp} [${label}] ${level} : ${message}`;
  // 로그 출력 포맷
});

const logDir = "logs";
// 로그를 저장한 폴더명

/**
 * log Level
 */
const logger = winston.createLogger({
  format: combine(
    label({
      // 해당 로그의 명칭을 설정하는 것이다.
      label: "System Name",
    }),
    timestamp({
      format: "YYYY-MM-DD HH:mm:ss",
    }),
    logFormat // 로그 출력 포맷
  ),
  transports: [
    // 로그를 어떤 식으로 기록할 것인지
    // info 레벨의 로그를 저장할 파일 설정
    new wistonDaily({
      level: "info",
      datePattern: "YYYY-MM-DD",
      dirname: logDir,
      filename: "%Date%.log",
      maxFiles: 30,
      zippedArchive: true,
    }),
    // error 레벨 로그를 저장할 파일 설정
    new wistonDaily({
      level: "error",
      datePattern: "YYYY-MM-DD",
      dirname: logDir,
      filename: "%DATE%.error.log",
      maxFiles: 30,
      zippedArchive: true,
    }),
  ],
  exceptionHandlers: [
    //uncaughtException 발생시
    new wistonDaily({
      level: "error",
      datePattern: "YYYY-MM-DD",
      dirname: logDir,
      filename: "%DATE%.exception.log",
      maxFiles: 30,
      zippedArchive: true,
    }),
  ],
});

// production 환경이 아닌 경우 (개발 단계 등)
if (process.env.NODE_ENV !== "production") {
  // 게발 환경인 경우에는 바로 바로 확인할 수 있게 console.log를 추가
  logger.add(
    new winston.transport.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        // 색깔 넣어서 출력
        winston.format.simple()
        // winston에서 제공되는 기본 format을 사용
      ),
    })
  );
}

export default logger;

로그 사용시에는 logger파일을 불러와 설정해둔 level에 따라 상황에 맞게 사용한다. 

import express from "express";
import log from "./config/logger.js";

const app = express();

try {
  app.listen(3000, () => {
    log.info("server start 3000 💥");
    log.error("server error");
    throw new Error();
  });
} catch (e) {
  log.error(e);
}

위의 코드에서 log.error()는 2가지가 존재하는데 우선 try에서 사용된 log.error()의 경우 우리가 transports를 통해 설정해둔 로그가 생성되며, 그 아래의 catch(){} 부분에 작성된 log.error()는 예기치 않은 에러가 발생한 경우에 의해 실행되는 exceptionHandler를 통해 로그가 작성된다.

위와 같이 작성 후 서버를 작동시키면 아래와 같이 logs폴더가 생성되고 그 안에 해당 일자의 log가 기록된 파일이 생성된 것을 확인할 수 있다.

또한 production환경이 아닌 경우 바로 바로 확인할 수 있도록 콘솔 로그도 추가하였기 때문에 터미널 창에도 아래와 같은 콘솔 화면이 나오게 된다.

 

 

 

출처

https://www.youtube.com/watch?v=S0HI5DDCBBs 

winston docs

https://github.com/winstonjs/winston

 

반응형