-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
157 lines (140 loc) · 4.14 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* eslint no-use-before-define: ["error", "nofunc"] */
// @ts-check
const bunyan = require('bunyan')
const bunyanFormat = require('bunyan-format')
/* Print to console */
function onWrite(c) {
if (c[c.length - 1] === '\n') {
// eslint-disable-next-line no-console
console.log(c.substr(0, c.length - 1))
} else {
// eslint-disable-next-line no-console
console.log(c)
}
}
function sanitize(val) {
const mask = ['api_key', 'apikey', 'key', 'password', 'pwd']
if (val && typeof val === 'object') {
const rval = {}
for (const key of Object.keys(val)) {
if (Object.prototype.hasOwnProperty.call(val, key)) {
if (mask.includes(key.toLowerCase())) {
rval[key] = '*******'
} else {
rval[key] = val[key]
}
}
}
return rval
}
if (val && typeof val === 'string') {
let arr = []
arr = val
.split(',')
.filter(v => v.trim())
.map(v => {
if (v.includes('=')) {
const [p, pv] = v.split('=')
if (mask.includes(p.toLowerCase())) {
return `${p}=********`
}
return `${p}=${pv}`
}
return v
})
return JSON.stringify(arr)
}
return val
}
// Serialize an HTTP request.
function reqSerializer(req) {
if (!req || !req.connection) return {}
const rval = {
method: req.method,
url: req.originalUrl || req.url,
accept: req.header('Accept'),
guid: req.header('Request-Guid'),
agent: req.header('User-Agent'),
hostname: req.hostname,
referer: req.header('Referer'),
path: req.path,
protocol: req.protocol,
secure: req.secure,
params: sanitize(req.params),
query: sanitize(req.query),
remoteAddress: req.connection.remoteAddress,
remotePort: req.connection.remotePort,
}
return rval
}
// Serialize an HTTP response.
function resSerializer(res) {
if (!res || !res.statusCode) return {}
const rval = {
statusCode: res.statusCode,
}
return rval
}
const defaults = {
name: 'node-log',
env: process.env.NODE_ENV,
level: bunyan.INFO,
// Using
// https://github.com/trentm/node-bunyan#recommendedbest-practice-fields
serializers: { err: bunyan.stdSerializers.err, req: reqSerializer, res: resSerializer },
}
function initLogger(inpOptions) {
const options = { ...defaults, ...inpOptions }
const loggerOptions = {
name: options.name,
level: options.level,
serializers: options.serializers,
}
if (options.env === undefined || options.env === 'development' || options.env === 'test') {
// Write to std out when not in production mode
// @ts-ignore
loggerOptions.stream = bunyanFormat({ outputMode: 'short' }, { write: options.onWrite || onWrite })
}
const logger = bunyan.createLogger(loggerOptions)
// Mutating module.exports to maintian compatibility with old apps
;['debug', 'info', 'warn', 'trace', 'fatal', 'error', 'child'].forEach(key => {
module.exports[key] = logger[key].bind(logger)
})
module.exports.init = () => logger.info("kth-node-log already initialized, won't do it again")
}
/**
* Bunyan logger wrapper
* @type {{init:Function,child:Function,trace:Function,debug:Function,info:Function,warn:Function,error:Function,fatal:Function}}
*/
module.exports = {
init: initLogger,
debug: _showMessageAboutMissingInit,
info: _showMessageAboutMissingInit,
warn: _showMessageAboutMissingInit,
trace: _showMessageAboutMissingInit,
fatal: _showMessageAboutMissingInit,
error: _showMessageAboutMissingInit,
child: () => ({
init: initLogger,
debug: _showMessageAboutMissingInit,
info: _showMessageAboutMissingInit,
warn: _showMessageAboutMissingInit,
trace: _showMessageAboutMissingInit,
fatal: _showMessageAboutMissingInit,
error: _showMessageAboutMissingInit,
}),
}
const Global = {
messageShown: false,
}
function _showMessageAboutMissingInit() {
if (Global.messageShown) {
return
}
// eslint-disable-next-line no-console
console.warn(
'You are using package "@kth/log" before/without init(). ' +
'This might be fine in test environments but is most likely unwanted when running your application.'
)
Global.messageShown = true
}