로그 처리
winston 깃 허브 문서 : https://github.com/winstonjs/winston
소스 : https://github.com/braverokmc79/login-lecture
1. 설치
$ npm install winston $ npm install winston-daily-rotate-file $ npm install dotenv
2.env 설정
개발시 dev , 운영서버 반영시 production
.env
NODE_ENV ="dev"
app.js 에 추가
const dotenv = require("dotenv"); dotenv.config();
3. winston.log.js 파일과 logger.js 파일을 config 디렉토리에 저장한다.
1) src/config/winston.log.js
const winston = require("winston"); const winstonDaily = require("winston-daily-rotate-file"); const { combine, timestamp, printf, colorize, label } = winston.format; const logDir = "logs"; // logs 디렉토리 하위에 로그 파일 저장 const logFormat = printf((info) => { return `${info.timestamp} ${info.level}: ${info.message}`; }); const productionWinstonDail = [ new winstonDaily({ level: "warn", datePattern: "YYYY-MM-DD", dirname: logDir + "/warn", filename: `%DATE%.warn.log`, // file 이름 날짜로 저장 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, }) ] const devWinstonDail = [...productionWinstonDail]; devWinstonDail.push( // info 레벨 로그를 저장할 파일 설정 new winstonDaily({ level: "info", datePattern: "YYYY-MM-DD", dirname: logDir + "/info", filename: `%DATE%.info.log`, // file 이름 날짜로 저장 maxFiles: 30, // 30일치 로그 파일 저장 zippedArchive: true, })); /* * Log Level * error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6 */ const winstonLog = winston.createLogger({ format: combine( timestamp({ format: "YYYY-MM-DD HH:mm:ss", }), logFormat ), transports: process.env.NODE_ENV !== "production" ? devWinstonDail : productionWinstonDail }); winstonLog.stream = { // morgan wiston 설정 write: (message) => { logger.info(message); }, }; // Production 환경이 아닌 경우(dev 등) 배포 환경에서는 // 최대한 자원을 안잡아 먹는 로그를 출력해야함 if (process.env.NODE_ENV !== "production") { winstonLog.add( // new winston.transports.Console({ // format: combine( // colorize({ all: true }), // console 에 출력할 로그 컬러 설정 적용함 // logFormat // log format 적용 // ), // }); new winston.transports.Console({ name: 'debug-console', colorize: true, level: "debug", format: combine( label({ label: '백엔드 맛보기' }), colorize(), timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), printf( info => `${info.timestamp} | [${info.label}] | (${info.level}) : ${info.message} ` ) ), showlevel: true, json: false, }) ); } module.exports = winstonLog;
2) src/config/logger.js
const winstonLog = require("./winston.log"); const parseurl = require('parseurl'); //로그 처리 및 결과값 반환처리 const logger = (response, req, res) => { const url = { method: req.method, path: parseurl(req).pathname, status: (response !== null ? response.err : false) ? 400 : 200, }; if (response === null) { winstonLog.info(`${url.method} | ${url.path} 화면 | Request Query : ${JSON.stringify(req.query)} `); return; } let result = false; if (response.err) { winstonLog.error( `${url.method} ${url.path} ${url.status} Response: ${response.success} | Request Body : ${JSON.stringify(req.body)} | msg | ${response.err}` ); result = true; } else { if (url.method === "GET") { winstonLog.info(`${url.method} | ${url.path} 화면 | Request Query : ${JSON.stringify(req.query)} | msg | ${response.msg || ""} `); } else { winstonLog.info( `${url.method} ${url.path} ${url.status} Response: ${response.success} | Request Body : ${JSON.stringify(req.body)} | msg | ${response.msg || ""}` ); } result = false; } if (result) return res.status(400).json({ msg: response.err.toString() }); return res.status(200).json(response); }; module.exports = logger;
3) logs 폴더를 프로젝트 app.js 와 동일한 루트 경로에 생성한다.
4. 사용방법
1) 모델에서 에러반환 처리 또는 try~catch 처리로 에러 또는 메시지 반환 처리를 한다.
src/models/UserStorage.js
static async getUserInfo(id) { return new Promise((resolove, rejects) => { const query = "SELECT * FROM users WHERE id= 6 ?"; db.query(query, [id], function (err, data) { if (err) return rejects(err); resolove(data.length === 0 ? false : data[0]); }) }); }
src/models/User.js
async login() { try { const client = this.body; const { id, psword } = await UserStorage.getUserInfo(client.id); if (id) { if (id === client.id && psword === client.psword) { return { success: true }; } return { success: false, msg: "비밀번호가 틀렸습니다." }; } return { success: false, msg: "존재하지 않는 아이디 입니다." }; } catch (err) { return { success: false, err } } }
2) 컨트롤에서 get 방식 post 방식에 따라 알맞게 logger 함수를 사용한다.
컨트롤 코드 예
"use strict" const User = require("../../models/User"); const logger = require("../../config/logger"); const output = { home: (req, res) => { logger(null, req, res); res.render("home/index"); }, login: (req, res) => { logger(null, req, res); res.render("home/login"); }, register: (req, res) => { logger(null, req, res); res.render("home/register"); } } const process = { login: async (req, res) => { const user = new User(req.body); const response = await user.login(); logger(response, req, res); }, register: async (req, res) => { const user = new User(req.body); const response = await user.register(); logger(response, req, res); } } module.exports = { output, process }
3) 반환처리 방법은 프로젝트에 맞게 logger.js 파일을 수정해서 사용할것
댓글 ( 4)
댓글 남기기