代碼地址以下:
http://www.demodashi.com/demo/12466.htmlhtml
以前作的項目是採用 Express 框架進行搭建的,其中的日誌管理採用了 winston + Postgresql + sequelize的形式, 最近倒弄 Koa2 框架,因而就想着嘗試採用另外一種方式進行訪問日誌的管理,就想到了 log4js。關於 log4js 的介紹在這裏就很少敘述了,想了解請點擊 log4js詳細介紹node
說到數據持久化,最廣泛的無非就兩種方式:sql
本文將以log4js爲主線,分別對這兩種形式進行實現。mongodb
log4js 輸入日誌到文件有兩種形式:數據庫
直接上代碼:npm
// log4js.js const log4js = require('log4js') log4js.configure({ appenders: { error: { type: 'file', //日誌類型 category: 'errLogger', //日誌名稱 filename: __dirname + '/../logs/error.log/', //日誌輸出位置,當目錄文件或文件夾不存在時自動建立 maxLogSize: 104800, // 文件最大存儲空間 backups: 100 //當文件內容超過文件存儲空間時,備份文件的數量 }, response: { type: 'dateFile', category: 'resLogger', filename: __dirname + '/../logs/responses/', pattern: 'yyyy-MM-dd.log', //日誌輸出模式 alwaysIncludePattern: true, maxLogSize: 104800, backups: 100 } }, categories: { error: {appenders: ['error'], level: 'error'}, response: {appenders: ['response'], level: 'info'}, default: { appenders: ['response'], level: 'info'} }, replaceConsole: true })
日誌配置文件咱們已經完成,在這裏定義了兩種形式的日誌,分別是 errLogger 錯誤日誌, resLogger 響應日誌。
接下來咱們將這兩種日誌進行自定義格式化輸出:api
// log4js.js const {formatError, formatRes} = require('./formatLog') let logger = {} let errorLogger = log4js.getLogger('error') let resLogger = log4js.getLogger('response') // 封裝錯誤日誌 logger.errLogger = (ctx, error, resTime) => { if(ctx && error) { errorLogger.error(formatError(ctx, error, resTime)) } } // 封裝響應日誌 logger.resLogger = (ctx, resTime) => { if(ctx) { resLogger.info(formatRes(ctx, resTime)) } }
// formatLog.js let formatError = (ctx, err,costTime) => { let method = ctx.method let url = ctx.url let body = ctx.request.body let userAgent = ctx.header.userAgent return {method, url, body, costTime, err} } let formatRes = (ctx,costTime) => { let method = ctx.method let url = ctx.url let body = ctx.request.body let response = ctx.response return {method, url, body, costTime, response} } module.exports = {formatError, formatRes}
在咱們的應用中使用咱們自定義的日誌模型服務器
//app.js const log4js = require('./utils/log4js') // logger app.use(async(ctx, next) => { const start = new Date() await next() const ms = new Date() - start log4js.resLogger(ctx, ms) }) app.on('error', (err, ctx) => { log4js.errLogger(ctx, err) console.error('server error', err, ctx) });
此時咱們的訪問信息都已被輸出到了項目 logs 文件夾下面。app
咱們採用 Mongoose 驅動進行與 MongoDB 數據庫進行交互。關於 Mongoose 的使用請查看 Mongoose使用詳情框架
首先咱們先定義一個存放日誌的數據模型 Log,以下:
//log.js let log = new Schema({ level: {type: String}, message: {type: String}, info: { method: String, url: String, costTime: Number, body: String, response: { status: Number, message: String, header: String, body: String } } }, { versionKey: false }) module.exports = mongoose.model('logs', log)
日誌內容存儲到數據庫中,實現以下log2db.js
//log2db.js const {Log} = require('../models') let log2db = (msg, level, info) => { let log = { level: level || 'info', message: msg, info: { method: info.method, url: info.url, costTime: info.costTime, body: JSON.stringify(info.body), response: { status: info.response.status, message: info.response.message, header: JSON.stringify(info.response.header), body: JSON.stringify(info.response.body) } } } Log.create(log, (err, res) => { if(err) {console.log(err)} }) } module.exports = log2db
修改咱們上邊封裝的兩種日誌類型,添加 log2db 以下:
// 封裝錯誤日誌 logger.errLogger = (ctx, error, resTime) => { if(ctx && error) { log2db('ErrorRequest', 'error', formatError(ctx, error, resTime)) errorLogger.error(formatError(ctx, error, resTime)) } } // 封裝相應日誌 logger.resLogger = (ctx, resTime) => { if(ctx) { log2db('RequestInfo', 'info', formatRes(ctx, resTime)) resLogger.info(formatRes(ctx, resTime)) } }
OK, 咱們重啓服務器,進行訪問,而後經過 RoboMongo 進行查看咱們的 Log 集合,就會發現咱們的訪問信息都已經記錄了下來。
Koa2 + Mongoose + Log4js 持久化日誌
注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權