log4js
스프링을 하다가 Nodejs로 넘어온뒤 가장 낯익은 로그 라이브러리는 log4js 였다.
log4js 의 장점은 설정 옵션이 간단한 편? 이라고 생각한다.
일단 라이브러리부터 설치한다.
## npm $ npm i --save log4js ## yarn $ yarn add log4js
이 후, log4js 설정파일을 만든다. (파일로 안만들고 바로 넣어도된다..)
## ./log4js.json { "appenders": { "app": { "type": "console" }, "infoFile": { "type": "file", "filename": "./log/info.log", "maxLogSize": 524288, "numBackups": 3, "compress": true }, "info": { "type": "logLevelFilter", "level": "INFO", "appender": "infoFile" }, "errorFile": { "type": "file", "filename": "./log/errors.log", "maxLogSize": 524288, "numBackups": 3, "compress": true }, "errors": { "type": "logLevelFilter", "level": "ERROR", "appender": "errorFile" } }, "categories": { "default": { "appenders": [ "app", "errors", "info" ], "level": "info" } } }
appenders : log4js 의 액션을 담당 ( 각 종류 별로 파일저장, 콘솔출력 등을 정의할 수 있다.)
categories : log4js.getLogger() 함수의 매개변수로 지정한 카테고리로 원하는 로그액션을 처리할 수 있다.
default : 기본설정으로 여기서는 app(콘솔출력), errors(에러로그파일저장), info(모든로그파일저장) 를 appenders에 추가했다.
설정을 정의하고 (나는 내가 출력시키는 모든 로그에 대해서 콘솔창에 출력 및 info 로그와 error 로그를 파일로 쌓도록 설정하였다.) nodejs 가 시작할 때, log4js 의 configure 함수를 통해 설정을 완료하면 된다.
const path = require('path'); const log4js = require('log4js'); log4js.configure(path.join(__dirname, 'log4js.json')); // log4js 설정
이 후, 로그를 원하는 위치에서 import 이후 사용하면된다.
const logger = require('log4js').getLogger('logTest'); logger.info('info test'); logger.error('error test');



콘솔 로그에도 찍히고, 파일로도 정상적으로 쌓이는것을 확인할 수 있다.
위에서 보는 바와 같이 log4js 의 장점은 log4js 패키지를 가져와서 설정을 했기 때문에 한번 설정해놓으면 어디서든지 log4js 의 패키지를 가져오면 같은 설정이라는 점이다.
winston
winston 은 사용자가 많다. 그만큼 인터넷에 정보도 많고, 관련 라이브러리도 많은 것 같다.
라이브러리를 설치한다.
## npm $ npm i --save winston $ npm i --save winston-daily-rotate-file ## yarn $ yarn add winston $ yarn add winston-daily-rotate-file
winston 의 로그 설정을 한다.
/** * winston.js */ const winston = require('winston'); const winstonDaily = require('winston-daily-rotate-file'); // 날짜별로 로그 저장 const logDir = 'logs'; // logs 디렉토리 하위에 로그 파일 저장 const { combine, timestamp, printf, label } = winston.format; const colorize = winston.format.colorize(); // 로그레벨별로 색상 정의 // 기본설정을 사용하면 로그레벨만 색상이 적용되어 출력되는 로그를 재정의하였다. // Define log format const logFormat = printf(({ level, message, label, timestamp }) => { return `${colorize.colorize(level, `[${timestamp}] [${level.toUpperCase()}] ${label ?? 'default'}:`)} ${message}`; }); /** * winston 로그 사용을 위한 함수 * @param path{string}: label * @returns {Logger} */ const getLogger = (path) => { /** * Log Level * error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6 */ const logger = winston.createLogger({ format: combine( label({ label: path }), // 로그 출력 시 라벨링 설정 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, }), ], }); /** * http log */ const httpLogger = winston.createLogger({ format: combine( label({ label: 'http' }), timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), logFormat, ), transports: [ // info 레벨 로그를 저장할 파일 설정 new winstonDaily({ level: 'info', datePattern: 'YYYY-MM-DD', dirname: logDir, filename: `%DATE%.http.log`, maxFiles: 30, // 30일치 로그 파일 저장 zippedArchive: true, }) ], }); logger.stream = { write: (message, encoding) => { httpLogger.info(message); } }; // Production 환경이 아닌 경우(dev 등) - Console 로그 출력 if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ // handleExceptions: true, // json: false, format: combine( label({ label: path }), timestamp(), logFormat, // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력 // winston.format.simple(), ) })); } return logger; }; module.exports = getLogger;
이 후, 로그를 원하는 위치에서 import 이후 사용하면된다.
const logger = require('./winston')('server'); logger.info('winston info log test'); logger.error('winston error log test');



위와 같이 정상적으로 로그가 출력되고, 파일로 저장되는 것을 확인할 수 있다.
+ morgan ( with winston )
morgan 은 http request 에 대한 로그를 기록하는 미들웨어이다.
winston 을 사용하고 있다면, 기존 로거를 사용해도 되지만 나는 새로 만들었다. ( 위 글 winston 예제를 참고하신 거라면 이미 추가 되어 있을 것이다.)
// winston.js /** * http log */ const httpLogger = winston.createLogger({ format: combine( label({ label: 'http' }), timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), logFormat, ), transports: [ // info 레벨 로그를 저장할 파일 설정 new winstonDaily({ level: 'info', datePattern: 'YYYY-MM-DD', dirname: logDir, filename: `%DATE%.http.log`, maxFiles: 30, // 30일치 로그 파일 저장 zippedArchive: true, }) ], }); logger.stream = { write: (message, encoding) => { httpLogger.info(message); } };
이 후, express 를 셋팅하는 부분에서
// app.js const express = require('express'); const cors = require('cors'); const morgan = require('morgan'); const { stream } = require('./winston')(); const app = express(); app.use(cors()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use( // 환경에 따라 다른 인자 적용 - 운영 : combined , 개발 : dev // (dev, short, common, combined) morgan(process.env.NODE_ENV !== "production" ? "dev" : "combined", { // 400 미만의 http code일 때는 스킵 skip: (req, res) => { return res.statusCode < 400 }, // 400 이상일 때 로그 출력 stream }) ); ...........생략................
2021-04-18.http.log
[dev]
[2021-04-18 11:21:47] [INFO] http: GET /api/v1/test/test1 404 2.554 ms - -
[combined]
[2021-04-18 11:20:06] [INFO] http: ::1 - - [18/Apr/2021:02:20:06 +0000] "GET /api/v1/test/test1 HTTP/1.1" 404 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36"
위와 같이 파일로 저장되는 것을 확인 할 수 있다.
각 로그 라이브러리들은 장단점이 있을 수 있기 때문에 본인 입맛에 맞는 라이브러리를 사용하면 될 듯 하다.
참고소스
https://github.com/sbjang123456/nodejs-sequelize-pm2.git
sbjang123456/nodejs-sequelize-pm2
pm2 배포 환경 설정. Contribute to sbjang123456/nodejs-sequelize-pm2 development by creating an account on GitHub.
github.com
'Nodejs' 카테고리의 다른 글
사용자 접속 IP 가져오기 (0) | 2022.01.11 |
---|---|
Window NVM 설치 및 설정 (0) | 2022.01.10 |
Nodejs PM2 배포 - ecosystem.config.js (babel 적용) (0) | 2021.04.09 |
Nodejs 상대경로 지옥 탈출하기 (0) | 2021.04.08 |
Nodejs 개발환경 구성(nodemon, babel-node) (0) | 2021.04.04 |