-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathLogEcs.js
More file actions
111 lines (101 loc) · 2.99 KB
/
LogEcs.js
File metadata and controls
111 lines (101 loc) · 2.99 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
import { Log, stringify } from '../node.js'
import { ecsSerializers } from './serializers.js'
import { wrapConsole } from '../wrapConsole.js'
import { wrapDebug } from '../wrapDebug.js'
/** @typedef {import('../serializers/index.js').Serializer} Serializer */
/** @typedef {import('../node.js').LogOptions & {serializers: Record<string, Serializer>}} LogOptionsEcs */
/** @typedef {import('../node.js').LogOptionWrapConsole} LogOptionWrapConsole */
/**
* Elastic Common Schema (ECS) compatible logger;
* See [field reference](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html)
*
* Default serializers apply to `err` (error), `req` (request) and `res`
* (response) keys in objects
*/
export class LogEcs extends Log {
/**
* @param {string} name logger namespace
* @param {LogOptionsEcs} [opts]
*/
constructor(name, opts) {
const { serializers, ..._opts } = opts || {}
super(name, {
..._opts,
timestamp: 'iso'
})
this.serializers = { ...ecsSerializers, ...serializers }
const [extra] = name.split(':')
this._extraName = extra
this.toJson = this._toJson
}
/**
* @param {string} [name]
* @param {LogOptionsEcs & LogOptionWrapConsole} [opts]
* @returns {() => void} unwrap function
*/
static wrapConsole(name = 'console', opts) {
const log = new LogEcs(name, opts)
return wrapConsole(log, opts)
}
/**
* @param {LogOptionsEcs} [opts]
* @returns {() => void} unwrap function
*/
static wrapDebug(opts) {
return wrapDebug(LogEcs, opts)
}
/* c8 ignore next 18 */
_applySerializers(obj) {
const ecsObj = {}
for (const key in obj) {
const value = obj[key]
if (
Object.prototype.hasOwnProperty.call(obj, key) &&
value !== undefined
) {
if (this.serializers && this.serializers[key]) {
this.serializers[key](value, ecsObj)
} else {
// add all other unknown fields to extra
const extra = this._extraName
ecsObj.extra = ecsObj.extra || { [extra]: {} }
ecsObj.extra[extra][key] = value
}
}
}
return ecsObj
}
_toJson(obj, serializers) {
const { level, time, name, msg, pid, hostname, diff, ...other } = obj
const ecsObj = {
log: {
level,
logger: name,
diff_ms: diff
},
message: msg,
'@timestamp': time,
process: pid ? { pid } : undefined,
host: hostname ? { hostname } : undefined
}
for (const key in other) {
const value = other[key]
if (
value === undefined ||
!Object.prototype.hasOwnProperty.call(other, key)
) {
continue
}
if (serializers[key]) {
serializers[key](value, ecsObj)
} else {
// add all other unknown fields to extra
const extra = this._extraName
ecsObj.extra = ecsObj.extra || { [extra]: {} }
ecsObj.extra[extra][key] = value
}
}
return stringify(ecsObj)
}
}
LogEcs.serializers = ecsSerializers