체인의정석

winston으로 백엔드 로그 관리하기 본문

개발/backend

winston으로 백엔드 로그 관리하기

체인의정석 2024. 9. 4. 16:48
728x90
반응형

여태까지 로그 관리의 경우 log4.js로 이미 진행중인 백엔드에 온보딩하여 남긴 경험밖에 없었는데, 따로 이벤트 봇을 만들게 되어 여기서 winston으로 로그 관리를 적용하였으며 이에 대한 내용을 정리해 보겠다.

1. 사용모듈 및 설정 방법

https://www.npmjs.com/package/winston-daily-rotate-file

 

winston-daily-rotate-file

A transport for winston which logs to a rotating file each day.. Latest version: 5.0.0, last published: 7 months ago. Start using winston-daily-rotate-file in your project by running `npm i winston-daily-rotate-file`. There are 2030 other projects in the n

www.npmjs.com

 

winston 외에도 winston-daily-rotate-file 까지 쓰게 되면 특정 기간 별로 로그를 나누어서 저장할 수 있는 장점이 존재한다.

const winston = require('winston');
require('winston-daily-rotate-file');

먼저 해당 모듈을 사용할 경우 세팅을 기본적으로 해줘야하는데 나는 다음과 같이 세팅을 진행하였다.

// Winston logger setup
const transport = new winston.transports.DailyRotateFile({
    level: 'info',
    filename: 'logs/application-%DATE%.log',
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    maxSize: '1d',
    maxFiles: '30d'
});

const logger = winston.createLogger({
    transports: [
        transport,
        new winston.transports.Console()
    ],
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.printf(({ timestamp, level, message }) => {
            return `${timestamp} [${level}]: ${message}`;
        })
    )
});

보면 transport에서 level을 info로 두었는데 기본적으로 제공하는 level의 종류가 있기 때문에 거기 맞추어서 관리해주면 된다. 나의 경우에는 error와 info 2개의 level을 사용하였으며 info 부분만 명시적으로 정리하였다.

zippedArchive를 true로 해두면 용량이 커지면 zip 파일로 관리가 되며

max size와 maxfiles를 통해서 로그별 사이즈랑 파일 등을 시간 단위로 지정할 수 있ㄷ.

filename의 경우 파일의 이름을 의미하며 해당 프로그램이 실행되는 경로에 있는 log경로 밑에 기록하도록 만들었다.

또한 winston.createLogger를 사용해서 로그를 남길 경우의 포맷을 뽑아낼 수 있다.

 

2. 로그 남기기

상황에 따라서 미리 지정된 level에 해당되는 로그를 남길 수있다.

logger.error('file not found at:', filePath);
logger.info(`event emitted with tx hash ${event.log.transactionHash}`);

위와 같은 식으로 logger.error , logger.info 와 같이 미리 예약 되어 있는 level의 로그를 남길 수 있다.

3. 공식 예제

공식 사이트에 있는 기본 예제는 다음과 같다.

  var winston = require('winston');
  require('winston-daily-rotate-file');

  var transport = new winston.transports.DailyRotateFile({
    level: 'info',
    filename: 'application-%DATE%.log',
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    maxSize: '20m',
    maxFiles: '14d'
  });
  
  transport.on('error', error => {
    // log or handle errors here
  });

  transport.on('rotate', (oldFilename, newFilename) => {
    // do something fun
  });

  var logger = winston.createLogger({
    transports: [
      transport
    ]
  });

  logger.info('Hello World!');

하나의 level info만 다루는 경우 위와 같이 사용이 가능하며 하나의 경로 안에 모든 내용이 다 들어가게 된다.
아래는 에러와 log를 분리하여 저장 시키는 케이스이다.

  var winston = require('winston');
  require('winston-daily-rotate-file');

  var transport1 = new winston.transports.DailyRotateFile({
    filename: 'application-%DATE%.log',
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    maxSize: '20m',
    maxFiles: '14d'
  });

  var transport2 = new winston.transports.DailyRotateFile({
    level: 'error',
    filename: 'application-error-%DATE%.log',
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    maxSize: '20m',
    maxFiles: '14d'
  });

  transport1.on('error', error => {
    // log or handle errors here
  });

  transport2.on('error', error => {
    // log or handle errors here
  });

  transport1.on('rotate', function(oldFilename, newFilename) {
    // do something fun
  });

  transport2.on('rotate', function(oldFilename, newFilename) {
    // do something fun
  });

  var logger = winston.createLogger({
    level: 'info'
    transports: [
      transport1, // will be used on info level
      transport2  // will be used on error level
    ]
  });

  logger.info('Hello World!');
  logger.error('Hello Error!');
728x90
반응형
Comments