nodejs 日誌模塊 winston 的使用

winston 日誌模塊

在使用 nodejs winston 模塊中,加上相關的兩個模塊,事倍功半。css

  • express-winston
  • winston-daily-rotate-file

express-winston

是 express-winston 的 winston 的增長版, 是做爲 express 的中間件來打印日誌,不只有請求頭信息,而且有響應時間。
做爲中間件, 爲何會有響應時間呢? 由於 express-winston 改寫了 express 的 res.end 辦法, 是請求結束後再打的日誌。node

代碼片斷

var end = res.end;
res.end = function(chunk, encoding) {
    res.responseTime = (new Date) - req._startTime;
    res.end = end;
    res.end(chunk, encoding);
    ...
    }

express-winston 沒有修改或者擴展 winston 的transport, 而 winston-daily-rotate-file 正是加強了 winston 的transport 辦法express

winston-daily-rotate-file

winston-daily-rotate-file 是 winston 擴展, 增長了 transport 的辦法,使 winston 有滾動日誌的能力。api

結合使用

咱們來一個需求: 如何讓 express-winston 打印日誌的時候,也打印出接口 /api 的請求參數和響應數據?app

  • 該日誌中間件應該在調用鏈 api 後面, api/* 業務處理以前。 like: app.use('/api', apiRequestLogger, apiHandler)
  • 要獲取到響應數據, 就要在業務處理完後 send 出來後才能捕獲到,express 全部的請求響應最後都是走 res.send 咱們能夠從這裏入手捕獲響應數據

代碼以下ide

import winston from 'winston'
import expressWinston from 'express-winston'
import 'winston-daily-rotate-file'
import path from 'path'

export let DailyRotateFileTransport = (fileName) => {
  return new (winston.transports.DailyRotateFile)({
    filename: path.join(process.env.LOGPATH, `${fileName}-%DATE%.log`),
    datePattern: 'YYYY-MM-DD-HH',
    // maxSize: '20m',
    maxFiles: '7d',
    timestamp: () => new Date().format('yyyy-MM-dd hh:mm:ss.S')
  })
}

export let pageRequestLogger = expressWinston.logger({
  transports: [
    DailyRotateFileTransport('page-request')
  ],
  meta: true, // optional: control whether you want to log the meta data about the request (default to true)
  msg: 'HTTP {{req.method}} {{req.url}}', // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}"
  expressFormat: true, // Use the default Express/morgan request formatting. Enabling this will override any msg if true. Will only output colors with colorize set to true
  colorize: false, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red).
  ignoreRoute: function (req, res) {
    // 只打印頁面請求信息
    let notPageRequest = false
    let ignoreArr = ['/api', '.js', '.css', '.png', '.jpg', '.gif']
    ignoreArr.forEach(item => {
      if (req.url.indexOf(item) > -1) notPageRequest = true
    })
    return notPageRequest
  } // optional: allows to skip some log messages based on request and/or response
})

export let apiRequestLogger = (req, res, next) => {
  let send = res.send
  let content = ''
  let query = req.query || {}
  let body = req.body || {}
  res.send = function () {
    content = arguments[0]
    send.apply(res, arguments)
  }
  expressWinston.logger({
    transports: [
      DailyRotateFileTransport('api-request')
    ],
    meta: true, // optional: control whether you want to log the meta data about the request (default to true)
    msg () {
      return `HTTP ${req.method} ${req.url} query ${JSON.stringify(query)} body ${JSON.stringify(body)} resData ${content} `
    },
    colorize: true, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red).
    ignoreRoute: function (req, res) {
      if (req.headers.self) return true
      return false
    } // optional: allows to skip some log messages based on request and/or response
  })(req, res, next)
}
相關文章
相關標籤/搜索