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
'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 |