在使用 nodejs winston 模块中,加上相关的两个模块,事倍功半。 日志模块

winston 日志模块

在使用 nodejs winston 模块中,加上相关的两个模块,事倍功半。

  1. express-winston
  2. winston-daily-rotate-file

express-winston

是 express-winston 的 winston 的增加版, 是作为 express 的中间件来打印日志,不仅有请求头信息,并且有响应时间。
作为中间件, 为什么会有响应时间呢? 因为 express-winston 改写了 express 的 res.end 办法, 是请求结束后再打的日志。

代码片段

?

1

2

3

4

5

6

7

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 办法

winston-daily-rotate-file

winston-daily-rotate-file 是 winston 扩展, 增加了 transport 的办法,使 winston 有滚动日志的能力。

结合使用

我们来一个需求: 如何让 express-winston 打印日志的时候,也打印出接口 /api 的请求参数和响应数据?

  1. 该日志中间件应该在调用链 api 后面, api/* 业务处理之前。 like: app.use('/api', apiRequestLogger, apiHandler)
  2. 要获取到响应数据, 就要在业务处理完后 send 出来后才能捕获到,express 所有的请求响应最后都是走 res.send 我们可以从这里入手捕获响应数据

代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

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)

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

发布了363 篇原创文章 · 获赞 32 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/gwdgwd123/article/details/104370678
今日推荐