從零開始的Koa實戰(3) 日誌
日誌讓我們能夠監控應用的執行狀態、問題排查等。
經過上一節的實戰,我們已經有了下面的目錄結構:
koa-blog ├── package.json ├── app.js ├── app │├── router │|├── homde.js │|└── index.js │└── view │├── 404.html │└── index.html └── config └── config.js
安裝
我們使用log4js-node 來記錄日誌:
npm install log4js --save
設定
我們來修改config.js
,對 log4js 進行一些設定:
// config.js const CONFIG = { "API_PREFIX": "/api", // 配置了路由字首 "LOG_CONFIG": { "appenders": { error: { "category": "errorLogger", //logger名稱 "type": "dateFile", //日誌型別 "filename": 'logs/error/error', //日誌輸出位置 "alwaysIncludePattern": true, //是否總是有後綴名 "pattern": "-yyyy-MM-dd-hh.log" //字尾,每小時建立一個新的日誌檔案 }, response: { "category": "resLogger", "type": "dateFile", "filename": 'logs/response/response', "alwaysIncludePattern": true, "pattern": "-yyyy-MM-dd-hh.log" } }, "categories": { error: { appenders: ['error'], level: 'error' }, response: { appenders: ['response'], level: 'info' }, default: { appenders: ['response'], level: 'info' } } } }; module.exports = CONFIG;
日誌格式
為了使請求產生的 log 方便檢視,我們新增一個檔案來處理格式統一:
// app/util/log_format.js const log4js = require('log4js'); const { LOG_CONFIG } = require('../../config/config'); //載入配置檔案 log4js.configure(LOG_CONFIG); let logFormat = {}; let errorLogger = log4js.getLogger('error'); // categories的元素 let resLogger = log4js.getLogger('response'); //封裝錯誤日誌 logFormat.error = (ctx, error, resTime) => { if (ctx && error) { errorLogger.error(formatError(ctx, error, resTime)); } }; //封裝響應日誌 logFormat.response = (ctx, resTime) => { if (ctx) { resLogger.info(formatRes(ctx, resTime)); } }; //格式化響應日誌 const formatRes = (ctx, resTime) => { let responserLog = formatReqLog(ctx.request, resTime); // 新增請求日誌 responserLog.push(`response status: ${ctx.status}`); // 響應狀態碼 responserLog.push(`response body: \n${JSON.stringify(ctx.body)}`); // 響應內容 responserLog.push(`------------------------ end\n`); // 響應日誌結束 return responserLog.join("\n"); }; //格式化錯誤日誌 const formatError = (ctx, err, resTime) => { let errorLog = formatReqLog(ctx.request, resTime); // 新增請求日誌 errorLog.push(`err name: ${err.name}`); // 錯誤名稱 errorLog.push(`err message: ${err.message}`); // 錯誤資訊 errorLog.push(`err stack: ${err.stack}`); // 錯誤詳情 errorLog.push(`------------------------ end\n`); // 錯誤資訊結束 return errorLog.join("\n"); }; // 格式化請求日誌 const formatReqLog = (req, resTime) => { let method = req.method; // 訪問方法 請求原始地址 客戶端ip let formatLog = [`\n------------------------ ${method} ${req.originalUrl}`, `request client ip: ${req.ip}`]; if (method === 'GET') { // 請求引數 formatLog.push(`request query: ${JSON.stringify(req.query)}\n`) } else { formatLog.push(`request body: ${JSON.stringify(req.body)}\n`) } formatLog.push(`response time: ${resTime}`); // 伺服器響應時間 return formatLog; }; module.exports = logFormat;
logger 中介軟體
有了 log4js 的配置和統一格式之後,我們需要將它們都做進一箇中間件中,下面來建立一箇中間件logger
:
// app/middleware/logger.js const logFormat = require('../util/log_format'); const logger = () => { return async (ctx, next) => { const start = new Date(); //開始時間 let ms; //間隔時間 try { await next(); // 下一個中介軟體 ms = new Date() - start; logFormat.response(ctx, `${ms}ms`); //記錄響應日誌 } catch (error) { ms = new Date() - start; logFormat.error(ctx, error, `${ms}ms`); //記錄異常日誌 } } }; module.exports = logger;
中介軟體logger
已經建立好,下面來使用這個中介軟體:
// ... // 引入logger const logger = require('./app/middleware/logger'); // 使用模板引擎 app.use(koaNunjucks({ ext: 'html', path: path.join(__dirname, 'app/view'), nunjucksConfig: { trimBlocks: true // 開啟轉義 防止Xss } })); app.use(logger()); // 處理log的中介軟體 // ... app.listen(3000, () => { console.log('App started on http://localhost:3000/api') });
都設定好了之後,執行npm start
,當啟動成功之後,我們看到專案多了一個目錄logs
,裡面有兩個檔案,分別是報錯日誌和響應日誌。在瀏覽器中訪問http://localhost:3000/v1
,可以看到響應日誌裡面添加了剛剛的訪問記錄。
完成這一節實戰之後,整個檔案目錄如下:
koa-blog ├── package.json ├── app.js ├── app │├── middleware │|└── logger.js │├── router │|├── homde.js │|└── index.js │├── util │|└── log_format.js │└── view │├── 404.html │└── index.html ├── logs │├── error │└── response └── config └── config.js
當然,我們不需要將logs
目錄提交到 git 倉庫,我們可以在.gitignore
檔案中將其忽略。
下一步,我們來了解 MongoDB …