Koa2 + Mongoose + Log4js 持久化日誌

代碼地址以下:
http://www.demodashi.com/demo/12466.htmlhtml

 以前作的項目是採用 Express 框架進行搭建的,其中的日誌管理採用了 winston + Postgresql + sequelize的形式, 最近倒弄 Koa2 框架,因而就想着嘗試採用另外一種方式進行訪問日誌的管理,就想到了 log4js。關於 log4js 的介紹在這裏就很少敘述了,想了解請點擊  log4js詳細介紹node

 說到數據持久化,最廣泛的無非就兩種方式:sql

  • 文件存儲
  • 數據庫存儲

 本文將以log4js爲主線,分別對這兩種形式進行實現。mongodb

持久化至文件

 log4js 輸入日誌到文件有兩種形式:數據庫

  • file 輸出到文件, 指定單一文件名稱, 例如: default.log
  • dateFile 輸出到文件,文件能夠按日期模式滾動,例如: default-2017-02-03.log

直接上代碼: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

持久化到 MongoDB

咱們採用 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-mongo-logs

項目結構圖


Koa2 + Mongoose + Log4js 持久化日誌

代碼地址以下:
http://www.demodashi.com/demo/12466.html

注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權

相關文章
相關標籤/搜索