로그 처리
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)  
댓글 남기기