-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathindex.js
More file actions
130 lines (109 loc) · 3.1 KB
/
index.js
File metadata and controls
130 lines (109 loc) · 3.1 KB
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
'use strict'
const metadata = Symbol.for('pino.metadata')
const split = require('split2')
const { Duplex } = require('stream')
const { parentPort, workerData } = require('worker_threads')
function createDeferred () {
let resolve
let reject
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject
})
promise.resolve = resolve
promise.reject = reject
return promise
}
module.exports = function build (fn, opts = {}) {
const waitForConfig = opts.expectPinoConfig === true && workerData?.workerData?.pinoWillSendConfig === true
const parseLines = opts.parse === 'lines'
const parseLine = typeof opts.parseLine === 'function' ? opts.parseLine : JSON.parse
const close = opts.close || defaultClose
const timeKey = opts.timeKey || 'time'
const levelKey = opts.levelKey || 'level'
const stream = split(function (line) {
let value
try {
value = parseLine(line)
} catch (error) {
this.emit('unknown', line, error)
return
}
if (value === null) {
this.emit('unknown', line, 'Null value ignored')
return
}
if (typeof value !== 'object') {
value = {
data: value,
time: Date.now()
}
}
if (stream[metadata]) {
stream.lastTime = value[timeKey]
stream.lastLevel = value[levelKey]
stream.lastObj = value
}
if (parseLines) {
return line
}
return value
}, { autoDestroy: true })
stream._destroy = function (err, cb) {
const promise = close(err, cb)
if (promise && typeof promise.then === 'function') {
promise.then(cb, cb)
}
}
if (opts.expectPinoConfig === true && workerData?.workerData?.pinoWillSendConfig !== true) {
setImmediate(() => {
stream.emit('error', new Error('This transport is not compatible with the current version of pino. Please upgrade pino to the latest version.'))
})
}
if (opts.metadata !== false) {
stream[metadata] = true
stream.lastTime = 0
stream.lastLevel = 0
stream.lastObj = null
}
if (waitForConfig) {
let pinoConfig = {}
const configReceived = createDeferred()
parentPort.on('message', function handleMessage (message) {
if (message.code === 'PINO_CONFIG') {
pinoConfig = message.config
configReceived.resolve()
parentPort.off('message', handleMessage)
}
})
Object.defineProperties(stream, {
levels: {
get () { return pinoConfig.levels }
},
messageKey: {
get () { return pinoConfig.messageKey }
},
errorKey: {
get () { return pinoConfig.errorKey }
}
})
return configReceived.then(finish)
}
return finish()
function finish () {
let res = fn(stream)
if (res && typeof res.catch === 'function') {
res.catch((err) => {
stream.destroy(err)
})
// set it to null to not retain a reference to the promise
res = null
} else if (opts.enablePipelining && res) {
return Duplex.from({ writable: stream, readable: res })
}
return stream
}
}
function defaultClose (err, cb) {
process.nextTick(cb, err)
}