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