You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					96 lines
				
				2.8 KiB
			
		
		
			
		
	
	
					96 lines
				
				2.8 KiB
			| 
											3 years ago
										 | # Child loggers
 | ||
|  | 
 | ||
|  | Let's assume we want to have `"module":"foo"` added to every log within a | ||
|  | module `foo.js`. | ||
|  | 
 | ||
|  | To accomplish this, simply use a child logger: | ||
|  | 
 | ||
|  | ```js | ||
|  | 'use strict' | ||
|  | // imports a pino logger instance of `require('pino')()` | ||
|  | const parentLogger = require('./lib/logger') | ||
|  | const log = parentLogger.child({module: 'foo'}) | ||
|  | 
 | ||
|  | function doSomething () { | ||
|  |   log.info('doSomething invoked') | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = { | ||
|  |   doSomething | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Cost of child logging
 | ||
|  | 
 | ||
|  | Child logger creation is fast: | ||
|  | 
 | ||
|  | ``` | ||
|  | benchBunyanCreation*10000: 564.514ms | ||
|  | benchBoleCreation*10000: 283.276ms | ||
|  | benchPinoCreation*10000: 258.745ms | ||
|  | benchPinoExtremeCreation*10000: 150.506ms | ||
|  | ``` | ||
|  | 
 | ||
|  | Logging through a child logger has little performance penalty: | ||
|  | 
 | ||
|  | ``` | ||
|  | benchBunyanChild*10000: 556.275ms | ||
|  | benchBoleChild*10000: 288.124ms | ||
|  | benchPinoChild*10000: 231.695ms | ||
|  | benchPinoExtremeChild*10000: 122.117ms | ||
|  | ``` | ||
|  | 
 | ||
|  | Logging via the child logger of a child logger also has negligible overhead: | ||
|  | 
 | ||
|  | ``` | ||
|  | benchBunyanChildChild*10000: 559.082ms | ||
|  | benchPinoChildChild*10000: 229.264ms | ||
|  | benchPinoExtremeChildChild*10000: 127.753ms | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Duplicate keys caveat
 | ||
|  | 
 | ||
|  | It's possible for naming conflicts to arise between child loggers and | ||
|  | children of child loggers. | ||
|  | 
 | ||
|  | This isn't as bad as it sounds, even if the same keys between | ||
|  | parent and child loggers are used, Pino resolves the conflict in the sanest way. | ||
|  | 
 | ||
|  | For example, consider the following: | ||
|  | 
 | ||
|  | ```js | ||
|  | const pino = require('pino') | ||
|  | pino(pino.destination('./my-log')) | ||
|  |   .child({a: 'property'}) | ||
|  |   .child({a: 'prop'}) | ||
|  |   .info('howdy') | ||
|  | ``` | ||
|  | 
 | ||
|  | ```sh | ||
|  | $ cat my-log | ||
|  | {"pid":95469,"hostname":"MacBook-Pro-3.home","level":30,"msg":"howdy","time":1459534114473,"a":"property","a":"prop"} | ||
|  | ``` | ||
|  | 
 | ||
|  | Notice how there's two key's named `a` in the JSON output. The sub-childs properties | ||
|  | appear after the parent child properties. | ||
|  | 
 | ||
|  | At some point the logs will most likely be processed (for instance with a [transport](transports.md)), | ||
|  | and this generally involves parsing. `JSON.parse` will return an object where the conflicting | ||
|  | namespace holds the final value assigned to it: | ||
|  | 
 | ||
|  | ```sh | ||
|  | $ cat my-log | node -e "process.stdin.once('data', (line) => console.log(JSON.stringify(JSON.parse(line))))" | ||
|  | {"pid":95469,"hostname":"MacBook-Pro-3.home","level":30,"msg":"howdy","time":"2016-04-01T18:08:34.473Z","a":"prop"} | ||
|  | ``` | ||
|  | 
 | ||
|  | Ultimately the conflict is resolved by taking the last value, which aligns with Bunyans child logging | ||
|  | behavior. | ||
|  | 
 | ||
|  | There may be cases where this edge case becomes problematic if a JSON parser with alternative behavior | ||
|  | is used to process the logs. It's recommended to be conscious of namespace conflicts with child loggers, | ||
|  | in light of an expected log processing approach. | ||
|  | 
 | ||
|  | One of Pino's performance tricks is to avoid building objects and stringifying | ||
|  | them, so we're building strings instead. This is why duplicate keys between | ||
|  | parents and children will end up in log output. |