@@ -16,6 +16,38 @@ const stdSerializers = {
16
16
err : asErrValue ,
17
17
errWithCause : asErrValue
18
18
}
19
+ function levelToValue ( level , logger ) {
20
+ return level === 'silent'
21
+ ? Infinity
22
+ : logger . levels . values [ level ]
23
+ }
24
+ const baseLogFunctionSymbol = Symbol ( 'pino.logFuncs' )
25
+ const hierarchySymbol = Symbol ( 'pino.hierarchy' )
26
+
27
+ const logFallbackMap = {
28
+ error : 'log' ,
29
+ fatal : 'error' ,
30
+ warn : 'error' ,
31
+ info : 'log' ,
32
+ debug : 'log' ,
33
+ trace : 'log'
34
+ }
35
+
36
+ function appendChildLogger ( parentLogger , childLogger ) {
37
+ const newEntry = {
38
+ logger : childLogger ,
39
+ parent : parentLogger [ hierarchySymbol ]
40
+ }
41
+ childLogger [ hierarchySymbol ] = newEntry
42
+ }
43
+
44
+ function setupBaseLogFunctions ( logger , levels , proto ) {
45
+ const logFunctions = { }
46
+ levels . forEach ( level => {
47
+ logFunctions [ level ] = proto [ level ] ? proto [ level ] : ( _console [ level ] || _console [ logFallbackMap [ level ] ?? 'log' ] || noop )
48
+ } )
49
+ logger [ baseLogFunctionSymbol ] = logFunctions
50
+ }
19
51
20
52
function shouldSerialize ( serialize , serializers ) {
21
53
if ( Array . isArray ( serialize ) ) {
@@ -61,6 +93,10 @@ function pino (opts) {
61
93
const logger = Object . create ( proto )
62
94
if ( ! logger . log ) logger . log = noop
63
95
96
+ setupBaseLogFunctions ( logger , levels , proto )
97
+ // setup root hierarchy entry
98
+ appendChildLogger ( { } , logger )
99
+
64
100
Object . defineProperty ( logger , 'levelVal' , {
65
101
get : getLevelVal
66
102
} )
@@ -94,9 +130,7 @@ function pino (opts) {
94
130
if ( transmit ) logger . _logEvent = createLogEventShape ( )
95
131
96
132
function getLevelVal ( ) {
97
- return this . level === 'silent'
98
- ? Infinity
99
- : this . levels . values [ this . level ]
133
+ return levelToValue ( this . level , this )
100
134
}
101
135
102
136
function getLevel ( ) {
@@ -108,15 +142,15 @@ function pino (opts) {
108
142
}
109
143
this . _level = level
110
144
111
- set ( setOpts , logger , 'error' , 'log ') // <-- must stay first
112
- set ( setOpts , logger , 'fatal' , 'error ')
113
- set ( setOpts , logger , 'warn' , 'error ')
114
- set ( setOpts , logger , 'info' , 'log ')
115
- set ( setOpts , logger , 'debug' , 'log ')
116
- set ( setOpts , logger , 'trace' , 'log ')
145
+ set ( this , setOpts , logger , 'error' ) // <-- must stay first
146
+ set ( this , setOpts , logger , 'fatal' )
147
+ set ( this , setOpts , logger , 'warn' )
148
+ set ( this , setOpts , logger , 'info' )
149
+ set ( this , setOpts , logger , 'debug' )
150
+ set ( this , setOpts , logger , 'trace' )
117
151
118
- customLevels . forEach ( function ( level ) {
119
- set ( setOpts , logger , level , 'log' )
152
+ customLevels . forEach ( ( level ) => {
153
+ set ( this , setOpts , logger , level )
120
154
} )
121
155
}
122
156
@@ -139,12 +173,10 @@ function pino (opts) {
139
173
}
140
174
function Child ( parent ) {
141
175
this . _childLevel = ( parent . _childLevel | 0 ) + 1
142
- this . error = bind ( parent , bindings , 'error' )
143
- this . fatal = bind ( parent , bindings , 'fatal' )
144
- this . warn = bind ( parent , bindings , 'warn' )
145
- this . info = bind ( parent , bindings , 'info' )
146
- this . debug = bind ( parent , bindings , 'debug' )
147
- this . trace = bind ( parent , bindings , 'trace' )
176
+
177
+ // make sure bindings are available in the `set` function
178
+ this . bindings = bindings
179
+
148
180
if ( childSerializers ) {
149
181
this . serializers = childSerializers
150
182
this . _serialize = childSerialize
@@ -156,7 +188,14 @@ function pino (opts) {
156
188
}
157
189
}
158
190
Child . prototype = this
159
- return new Child ( this )
191
+ const newLogger = new Child ( this )
192
+
193
+ // must happen before the level is assigned
194
+ appendChildLogger ( this , newLogger )
195
+ // required to actually initialize the logger functions for any given child
196
+ newLogger . level = this . level
197
+
198
+ return newLogger
160
199
}
161
200
return logger
162
201
}
@@ -203,19 +242,54 @@ pino.levels = {
203
242
pino . stdSerializers = stdSerializers
204
243
pino . stdTimeFunctions = Object . assign ( { } , { nullTime, epochTime, unixTime, isoTime } )
205
244
206
- function set ( opts , logger , level , fallback ) {
207
- const proto = Object . getPrototypeOf ( logger )
208
- logger [ level ] = logger . levelVal > logger . levels . values [ level ]
245
+ function getBindingChain ( logger ) {
246
+ const bindings = [ ]
247
+ if ( logger . bindings ) {
248
+ bindings . push ( logger . bindings )
249
+ }
250
+
251
+ // traverse up the tree to get all bindings
252
+ let hierarchy = logger [ hierarchySymbol ]
253
+ while ( hierarchy . parent ) {
254
+ hierarchy = hierarchy . parent
255
+ if ( hierarchy . logger . bindings ) {
256
+ bindings . push ( hierarchy . logger . bindings )
257
+ }
258
+ }
259
+
260
+ return bindings . reverse ( )
261
+ }
262
+
263
+ function set ( self , opts , rootLogger , level ) {
264
+ // override the current log functions with either `noop` or the base log function
265
+ self [ level ] = levelToValue ( self . level , rootLogger ) > levelToValue ( level , rootLogger )
209
266
? noop
210
- : ( proto [ level ] ? proto [ level ] : ( _console [ level ] || _console [ fallback ] || noop ) )
267
+ : rootLogger [ baseLogFunctionSymbol ] [ level ]
211
268
212
- wrap ( opts , logger , level )
269
+ if ( ! opts . transmit && self [ level ] === noop ) {
270
+ return
271
+ }
272
+
273
+ // make sure the log format is correct
274
+ self [ level ] = createWrap ( self , opts , rootLogger , level )
275
+
276
+ // prepend bindings if it is not the root logger
277
+ const bindings = getBindingChain ( self )
278
+ if ( bindings . length === 0 ) {
279
+ // early exit in case for rootLogger
280
+ return
281
+ }
282
+ self [ level ] = prependBindingsInArguments ( bindings , self [ level ] )
213
283
}
214
284
215
- function wrap ( opts , logger , level ) {
216
- if ( ! opts . transmit && logger [ level ] === noop ) return
285
+ function prependBindingsInArguments ( bindings , logFunc ) {
286
+ return function ( ) {
287
+ return logFunc . apply ( this , [ ...bindings , ...arguments ] )
288
+ }
289
+ }
217
290
218
- logger [ level ] = ( function ( write ) {
291
+ function createWrap ( self , opts , rootLogger , level ) {
292
+ return ( function ( write ) {
219
293
return function LOG ( ) {
220
294
const ts = opts . timestamp ( )
221
295
const args = new Array ( arguments . length )
@@ -229,22 +303,22 @@ function wrap (opts, logger, level) {
229
303
else write . apply ( proto , args )
230
304
231
305
if ( opts . transmit ) {
232
- const transmitLevel = opts . transmit . level || logger . level
233
- const transmitValue = logger . levels . values [ transmitLevel ]
234
- const methodValue = logger . levels . values [ level ]
306
+ const transmitLevel = opts . transmit . level || self . _level
307
+ const transmitValue = rootLogger . levels . values [ transmitLevel ]
308
+ const methodValue = rootLogger . levels . values [ level ]
235
309
if ( methodValue < transmitValue ) return
236
310
transmit ( this , {
237
311
ts,
238
312
methodLevel : level ,
239
313
methodValue,
240
314
transmitLevel,
241
- transmitValue : logger . levels . values [ opts . transmit . level || logger . level ] ,
315
+ transmitValue : rootLogger . levels . values [ opts . transmit . level || self . _level ] ,
242
316
send : opts . transmit . send ,
243
- val : logger . levelVal
317
+ val : levelToValue ( self . _level , rootLogger )
244
318
} , args )
245
319
}
246
320
}
247
- } ) ( logger [ level ] )
321
+ } ) ( self [ baseLogFunctionSymbol ] [ level ] )
248
322
}
249
323
250
324
function asObject ( logger , level , args , ts ) {
@@ -283,17 +357,6 @@ function applySerializers (args, serialize, serializers, stdErrSerialize) {
283
357
}
284
358
}
285
359
286
- function bind ( parent , bindings , level ) {
287
- return function ( ) {
288
- const args = new Array ( 1 + arguments . length )
289
- args [ 0 ] = bindings
290
- for ( var i = 1 ; i < args . length ; i ++ ) {
291
- args [ i ] = arguments [ i - 1 ]
292
- }
293
- return parent [ level ] . apply ( this , args )
294
- }
295
- }
296
-
297
360
function transmit ( logger , opts , args ) {
298
361
const send = opts . send
299
362
const ts = opts . ts
0 commit comments