forked from tellnes/bunyan-middleware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
126 lines (108 loc) · 3.3 KB
/
index.js
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
var uuid = require('uuid').v1
module.exports = function (options, logger) {
options = options || {}
logger = logger || options.logger
if (!logger && options.constructor && options.constructor.name === 'Logger') {
logger = options
options = {}
}
if (!logger) {
throw new Error('`logger` is required')
}
var headerName = options.headerName || 'X-Request-Id'
, headerNameLower = headerName.toLowerCase()
, propertyName = options.propertyName || 'reqId'
, additionalRequestFinishData = options.additionalRequestFinishData
, logName = options.logName || 'req_id'
, obscureHeaders = options.obscureHeaders
, requestStart = options.requestStart || false
, verbose = options.verbose || false
, parentRequestSerializer = logger.serializers && logger.serializers.req
, level = options.level || 'info'
if (obscureHeaders && obscureHeaders.length) {
obscureHeaders = obscureHeaders.map(function (name) {
return name.toLowerCase()
})
} else {
obscureHeaders = false
}
function requestSerializer(req) {
var obj
if (parentRequestSerializer) {
obj = parentRequestSerializer(req)
} else {
obj =
{ method: req.method
, url: req.originalUrl || req.url
, headers: req.headers
, query: req.query
, remoteAddress: req.connection.remoteAddress
, remotePort: req.connection.remotePort
}
}
if (obscureHeaders && obj.headers) {
var headers = {}
Object.keys(obj.headers).forEach(function(name) {
headers[name] = obj.headers[name]
})
for (var i = 0; i < obscureHeaders.length; i++) {
headers[ obscureHeaders[i] ] = null
}
obj.headers = headers
}
return obj
}
logger = logger.child(
{ serializers:
{ req: requestSerializer
, res: logger.serializers && logger.serializers.res || logger.constructor.stdSerializers.res
}
}
)
return function (req, res, next) {
var id = req[propertyName]
|| req.headers[headerNameLower]
|| uuid()
var start = process.hrtime()
var prefs = {}
prefs[logName] = id
req.log = res.log = logger.child(prefs, true)
req[propertyName] = res[propertyName] = id
res.setHeader(headerName, id)
if (requestStart || verbose) {
var reqStartData = { req: req }
if (verbose) reqStartData.res = res
req.log[level](reqStartData, 'request start')
}
res.on('finish', function() {
var reqFinishData =
{ res: res
, duration: getDuration(start)
}
if (!requestStart || verbose) reqFinishData.req = req
if (additionalRequestFinishData) {
var additionReqFinishData = additionalRequestFinishData(req, res)
if (additionReqFinishData) {
Object.keys(additionReqFinishData).forEach(function(name) {
reqFinishData[name] = additionReqFinishData[name]
})
}
}
res.log[level](reqFinishData, 'request finish')
})
res.on('close', function () {
res.log.warn(
{ req: req
, res: res
, duration: getDuration(start)
}
, 'request socket closed'
)
})
next()
}
}
function getDuration(start) {
var diff = process.hrtime(start)
return diff[0] * 1e3 + diff[1] * 1e-6
}