개발 노트

Winston 모듈 본문

Node

Winston 모듈

한츄 2023. 12. 22. 14:25

서비스를 운영하기 위해서는 로그를 꼼꼼하게 남겨야 합니다.

로그는 에러를 파악하고 관리하는 방법이기 때문에 로그시스템을 구축하는 것이 필요합니다.

 

test개발중에는 console.log와 console.error을 사용하게 되는데 console객체의 메서드들은 언제 호출되었는지 파악이 어렵고, 서버가 종료되는 순간 쌓여있던 로그들도 사라져버리기 때문입니다.

 

이와같은 상황을 방지하려면 배포시에 로그를 외부파일로 저장해서 관리하는것이 바람직한데, 이때 winston을 사용합니다.

 

Winston 모듈 사용하기

https://www.npmjs.com/package/winston

 

winston

A logger for just about everything.. Latest version: 3.11.0, last published: 2 months ago. Start using winston in your project by running `npm i winston`. There are 19561 other projects in the npm registry using winston.

www.npmjs.com

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: 4.7.1, last published: 2 years ago. Start using winston-daily-rotate-file in your project by running `npm i winston-daily-rotate-file`. There are 1781 other projects in the np

www.npmjs.com

 

winston은 로그파일을 생성해주는 모듈이고 winstion-daily-rotate-file은 로그파일들을 생성 / 관리 해주는 모듈입니다.

$ npm i winston winston-daily-rotate-file

 

1. Winston 로그 경로 설정

winston을 설치 한 다음 logger.js 파일을 생성합니다.

const winston = require('winston');
const path = require('path');
const DailyRotateFile = require('winston-daily-rotate-file');
const { combine, timestamp, json } = winston.format;

// 로그 파일들을 저장할 디렉토리를 설정합니다.
const logDirectory = path.resolve('C:/User/user');

const logFormat = printf(({ level, message, label, timestamp }) => {
   return `${timestamp} [${label}] ${level}: ${message}`; // 날짜 [시스템이름] 로그레벨 메세지
});

 

필요한 모듈을 불러온 뒤, winston.format에서 필요한 메소드와 파라미터를 구조분해하여 저장합니다.

path모듈은 경로를 저장하기 위해서 가져왔는데 사용하지 않고도 가능합니다.

아래는 사용하지 않고 불러온 코드입니다.

// logger.js
const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');
const { combine, timestamp, json } = winston.format;

// 로그 파일들을 저장할 디렉토리를 설정합니다.
const logDirectory = 'C:\\User\\user';

 

2. Winston 로거 생성(createLogger) 및 로깅형식 지정(transports)

// 로거를 생성
const logger = winston.createLogger({
  format: combine(
    timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    json(),
  ),
  
 // 실제 로그를 어떻게 기록을 한 것인가 정의
 transports: [
    new DailyRotateFile({ 
      filename: path.join(logDirectory, '%DATE%.log'), 
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true,
      maxFiles: '14d',
      level: 'error',
      format: printf(info => {
        let message = info.message.replace(/\n/g, ' ');
        return JSON.stringify({ message: message, timestamp: info.timestamp })})
    }),
    new DailyRotateFile({ 
      filename: path.join(logDirectory, 'combined-%DATE%.log'),
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true,
      maxFiles: '14d',
      format: json()
    }),
    new winston.transports.Console({
      format: printf(({ level, message }) => {
        return `[${level}] ${message}`;
      })
    })
  ],
});

 

  • createLogger()

winston에서 제공하는 createLogger 메서드를 사용하여 logger를 만들 수 있습니다.

format의 파라미터를 조정하여 메세지에 대한 기본 설정을 합니다.

더보기

format

format은 로그의 형식을 지정할 수 있습니다. 
json, label, timestamp, printf, simple, combine 등의 다양한 형식으로 지정이 가능합니다. 
기본적으로는 JSON 형식으로 기록하지만, combine은 여러 형식을 혼합해서 사용할 때 씁니다. 

  • transports

transports는 로그 저장방식을 정의하며, winston-daily-rotate-file에서 불러온 new DailyRotateFile을 정의하여 어떤 레벨의 로그를 어떤 형식으로 며칠동안 보관할 지를 설정할 수 있습니다.

 

로그레벨의 형식은 다음과 같고 숫자가 낮을 수록 중요도가 높습니다.

 error: 0 , warn: 1 , info: 2 , http: 3 , verbose: 4 , debug: 5 , silly: 6 

레벨을 설정하면 해당 레벨과 같거나 숫자가 작은 레벨의 로그를 출력합니다.

 

외부에 코드를 내보내는 포맷을 두가지 형태로 만들었는데 하나는 JSON타입의 파일로 내보냈고 콘솔에는 에러메세지만 출력되는 형태로 만들었습니다.

new DailyRotateFile({

    frequency: 회전 빈도를 나타내는 문자열입니다. 이는 특정 시간에 발생하는 회전과 달리 시간이 지정된 회전을 원하는 경우에 유용합니다. 유효한 값은 '#m' 또는 '#h'(예: '5m' 또는 '3h')입니다. 이 null을 남겨두는 datePattern것은 회전 시간 에 의존합니다 . (기본값: null)
    
    datePattern: 회전에 사용할 moment.js 날짜 형식 을 나타내는 문자열 입니다. 이 문자열에 사용된 메타 문자는 파일 회전 빈도를 나타냅니다. 예를 들어, datePattern이 단순히 'HH'인 경우 매일 선택하여 추가되는 24개의 로그 파일로 끝납니다. (기본값: 'YYYY-MM-DD')
    
    zippedArchive: 아카이브된 로그 파일을 gzip으로 압축할지 여부를 정의하는 부울입니다. (기본값: '거짓')
    
    filename: 로그에 사용할 파일 이름입니다. 이 파일 이름은 파일 이름의 %DATE%해당 지점에 서식이 지정된 datePattern을 포함하는 자리 표시자를 포함할 수 있습니다 . (기본값: 'winston.log.%DATE%')
    
    dirname: 로그 파일을 저장할 디렉터리 이름입니다. (기본: '.')
    
    stream: 사용자 지정 스트림에 직접 쓰고 회전 기능을 우회합니다. (기본값: null)
    
    maxSize: 회전할 파일의 최대 크기입니다. 바이트 수 또는 kb, mb 및 GB 단위가 될 수 있습니다. 단위를 사용하는 경우 접미사로 'k', 'm' 또는 'g'를 추가합니다. 단위는 숫자를 직접 따라야 합니다. (기본값: null)
    
    maxFiles: 보관할 최대 로그 수입니다. 설정하지 않으면 로그가 제거되지 않습니다. 이는 파일 수 또는 일 수일 수 있습니다. 일을 사용하는 경우 접미사로 'd'를 추가합니다. (기본값: null)
    
    options: 파일 스트림에 전달되어야 하는 추가 옵션을 나타내는 'https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options' 와 유사한 객체 . (기본값: { flags: 'a' })
    
    auditFile : 감사 파일의 이름을 나타내는 문자열. 옵션 개체의 해시를 계산하여 생성된 기본 파일 이름을 재정의하는 데 사용할 수 있습니다. (기본값: '..json')
    
    utc : 파일 이름의 날짜에 UTC 시간을 사용합니다. (기본값: false)
    
    extension : 파일 이름에 추가할 파일 확장자. (기본: '')
    
    createSymlink : 현재 활성 로그 파일에 대한 tailable symlink를 만듭니다. (기본값: false)
    
    symlinkName : tailable symlink의 이름입니다. (기본값: 'current.log')
}),

 

 

3. logger 내보내기

외부에서 log()로 호출하기 위해 별도의 함수로 내보내줍니다.

function log(...args) {
  const message = args.map(arg => {
    if (typeof arg === 'object') {
      return JSON.stringify(arg);
    }
    return arg;
  }).join('\n');
  logger.error(message);
}


module.exports = log;

 

 

외부에서는 다음과같은 형태로 사용하면 됩니다.

const log = require("./logger")

log('에러메세지','여러개도','가능합니다')

 

 

콘솔출력 형태
파일 저장 형태

 

'Node' 카테고리의 다른 글

public ip 가져오기(axios)  (0) 2024.05.20
Path모듈  (0) 2023.12.21
util 모듈 - promisify()  (0) 2023.12.21
mysql 연동 시 datetime 에러  (0) 2023.12.19
Connection과 Connection Pool  (0) 2023.12.19