koa2學習筆記02 - 給koa2添加系統日志 —— node日志管理模塊log4js


前言

沒有日志系統的后台應用是沒有靈魂的,
平時工作中每次我們遇到接口報錯的時候,
都會叫后台的童鞋看下怎么回事,
這時后台的童鞋都會不慌不忙的打開一個騷騷的黑窗口。
一串噼里啪啦的命令輸進去,
哐哐哐,一堆報錯信息出現了... 不明覺厲~
so, 我們今天也為我們的應用加上日志系統。

正文

node中寫日志一般都用 log4js 具體不詳細介紹
請移步 https://www.npmjs.com/package/log4js
廢話不多說直接上代碼

1.1 安裝log4js

npm install --save log4js

1.2 增加配置文件

根目錄下新建config目錄 conifg目錄下全為配置文件
config目錄下 新建文件 logs.js

var path = require('path');

//日志根目錄
var baseLogPath = path.resolve(__dirname, '../logs')

/*報錯輸出日志*/
//錯誤日志目錄、文件名、輸出完整路徑
var errorPath = "/error";
var errorFileName = "error";
var errorLogPath = baseLogPath + errorPath + "/" + errorFileName;

/*請求數據得到響應時輸出響應日志*/
//響應日志目錄、文件名、輸出完整路徑
var responsePath = "/response";
var responseFileName = "response";
var responseLogPath = baseLogPath + responsePath + "/" + responseFileName;

/*操作數據庫進行增刪改等敏感操作記錄日志*/
//操作日志目錄、文件名、輸出完整路徑
var handlePath = "/handle";
var handleFileName = "handle";
var handleLogPath = baseLogPath + handlePath + "/" + handleFileName;


module.exports = {
    //日志格式等設置
    appenders:
        {
            "rule-console": {"type": "console"},
            "errorLogger": {
                "type": "dateFile",
                "filename": errorLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": errorPath
            },
            "resLogger": {
                "type": "dateFile",
                "filename": responseLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": responsePath
            },
            "handleLogger": {
                "type": "dateFile",
                "filename": handleLogPath,
                "pattern": "-yyyy-MM-dd-hh.log",
                "alwaysIncludePattern": true,
                "encoding": "utf-8",
                "maxLogSize": 1000,
                "numBackups": 3,
                "path": responsePath
            },
        },
    //供外部調用的名稱和對應設置定義
    categories: {
        "default": {"appenders": ["rule-console"], "level": "all"},
        "resLogger": {"appenders": ["resLogger"], "level": "info"},
        "errorLogger": {"appenders": ["errorLogger"], "level": "error"},
        "handleLogger": {"appenders": ["handleLogger"], "level": "all"},
        "http": {"appenders": ["resLogger"], "level": "info"}
    },
    "baseLogPath": baseLogPath
}

1.3 增加工具方法

新建 utils 目錄, utils 目錄下放置工具類方法
utils 下新建 logs.js 放置輸出日志的工具方法

var log4js = require('log4js');
var logsConfig = require('../config/logs.js');
//加載配置文件
log4js.configure(logsConfig);
//調用預先定義的日志名稱
var resLogger = log4js.getLogger("resLogger");
var errorLogger = log4js.getLogger("errorLogger");
var handleLogger = log4js.getLogger("handleLogger");
var consoleLogger = log4js.getLogger();

// 格式化日志文本 加上日志頭尾和換行方便查看 ==>  普通日志、請求日志、響應日志、操作日志、錯誤日志
var formatText = {
    info: function(info) {
        var logText = new String();
        //響應日志頭信息
        logText += "\n" + "***************info log start ***************" + "\n";
        //響應內容
        logText += "info detail: " + "\n" + JSON.stringify(info) + "\n";
        //響應日志結束信息
        logText += "*************** info log end ***************" + "\n";
        return logText;
    },
    request: function(req, resTime) {
        var logText = new String();
        var method = req.method;
        //訪問方法
        logText += "request method: " + method + "\n";
        //請求原始地址
        logText += "request originalUrl:  " + req.originalUrl + "\n";
        //客戶端ip
        logText += "request client ip:  " + req.ip + "\n";
        //開始時間
        var startTime;
        //請求參數
        if (method === 'GET') {
            logText += "request query:  " + JSON.stringify(req.query) + "\n";
            // startTime = req.query.requestStartTime;
        } else {
            logText += "request body: " + "\n" + JSON.stringify(req.body) + "\n";
            // startTime = req.body.requestStartTime;
        }
        //服務器響應時間
        logText += "response time: " + resTime + "\n";
        return logText;
    },
    response: function(ctx, resTime) {
        var logText = new String();
        //響應日志開始
        logText += "\n" + "*************** response log start ***************" + "\n";
        //添加請求日志
        logText += formatText.request(ctx.request, resTime);
        //響應狀態碼
        logText += "response status: " + ctx.status + "\n";
        //響應內容
        logText += "response body: " + "\n" + JSON.stringify(ctx.body) + "\n";
        //響應日志結束
        logText += "*************** response log end ***************" + "\n";
        return logText;
    },
    handle: function(info) {
        var logText = new String();
        //響應日志開始
        logText += "\n" + "***************info log start ***************" + "\n";
        //響應內容
        logText += "handle info detail: " + "\n" + JSON.stringify(info).replace(/\\n/g, "\n") + "\n";
        //響應日志結束
        logText += "*************** info log end ***************" + "\n";
        return logText;
    },
    error: function(ctx, err, resTime) {
        var logText = new String();
        //錯誤信息開始
        logText += "\n" + "*************** error log start ***************" + "\n";
        //添加請求日志
        logText += formatText.request(ctx.request, resTime);
        //錯誤名稱
        logText += "err name: " + err.name + "\n";
        //錯誤信息
        logText += "err message: " + err.message + "\n";
        //錯誤詳情
        logText += "err stack: " + err.stack + "\n";
        //錯誤信息結束
        logText += "*************** error log end ***************" + "\n";
        return logText;
    }
}

module.exports = {
    //封裝普通日志
    logInfo: function(info) {
        if (info) {
            consoleLogger.info(formatText.info(info));
        }
    },
    //封裝響應日志
    logResponse: function(ctx, resTime) {
        if (ctx) {
            resLogger.info(formatText.response(ctx, resTime));
        }
    },
    //封裝操作日志
    logHandle: function(res) {
        if (res) {
            handleLogger.info(formatText.handle(res));
        }
    },
    //封裝錯誤日志
    logError: function(ctx, error, resTime) {
        if (ctx && error) {
            errorLogger.error(formatText.error(ctx, error, resTime));
        }
    }
};

1.4 改造app.js

// logger
const logsUtil = require('./utils/logs.js');
app.use(async (ctx, next) => {
    const start = new Date();					          // 響應開始時間
    let intervals;								              // 響應間隔時間
    try {
        await next();
        intervals = new Date() - start;
        logsUtil.logResponse(ctx, intervals);	  //記錄響應日志
    } catch (error) {
        intervals = new Date() - start;
        logsUtil.logError(ctx, error, intervals);//記錄異常日志
    }
})

如圖: 在這里插入圖片描述

1.5 運行、使用日志系統

大工告成, 運行一下項目吧, 看是否自動在根目錄下創建了一個logs目錄。 如下
在這里插入圖片描述
目前我們現在只記錄的響應日志和 錯誤日志。
下面演示一下 如何打印操作日志。

我們打開 routes 文件夾。 然后打開 index.js 如圖所示。
在這里插入圖片描述
假裝我們做了這些操作。 訪問 http://localhost:3000/json
看一下日志文件夾和控制台是否和下面一樣?

在這里插入圖片描述
在這里插入圖片描述
這就是我們在utils中寫的四個輸出日志的方法。
如果覺得不夠用還可以仿照格式繼續寫其他方法。

ps: .gitignore中已設置忽略上傳logs文件夾,git中不可見。

作者 HoChine
2019 年 04月 03日
GitHub地址:https://github.com/HoChine/Koa2-demo/tree/02


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM