이건 저도 최근에 알게 된 모듈입니다. 서버에 찍히는 콘솔을 logging 해주는 라이브러리가 있다고 하여 알아보게 되어서 블로그에 정리할 겸 올려봅니다.
logging이란 무엇일까요? 저도 지금까지 프로젝트를 하면서 이런 개념은 사용한 적이 없어서 '이게 뭘까?' 싶었습니다.
바로 구글에 검색해보니 이게 진짜 말그대로 콘솔에 찍은 것을 기록으로 남길 수 있더라고요. 파일로도 만들어서 관리할 수 있고 진짜 영화에서 보던 것이 logging이었습니다.
저번 시간에 언급한 .env가 보안에서 중요한 영역이었다면 이 logging은 백엔드 작업을 할때 빼놓을 수 없는 그런 친구인 것 같더라고요.
그리고 이 logging을 이용할 수 있게 해주는 라이브러리가 Winston이라는 라이브러리입니다. 외에도 몇 개 있는데 검색해보니 Winston 라이브러리가 압도적으로 자료가 많더라고요. 그래서 저도 Winston 라이브러리에 대해서 많이 알아봤습니다.
npm install winston winston-daily-rotate-file
언제나와 똑같이 라이브러리를 사용하기 위해서는 설치를 해야겠죠? winston 라이브러리는 신기하게 Winston과 winston-daily-rotate-file 모듈 하나를 더 다운 받습니다.
winston-daily-rotate-file의 역활은 로그 파일을 관리해주는 역활을 한다고 합니다!
./config/winston.js 파일을 생성하고 아래와 같이 설정합니다.
import winston from 'winston'; import winstonDaily from 'winston-daily-rotate-file'; const logDir = 'logs'; // logs 디렉토리 하위에 로그 파일 저장 const { combine, timestamp, printf } = winston.format; // Define log format const logFormat = printf(info => { return `${info.timestamp} ${info.level}: ${info.message}`; }); /* * Log Level * error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6 */ const logger = winston.createLogger({ format: combine( timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), logFormat, ), transports: [ // info 레벨 로그를 저장할 파일 설정 new winstonDaily({ level: 'info', datePattern: 'YYYY-MM-DD', dirname: logDir, filename: `%DATE%.log`, maxFiles: 30, // 30일치 로그 파일 저장 zippedArchive: true, }), // error 레벨 로그를 저장할 파일 설정 new winstonDaily({ level: 'error', datePattern: 'YYYY-MM-DD', dirname: logDir + '/error', // error.log 파일은 /logs/error 하위에 저장 filename: `%DATE%.error.log`, maxFiles: 30, zippedArchive: true, }), ], }); // Production 환경이 아닌 경우(dev 등) if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), // 색깔 넣어서 출력 winston.format.simple(), // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력 ) })); } export { logger };
이런 긴 코드를 이용해서 '설정'을 해줍니다.
휴... logging 한 번 사용하기 쉽지 않네요.
그리고 winston에서는
error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6
이런 레벨 체계를 가진다고 합니다.
여기서 레벨이 뭔지 정말 머리가 아팠는데 이 설명을 보고 이해를 할 수 있었습니다.
level을 설정하면 해당 레벨 이상의 priority를 가지는(즉, 숫자가 같거나 낮은) 로그를 출력하게 됩니다.
자, 이게 무슨 말이냐? 저 위에 코드에서는 info 레벨로 설정을 했습니다. info는 2의 value를 가지고 있죠? 그러니까 로그를 출력할때 2보다 같거나 그보다 낮은 2, 1, 0 단계가 출력된다는 겁니다.
저 위에 설정에서는 error 코드를 따로 뺴서 출력하고 싶어서 따로 transport를 설정 해주었고요.
그리고 로그마다 색깔 설정도 가능합니다. 이게 안되면 가시성이 떨어지겠죠??
디폴트로는
error: 'red', warn: 'yellow', info: 'green', http: 'magenta', debug: 'blue',
이렇게 설정 되어있습니다~!
이제 설정도 끝났고 전체적인 Winston의 기능도 알아봤으니 사용할 차례입니다.
const express = require('express') const { logger } = require('./config/winston'); const app = express().Application; app.get('/', (req, res) => { logger.info('GET /'); res.sendStatus(200); }); app.get('/error', (req, res) => { logger.error('Error message'); res.sendStatus(500); }); app.listen(3000, () => { logger.info('Server listening on port 3000'); });
이제 실질적으로 사용하여 로그를 남겨볼까요??
매우 간단한 코드입니다. export한 logger 모듈을 import해서
'/'와 '/error' url에 들어갔을떄 로그가 찍히도록 짠 코드입니다.
이제 구동을 해보면...
Server listening on port 3000이라는 출력이 저희가 설정해둔 방식으로 가시성 좋게 출력이 잘 됩니다.
그리고 /error에 들어가시면 빨간색으로 error 메세지가 뜨죠.
정말 이런 기능을 지금 알았다는 것에 아직 배워야할 것이 산더미라는 것을 느낍니다.
위에도 있습니다만, 이 벨로그를 참고하였습니다.
그 외에도 많은 블로그를 참고하여 공부하는데 도움이 되었습니다.
감사합니다.