1 | 'use strict'
|
2 |
|
3 |
|
4 |
|
5 | const { EventEmitter } = require('events')
|
6 | const SonicBoom = require('sonic-boom')
|
7 | const flatstr = require('flatstr')
|
8 | const {
|
9 | lsCacheSym,
|
10 | levelValSym,
|
11 | setLevelSym,
|
12 | getLevelSym,
|
13 | chindingsSym,
|
14 | mixinSym,
|
15 | asJsonSym,
|
16 | writeSym,
|
17 | timeSym,
|
18 | timeSliceIndexSym,
|
19 | streamSym,
|
20 | serializersSym,
|
21 | formattersSym,
|
22 | useOnlyCustomLevelsSym,
|
23 | needsMetadataGsym
|
24 | } = require('./symbols')
|
25 | const {
|
26 | getLevel,
|
27 | setLevel,
|
28 | isLevelEnabled,
|
29 | mappings,
|
30 | initialLsCache,
|
31 | genLsCache,
|
32 | assertNoLevelCollisions
|
33 | } = require('./levels')
|
34 | const {
|
35 | asChindings,
|
36 | asJson,
|
37 | buildFormatters
|
38 | } = require('./tools')
|
39 | const {
|
40 | version
|
41 | } = require('./meta')
|
42 |
|
43 |
|
44 |
|
45 | const constructor = class Pino {}
|
46 | const prototype = {
|
47 | constructor,
|
48 | child,
|
49 | bindings,
|
50 | setBindings,
|
51 | flush,
|
52 | isLevelEnabled,
|
53 | version,
|
54 | get level () { return this[getLevelSym]() },
|
55 | set level (lvl) { return this[setLevelSym](lvl) },
|
56 | get levelVal () { return this[levelValSym] },
|
57 | set levelVal (n) { throw Error('levelVal is read-only') },
|
58 | [lsCacheSym]: initialLsCache,
|
59 | [writeSym]: write,
|
60 | [asJsonSym]: asJson,
|
61 | [getLevelSym]: getLevel,
|
62 | [setLevelSym]: setLevel
|
63 | }
|
64 |
|
65 | Object.setPrototypeOf(prototype, EventEmitter.prototype)
|
66 |
|
67 | module.exports = prototype
|
68 |
|
69 | const resetChildingsFormatter = bindings => bindings
|
70 | function child (bindings) {
|
71 | if (!bindings) {
|
72 | throw Error('missing bindings for child Pino')
|
73 | }
|
74 | const serializers = this[serializersSym]
|
75 | const formatters = this[formattersSym]
|
76 | const instance = Object.create(this)
|
77 | if (bindings.hasOwnProperty('serializers') === true) {
|
78 | instance[serializersSym] = Object.create(null)
|
79 |
|
80 | for (var k in serializers) {
|
81 | instance[serializersSym][k] = serializers[k]
|
82 | }
|
83 | const parentSymbols = Object.getOwnPropertySymbols(serializers)
|
84 | for (var i = 0; i < parentSymbols.length; i++) {
|
85 | const ks = parentSymbols[i]
|
86 | instance[serializersSym][ks] = serializers[ks]
|
87 | }
|
88 |
|
89 | for (var bk in bindings.serializers) {
|
90 | instance[serializersSym][bk] = bindings.serializers[bk]
|
91 | }
|
92 | const bindingsSymbols = Object.getOwnPropertySymbols(bindings.serializers)
|
93 | for (var bi = 0; bi < bindingsSymbols.length; bi++) {
|
94 | const bks = bindingsSymbols[bi]
|
95 | instance[serializersSym][bks] = bindings.serializers[bks]
|
96 | }
|
97 | } else instance[serializersSym] = serializers
|
98 | if (bindings.hasOwnProperty('formatters')) {
|
99 | const { level, bindings: chindings, log } = bindings.formatters
|
100 | instance[formattersSym] = buildFormatters(
|
101 | level || formatters.level,
|
102 | chindings || resetChildingsFormatter,
|
103 | log || formatters.log
|
104 | )
|
105 | } else {
|
106 | instance[formattersSym] = buildFormatters(
|
107 | formatters.level,
|
108 | resetChildingsFormatter,
|
109 | formatters.log
|
110 | )
|
111 | }
|
112 | if (bindings.hasOwnProperty('customLevels') === true) {
|
113 | assertNoLevelCollisions(this.levels, bindings.customLevels)
|
114 | instance.levels = mappings(bindings.customLevels, instance[useOnlyCustomLevelsSym])
|
115 | genLsCache(instance)
|
116 | }
|
117 | instance[chindingsSym] = asChindings(instance, bindings)
|
118 | const childLevel = bindings.level || this.level
|
119 | instance[setLevelSym](childLevel)
|
120 |
|
121 | return instance
|
122 | }
|
123 |
|
124 | function bindings () {
|
125 | const chindings = this[chindingsSym]
|
126 | var chindingsJson = `{${chindings.substr(1)}}`
|
127 | var bindingsFromJson = JSON.parse(chindingsJson)
|
128 | delete bindingsFromJson.pid
|
129 | delete bindingsFromJson.hostname
|
130 | return bindingsFromJson
|
131 | }
|
132 |
|
133 | function setBindings (newBindings) {
|
134 | const chindings = asChindings(this, newBindings)
|
135 | this[chindingsSym] = chindings
|
136 | }
|
137 |
|
138 | function write (_obj, msg, num) {
|
139 | const t = this[timeSym]()
|
140 | const mixin = this[mixinSym]
|
141 | const objError = _obj instanceof Error
|
142 | var obj
|
143 |
|
144 | if (_obj === undefined || _obj === null) {
|
145 | obj = mixin ? mixin() : {}
|
146 | } else {
|
147 | obj = Object.assign(mixin ? mixin() : {}, _obj)
|
148 | if (!msg && objError) {
|
149 | msg = _obj.message
|
150 | }
|
151 |
|
152 | if (objError) {
|
153 | obj.stack = _obj.stack
|
154 | if (!obj.type) {
|
155 | obj.type = 'Error'
|
156 | }
|
157 | }
|
158 | }
|
159 |
|
160 | const s = this[asJsonSym](obj, msg, num, t)
|
161 |
|
162 | const stream = this[streamSym]
|
163 | if (stream[needsMetadataGsym] === true) {
|
164 | stream.lastLevel = num
|
165 | stream.lastObj = obj
|
166 | stream.lastTime = t.slice(this[timeSliceIndexSym])
|
167 | stream.lastLogger = this
|
168 | }
|
169 | if (stream instanceof SonicBoom) stream.write(s)
|
170 | else stream.write(flatstr(s))
|
171 | }
|
172 |
|
173 | function flush () {
|
174 | const stream = this[streamSym]
|
175 | if ('flush' in stream) stream.flush()
|
176 | }
|