update
This commit is contained in:
		
							parent
							
								
									d9becc67b6
								
							
						
					
					
						commit
						9308795b8b
					
				
					 964 changed files with 104265 additions and 16 deletions
				
			
		
							
								
								
									
										24
									
								
								node_modules/pino/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								node_modules/pino/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2016-2019 Matteo Collina, David Mark Clements and the Pino contributors
 | 
			
		||||
 | 
			
		||||
Pino contributors listed at https://github.com/pinojs/pino#the-team and in
 | 
			
		||||
the README file.
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
							
								
								
									
										152
									
								
								node_modules/pino/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								node_modules/pino/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,152 @@
 | 
			
		|||

 | 
			
		||||
 | 
			
		||||
# pino  [](https://travis-ci.org/pinojs/pino) [](https://coveralls.io/github/pinojs/pino?branch=master) [](http://standardjs.com/) [](https://definitelytyped.org)
 | 
			
		||||
 | 
			
		||||
[Very low overhead](#low-overhead) Node.js logger, inspired by Bunyan.
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
* [Benchmarks ⇗](/docs/benchmarks.md)
 | 
			
		||||
* [API ⇗](/docs/api.md)
 | 
			
		||||
* [Browser API ⇗](/docs/browser.md)
 | 
			
		||||
* [Redaction ⇗](/docs/redaction.md)
 | 
			
		||||
* [Child Loggers ⇗](/docs/child-loggers.md)
 | 
			
		||||
* [Transports ⇗](/docs/transports.md)
 | 
			
		||||
* [Web Frameworks ⇗](/docs/web.md)
 | 
			
		||||
* [Pretty Printing ⇗](/docs/pretty.md)
 | 
			
		||||
* [Extreme Mode ⇗](/docs/extreme.md)
 | 
			
		||||
* [Ecosystem ⇗](/docs/ecosystem.md)
 | 
			
		||||
* [Legacy](/docs/legacy.md)
 | 
			
		||||
* [Help ⇗](/docs/help.md)
 | 
			
		||||
 | 
			
		||||
## Install
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ npm install pino
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')()
 | 
			
		||||
 | 
			
		||||
logger.info('hello world')
 | 
			
		||||
 | 
			
		||||
const child = logger.child({ a: 'property' })
 | 
			
		||||
child.info('hello child!')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This produces:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
{"level":30,"time":1531171074631,"msg":"hello world","pid":657,"hostname":"Davids-MBP-3.fritz.box","v":1}
 | 
			
		||||
{"level":30,"time":1531171082399,"msg":"hello child!","pid":657,"hostname":"Davids-MBP-3.fritz.box","a":"property","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For using Pino with a web framework see:
 | 
			
		||||
 | 
			
		||||
* [Pino with Fastify](docs/web.md#fastify)
 | 
			
		||||
* [Pino with Express](docs/web.md#express)
 | 
			
		||||
* [Pino with Hapi](docs/web.md#hapi)
 | 
			
		||||
* [Pino with Restify](docs/web.md#restify)
 | 
			
		||||
* [Pino with Koa](docs/web.md#koa)
 | 
			
		||||
* [Pino with Node core `http`](docs/web.md#http)
 | 
			
		||||
* [Pino with Nest](docs/web.md#nest)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<a name="essentials"></a>
 | 
			
		||||
## Essentials
 | 
			
		||||
 | 
			
		||||
### Development Formatting
 | 
			
		||||
 | 
			
		||||
The [`pino-pretty`](https://github.com/pinojs/pino-pretty) module can be used to
 | 
			
		||||
format logs during development:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
### Transports & Log Processing
 | 
			
		||||
 | 
			
		||||
Due to Node's single-threaded event-loop, it's highly recommended that sending,
 | 
			
		||||
alert triggering, reformatting and all forms of log processing
 | 
			
		||||
is conducted in a separate process. In Pino parlance we call all log processors
 | 
			
		||||
"transports", and recommend that the transports be run as separate
 | 
			
		||||
processes, piping the stdout of the application to the stdin of the transport.
 | 
			
		||||
 | 
			
		||||
For more details see our [Transports⇗](docs/transports.md) document.
 | 
			
		||||
 | 
			
		||||
### Low overhead
 | 
			
		||||
 | 
			
		||||
Using minimum resources for logging is very important. Log messages
 | 
			
		||||
tend to get added over time and this can lead to a throttling effect
 | 
			
		||||
on applications – such as reduced requests per second.
 | 
			
		||||
 | 
			
		||||
In many cases, Pino is over 5x faster than alternatives.
 | 
			
		||||
 | 
			
		||||
See the [Benchmarks](docs/benchmarks.md) document for comparisons.
 | 
			
		||||
 | 
			
		||||
<a name="team"></a>
 | 
			
		||||
## The Team
 | 
			
		||||
 | 
			
		||||
### Matteo Collina
 | 
			
		||||
 | 
			
		||||
<https://github.com/pinojs>
 | 
			
		||||
 | 
			
		||||
<https://www.npmjs.com/~matteo.collina>
 | 
			
		||||
 | 
			
		||||
<https://twitter.com/matteocollina>
 | 
			
		||||
 | 
			
		||||
### David Mark Clements
 | 
			
		||||
 | 
			
		||||
<https://github.com/davidmarkclements>
 | 
			
		||||
 | 
			
		||||
<https://www.npmjs.com/~davidmarkclements>
 | 
			
		||||
 | 
			
		||||
<https://twitter.com/davidmarkclem>
 | 
			
		||||
 | 
			
		||||
### James Sumners
 | 
			
		||||
 | 
			
		||||
<https://github.com/jsumners>
 | 
			
		||||
 | 
			
		||||
<https://www.npmjs.com/~jsumners>
 | 
			
		||||
 | 
			
		||||
<https://twitter.com/jsumners79>
 | 
			
		||||
 | 
			
		||||
### Thomas Watson Steen
 | 
			
		||||
 | 
			
		||||
<https://github.com/watson>
 | 
			
		||||
 | 
			
		||||
<https://www.npmjs.com/~watson>
 | 
			
		||||
 | 
			
		||||
<https://twitter.com/wa7son>
 | 
			
		||||
 | 
			
		||||
## Communication
 | 
			
		||||
 | 
			
		||||
### Chat on Gitter
 | 
			
		||||
 | 
			
		||||
<https://gitter.im/pinojs/pino>
 | 
			
		||||
 | 
			
		||||
### Chat on IRC
 | 
			
		||||
 | 
			
		||||
You'll find an active group of Pino users in the #pinojs channel on Freenode, including some of the contributors to this project.
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Pino is an **OPEN Open Source Project**. This means that:
 | 
			
		||||
 | 
			
		||||
> Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
 | 
			
		||||
 | 
			
		||||
See the [CONTRIBUTING.md](https://github.com/pinojs/pino/blob/master/CONTRIBUTING.md) file for more details.
 | 
			
		||||
 | 
			
		||||
<a name="acknowledgements"></a>
 | 
			
		||||
## Acknowledgements
 | 
			
		||||
 | 
			
		||||
This project was kindly sponsored by [nearForm](http://nearform.com).
 | 
			
		||||
 | 
			
		||||
Logo and identity designed by Cosmic Fox Design: https://www.behance.net/cosmicfox.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
Licensed under [MIT](./LICENSE).
 | 
			
		||||
 | 
			
		||||
[elasticsearch]: https://www.elastic.co/products/elasticsearch
 | 
			
		||||
[kibana]: https://www.elastic.co/products/kibana
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/bin.js
									
										
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/bin.js
									
										
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
#!/usr/bin/env node
 | 
			
		||||
console.error(
 | 
			
		||||
  '`pino` cli has been removed. Use `pino-pretty` cli instead.\n' +
 | 
			
		||||
  '\nSee: https://github.com/pinojs/pino-pretty'
 | 
			
		||||
)
 | 
			
		||||
process.exit(1)
 | 
			
		||||
							
								
								
									
										325
									
								
								node_modules/pino/browser.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								node_modules/pino/browser.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,325 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
var format = require('quick-format-unescaped')
 | 
			
		||||
 | 
			
		||||
module.exports = pino
 | 
			
		||||
 | 
			
		||||
var _console = pfGlobalThisOrFallback().console || {}
 | 
			
		||||
var stdSerializers = {
 | 
			
		||||
  mapHttpRequest: mock,
 | 
			
		||||
  mapHttpResponse: mock,
 | 
			
		||||
  wrapRequestSerializer: passthrough,
 | 
			
		||||
  wrapResponseSerializer: passthrough,
 | 
			
		||||
  wrapErrorSerializer: passthrough,
 | 
			
		||||
  req: mock,
 | 
			
		||||
  res: mock,
 | 
			
		||||
  err: asErrValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function pino (opts) {
 | 
			
		||||
  opts = opts || {}
 | 
			
		||||
  opts.browser = opts.browser || {}
 | 
			
		||||
 | 
			
		||||
  var transmit = opts.browser.transmit
 | 
			
		||||
  if (transmit && typeof transmit.send !== 'function') { throw Error('pino: transmit option must have a send function') }
 | 
			
		||||
 | 
			
		||||
  var proto = opts.browser.write || _console
 | 
			
		||||
  if (opts.browser.write) opts.browser.asObject = true
 | 
			
		||||
  var serializers = opts.serializers || {}
 | 
			
		||||
  var serialize = Array.isArray(opts.browser.serialize)
 | 
			
		||||
    ? opts.browser.serialize.filter(function (k) {
 | 
			
		||||
      return k !== '!stdSerializers.err'
 | 
			
		||||
    })
 | 
			
		||||
    : opts.browser.serialize === true ? Object.keys(serializers) : false
 | 
			
		||||
  var stdErrSerialize = opts.browser.serialize
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    Array.isArray(opts.browser.serialize) &&
 | 
			
		||||
    opts.browser.serialize.indexOf('!stdSerializers.err') > -1
 | 
			
		||||
  ) stdErrSerialize = false
 | 
			
		||||
 | 
			
		||||
  var levels = ['error', 'fatal', 'warn', 'info', 'debug', 'trace']
 | 
			
		||||
 | 
			
		||||
  if (typeof proto === 'function') {
 | 
			
		||||
    proto.error = proto.fatal = proto.warn =
 | 
			
		||||
    proto.info = proto.debug = proto.trace = proto
 | 
			
		||||
  }
 | 
			
		||||
  if (opts.enabled === false) opts.level = 'silent'
 | 
			
		||||
  var level = opts.level || 'info'
 | 
			
		||||
  var logger = Object.create(proto)
 | 
			
		||||
  if (!logger.log) logger.log = noop
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(logger, 'levelVal', {
 | 
			
		||||
    get: getLevelVal
 | 
			
		||||
  })
 | 
			
		||||
  Object.defineProperty(logger, 'level', {
 | 
			
		||||
    get: getLevel,
 | 
			
		||||
    set: setLevel
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  var setOpts = {
 | 
			
		||||
    transmit: transmit,
 | 
			
		||||
    serialize: serialize,
 | 
			
		||||
    asObject: opts.browser.asObject,
 | 
			
		||||
    levels: levels
 | 
			
		||||
  }
 | 
			
		||||
  logger.levels = pino.levels
 | 
			
		||||
  logger.level = level
 | 
			
		||||
 | 
			
		||||
  logger.setMaxListeners = logger.getMaxListeners =
 | 
			
		||||
  logger.emit = logger.addListener = logger.on =
 | 
			
		||||
  logger.prependListener = logger.once =
 | 
			
		||||
  logger.prependOnceListener = logger.removeListener =
 | 
			
		||||
  logger.removeAllListeners = logger.listeners =
 | 
			
		||||
  logger.listenerCount = logger.eventNames =
 | 
			
		||||
  logger.write = logger.flush = noop
 | 
			
		||||
  logger.serializers = serializers
 | 
			
		||||
  logger._serialize = serialize
 | 
			
		||||
  logger._stdErrSerialize = stdErrSerialize
 | 
			
		||||
  logger.child = child
 | 
			
		||||
 | 
			
		||||
  if (transmit) logger._logEvent = createLogEventShape()
 | 
			
		||||
 | 
			
		||||
  function getLevelVal () {
 | 
			
		||||
    return this.level === 'silent'
 | 
			
		||||
      ? Infinity
 | 
			
		||||
      : this.levels.values[this.level]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getLevel () {
 | 
			
		||||
    return this._level
 | 
			
		||||
  }
 | 
			
		||||
  function setLevel (level) {
 | 
			
		||||
    if (level !== 'silent' && !this.levels.values[level]) {
 | 
			
		||||
      throw Error('unknown level ' + level)
 | 
			
		||||
    }
 | 
			
		||||
    this._level = level
 | 
			
		||||
 | 
			
		||||
    set(setOpts, logger, 'error', 'log') // <-- must stay first
 | 
			
		||||
    set(setOpts, logger, 'fatal', 'error')
 | 
			
		||||
    set(setOpts, logger, 'warn', 'error')
 | 
			
		||||
    set(setOpts, logger, 'info', 'log')
 | 
			
		||||
    set(setOpts, logger, 'debug', 'log')
 | 
			
		||||
    set(setOpts, logger, 'trace', 'log')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function child (bindings) {
 | 
			
		||||
    if (!bindings) {
 | 
			
		||||
      throw new Error('missing bindings for child Pino')
 | 
			
		||||
    }
 | 
			
		||||
    var bindingsSerializers = bindings.serializers
 | 
			
		||||
    if (serialize && bindingsSerializers) {
 | 
			
		||||
      var childSerializers = Object.assign({}, serializers, bindingsSerializers)
 | 
			
		||||
      var childSerialize = opts.browser.serialize === true
 | 
			
		||||
        ? Object.keys(childSerializers)
 | 
			
		||||
        : serialize
 | 
			
		||||
      delete bindings.serializers
 | 
			
		||||
      applySerializers([bindings], childSerialize, childSerializers, this._stdErrSerialize)
 | 
			
		||||
    }
 | 
			
		||||
    function Child (parent) {
 | 
			
		||||
      this._childLevel = (parent._childLevel | 0) + 1
 | 
			
		||||
      this.error = bind(parent, bindings, 'error')
 | 
			
		||||
      this.fatal = bind(parent, bindings, 'fatal')
 | 
			
		||||
      this.warn = bind(parent, bindings, 'warn')
 | 
			
		||||
      this.info = bind(parent, bindings, 'info')
 | 
			
		||||
      this.debug = bind(parent, bindings, 'debug')
 | 
			
		||||
      this.trace = bind(parent, bindings, 'trace')
 | 
			
		||||
      if (childSerializers) {
 | 
			
		||||
        this.serializers = childSerializers
 | 
			
		||||
        this._serialize = childSerialize
 | 
			
		||||
      }
 | 
			
		||||
      if (transmit) {
 | 
			
		||||
        this._logEvent = createLogEventShape(
 | 
			
		||||
          [].concat(parent._logEvent.bindings, bindings)
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    Child.prototype = this
 | 
			
		||||
    return new Child(this)
 | 
			
		||||
  }
 | 
			
		||||
  return logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pino.LOG_VERSION = 1
 | 
			
		||||
 | 
			
		||||
pino.levels = {
 | 
			
		||||
  values: {
 | 
			
		||||
    fatal: 60,
 | 
			
		||||
    error: 50,
 | 
			
		||||
    warn: 40,
 | 
			
		||||
    info: 30,
 | 
			
		||||
    debug: 20,
 | 
			
		||||
    trace: 10
 | 
			
		||||
  },
 | 
			
		||||
  labels: {
 | 
			
		||||
    10: 'trace',
 | 
			
		||||
    20: 'debug',
 | 
			
		||||
    30: 'info',
 | 
			
		||||
    40: 'warn',
 | 
			
		||||
    50: 'error',
 | 
			
		||||
    60: 'fatal'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pino.stdSerializers = stdSerializers
 | 
			
		||||
 | 
			
		||||
function set (opts, logger, level, fallback) {
 | 
			
		||||
  var proto = Object.getPrototypeOf(logger)
 | 
			
		||||
  logger[level] = logger.levelVal > logger.levels.values[level] ? noop
 | 
			
		||||
    : (proto[level] ? proto[level] : (_console[level] || _console[fallback] || noop))
 | 
			
		||||
 | 
			
		||||
  wrap(opts, logger, level)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function wrap (opts, logger, level) {
 | 
			
		||||
  if (!opts.transmit && logger[level] === noop) return
 | 
			
		||||
 | 
			
		||||
  logger[level] = (function (write) {
 | 
			
		||||
    return function LOG () {
 | 
			
		||||
      var ts = Date.now()
 | 
			
		||||
      var args = new Array(arguments.length)
 | 
			
		||||
      var proto = (Object.getPrototypeOf && Object.getPrototypeOf(this) === _console) ? _console : this
 | 
			
		||||
      for (var i = 0; i < args.length; i++) args[i] = arguments[i]
 | 
			
		||||
 | 
			
		||||
      if (opts.serialize && !opts.asObject) {
 | 
			
		||||
        applySerializers(args, this._serialize, this.serializers, this._stdErrSerialize)
 | 
			
		||||
      }
 | 
			
		||||
      if (opts.asObject) write.call(proto, asObject(this, level, args, ts))
 | 
			
		||||
      else write.apply(proto, args)
 | 
			
		||||
 | 
			
		||||
      if (opts.transmit) {
 | 
			
		||||
        var transmitLevel = opts.transmit.level || logger.level
 | 
			
		||||
        var transmitValue = pino.levels.values[transmitLevel]
 | 
			
		||||
        var methodValue = pino.levels.values[level]
 | 
			
		||||
        if (methodValue < transmitValue) return
 | 
			
		||||
        transmit(this, {
 | 
			
		||||
          ts: ts,
 | 
			
		||||
          methodLevel: level,
 | 
			
		||||
          methodValue: methodValue,
 | 
			
		||||
          transmitLevel: transmitLevel,
 | 
			
		||||
          transmitValue: pino.levels.values[opts.transmit.level || logger.level],
 | 
			
		||||
          send: opts.transmit.send,
 | 
			
		||||
          val: logger.levelVal
 | 
			
		||||
        }, args)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })(logger[level])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function asObject (logger, level, args, ts) {
 | 
			
		||||
  if (logger._serialize) applySerializers(args, logger._serialize, logger.serializers, logger._stdErrSerialize)
 | 
			
		||||
  var argsCloned = args.slice()
 | 
			
		||||
  var msg = argsCloned[0]
 | 
			
		||||
  var o = { time: ts, level: pino.levels.values[level] }
 | 
			
		||||
  var lvl = (logger._childLevel | 0) + 1
 | 
			
		||||
  if (lvl < 1) lvl = 1
 | 
			
		||||
  // deliberate, catching objects, arrays
 | 
			
		||||
  if (msg !== null && typeof msg === 'object') {
 | 
			
		||||
    while (lvl-- && typeof argsCloned[0] === 'object') {
 | 
			
		||||
      Object.assign(o, argsCloned.shift())
 | 
			
		||||
    }
 | 
			
		||||
    msg = argsCloned.length ? format(argsCloned.shift(), argsCloned) : undefined
 | 
			
		||||
  } else if (typeof msg === 'string') msg = format(argsCloned.shift(), argsCloned)
 | 
			
		||||
  if (msg !== undefined) o.msg = msg
 | 
			
		||||
  return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function applySerializers (args, serialize, serializers, stdErrSerialize) {
 | 
			
		||||
  for (var i in args) {
 | 
			
		||||
    if (stdErrSerialize && args[i] instanceof Error) {
 | 
			
		||||
      args[i] = pino.stdSerializers.err(args[i])
 | 
			
		||||
    } else if (typeof args[i] === 'object' && !Array.isArray(args[i])) {
 | 
			
		||||
      for (var k in args[i]) {
 | 
			
		||||
        if (serialize && serialize.indexOf(k) > -1 && k in serializers) {
 | 
			
		||||
          args[i][k] = serializers[k](args[i][k])
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function bind (parent, bindings, level) {
 | 
			
		||||
  return function () {
 | 
			
		||||
    var args = new Array(1 + arguments.length)
 | 
			
		||||
    args[0] = bindings
 | 
			
		||||
    for (var i = 1; i < args.length; i++) {
 | 
			
		||||
      args[i] = arguments[i - 1]
 | 
			
		||||
    }
 | 
			
		||||
    return parent[level].apply(this, args)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function transmit (logger, opts, args) {
 | 
			
		||||
  var send = opts.send
 | 
			
		||||
  var ts = opts.ts
 | 
			
		||||
  var methodLevel = opts.methodLevel
 | 
			
		||||
  var methodValue = opts.methodValue
 | 
			
		||||
  var val = opts.val
 | 
			
		||||
  var bindings = logger._logEvent.bindings
 | 
			
		||||
 | 
			
		||||
  applySerializers(
 | 
			
		||||
    args,
 | 
			
		||||
    logger._serialize || Object.keys(logger.serializers),
 | 
			
		||||
    logger.serializers,
 | 
			
		||||
    logger._stdErrSerialize === undefined ? true : logger._stdErrSerialize
 | 
			
		||||
  )
 | 
			
		||||
  logger._logEvent.ts = ts
 | 
			
		||||
  logger._logEvent.messages = args.filter(function (arg) {
 | 
			
		||||
    // bindings can only be objects, so reference equality check via indexOf is fine
 | 
			
		||||
    return bindings.indexOf(arg) === -1
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger._logEvent.level.label = methodLevel
 | 
			
		||||
  logger._logEvent.level.value = methodValue
 | 
			
		||||
 | 
			
		||||
  send(methodLevel, logger._logEvent, val)
 | 
			
		||||
 | 
			
		||||
  logger._logEvent = createLogEventShape(bindings)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createLogEventShape (bindings) {
 | 
			
		||||
  return {
 | 
			
		||||
    ts: 0,
 | 
			
		||||
    messages: [],
 | 
			
		||||
    bindings: bindings || [],
 | 
			
		||||
    level: { label: '', value: 0 }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function asErrValue (err) {
 | 
			
		||||
  var obj = {
 | 
			
		||||
    type: err.constructor.name,
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack
 | 
			
		||||
  }
 | 
			
		||||
  for (var key in err) {
 | 
			
		||||
    if (obj[key] === undefined) {
 | 
			
		||||
      obj[key] = err[key]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return obj
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mock () { return {} }
 | 
			
		||||
function passthrough (a) { return a }
 | 
			
		||||
function noop () {}
 | 
			
		||||
 | 
			
		||||
/* eslint-disable */
 | 
			
		||||
/* istanbul ignore next */
 | 
			
		||||
function pfGlobalThisOrFallback () {
 | 
			
		||||
  function defd (o) { return typeof o !== 'undefined' && o }
 | 
			
		||||
  try { 
 | 
			
		||||
    if (typeof globalThis !== 'undefined') return globalThis
 | 
			
		||||
    Object.defineProperty(Object.prototype, 'globalThis', {
 | 
			
		||||
      get: function () {
 | 
			
		||||
        delete Object.prototype.globalThis
 | 
			
		||||
        return (this.globalThis = this)
 | 
			
		||||
      },
 | 
			
		||||
      configurable: true
 | 
			
		||||
    })
 | 
			
		||||
    return globalThis
 | 
			
		||||
  } catch (e) { 
 | 
			
		||||
    return defd(self) || defd(window) || defd(this) || {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
/* eslint-enable */
 | 
			
		||||
							
								
								
									
										868
									
								
								node_modules/pino/docs/api.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										868
									
								
								node_modules/pino/docs/api.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,868 @@
 | 
			
		|||
# API
 | 
			
		||||
 | 
			
		||||
* [pino() => logger](#export)
 | 
			
		||||
  * [options](#options)
 | 
			
		||||
  * [destination](#destination)
 | 
			
		||||
  * [destination\[Symbol.for('pino.metadata')\]](#metadata)
 | 
			
		||||
* [Logger Instance](#logger)
 | 
			
		||||
  * [logger.trace()](#trace)
 | 
			
		||||
  * [logger.debug()](#debug)
 | 
			
		||||
  * [logger.info()](#info)
 | 
			
		||||
  * [logger.warn()](#warn)
 | 
			
		||||
  * [logger.error()](#error)
 | 
			
		||||
  * [logger.fatal()](#fatal)
 | 
			
		||||
  * [logger.child()](#child)
 | 
			
		||||
  * [logger.bindings()](#bindings)
 | 
			
		||||
  * [logger.flush()](#flush)
 | 
			
		||||
  * [logger.level](#level)
 | 
			
		||||
  * [logger.isLevelEnabled()](#islevelenabled)
 | 
			
		||||
  * [logger.levels](#levels)
 | 
			
		||||
  * [logger\[Symbol.for('pino.serializers')\]](#serializers)
 | 
			
		||||
  * [Event: 'level-change'](#level-change)
 | 
			
		||||
  * [logger.version](#version)
 | 
			
		||||
  * [logger.LOG_VERSION](#log_version)
 | 
			
		||||
* [Statics](#statics)
 | 
			
		||||
  * [pino.destination()](#pino-destination)
 | 
			
		||||
  * [pino.extreme()](#pino-extreme)
 | 
			
		||||
  * [pino.final()](#pino-final)
 | 
			
		||||
  * [pino.stdSerializers](#pino-stdserializers)
 | 
			
		||||
  * [pino.stdTimeFunctions](#pino-stdtimefunctions)
 | 
			
		||||
  * [pino.symbols](#pino-symbols)
 | 
			
		||||
  * [pino.version](#pino-version)
 | 
			
		||||
  * [pino.LOG_VERSION](#pino-LOG_VERSION)
 | 
			
		||||
 | 
			
		||||
<a id="export"></a>
 | 
			
		||||
## `pino([options], [destination]) => logger`
 | 
			
		||||
 | 
			
		||||
The exported `pino` function takes two optional arguments,
 | 
			
		||||
[`options`](#options) and [`destination`](#destination) and
 | 
			
		||||
returns a [logger instance](#logger).
 | 
			
		||||
 | 
			
		||||
<a id=options></a>
 | 
			
		||||
### `options` (Object)
 | 
			
		||||
 | 
			
		||||
#### `name` (String)
 | 
			
		||||
 | 
			
		||||
Default: `undefined`
 | 
			
		||||
 | 
			
		||||
The name of the logger. When set adds a `name` field to every JSON line logged.
 | 
			
		||||
 | 
			
		||||
#### `level` (String)
 | 
			
		||||
 | 
			
		||||
Default: `'info'`
 | 
			
		||||
 | 
			
		||||
One of `'fatal'`, `'error'`, `'warn'`, `'info`', `'debug'`, `'trace'` or `'silent'`.
 | 
			
		||||
 | 
			
		||||
Additional levels can be added to the instance via the `customLevels` option.
 | 
			
		||||
 | 
			
		||||
* See [`customLevels` option](#opt-customlevels)
 | 
			
		||||
 | 
			
		||||
<a id=opt-customlevels></a>
 | 
			
		||||
#### `customLevels` (Object)
 | 
			
		||||
 | 
			
		||||
Default: `undefined`
 | 
			
		||||
 | 
			
		||||
Use this option to define additional logging levels.
 | 
			
		||||
The keys of the object correspond the namespace of the log level,
 | 
			
		||||
and the values should be the numerical value of the level.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = pino({
 | 
			
		||||
  customLevels: {
 | 
			
		||||
    foo: 35
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
logger.foo('hi')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id=opt-useOnlyCustomLevels></a>
 | 
			
		||||
#### `useOnlyCustomLevels` (Boolean)
 | 
			
		||||
 | 
			
		||||
Default: `false`
 | 
			
		||||
 | 
			
		||||
Use this option to only use defined `customLevels` and omit Pino's levels.
 | 
			
		||||
Logger's default `level` must be changed to a value in `customLevels` in order to use `useOnlyCustomLevels`
 | 
			
		||||
Warning: this option may not be supported by downstream transports.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = pino({
 | 
			
		||||
  customLevels: {
 | 
			
		||||
    foo: 35
 | 
			
		||||
  },
 | 
			
		||||
  useOnlyCustomLevels: true,
 | 
			
		||||
  level: 'foo'
 | 
			
		||||
})
 | 
			
		||||
logger.foo('hi')
 | 
			
		||||
logger.info('hello') // Will throw an error saying info in not found in logger object
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `mixin` (Function):
 | 
			
		||||
 | 
			
		||||
Default: `undefined`
 | 
			
		||||
 | 
			
		||||
If provided, the `mixin` function is called each time one of the active
 | 
			
		||||
logging methods is called. The function must synchronously return an
 | 
			
		||||
object. The properties of the returned object will be added to the
 | 
			
		||||
logged JSON.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
let n = 0
 | 
			
		||||
const logger = pino({
 | 
			
		||||
  mixin () {
 | 
			
		||||
    return { line: ++n }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
logger.info('hello')
 | 
			
		||||
// {"level":30,"time":1573664685466,"pid":78742,"hostname":"x","line":1,"msg":"hello","v":1}
 | 
			
		||||
logger.info('world')
 | 
			
		||||
// {"level":30,"time":1573664685469,"pid":78742,"hostname":"x","line":2,"msg":"world","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `redact` (Array | Object):
 | 
			
		||||
 | 
			
		||||
Default: `undefined`
 | 
			
		||||
 | 
			
		||||
As an array, the `redact` option specifies paths that should
 | 
			
		||||
have their values redacted from any log output.
 | 
			
		||||
 | 
			
		||||
Each path must be a string using a syntax which corresponds to JavaScript dot and bracket notation.
 | 
			
		||||
 | 
			
		||||
If an object is supplied, three options can be specified:
 | 
			
		||||
  * `paths` (array): Required. An array of paths. See [redaction - Path Syntax ⇗](/docs/redaction.md#paths) for specifics.
 | 
			
		||||
  * `censor` (String|Function|Undefined): Optional. When supplied as a String the `censor` option will overwrite keys which are to be redacted. When set to `undefined` the the key will be removed entirely from the object.
 | 
			
		||||
    The `censor` option may also be a mapping function. The (synchronous) mapping function is called with the unredacted value. The value returned from the mapping function becomes the applied censor value. Default: `'[Redacted]'`
 | 
			
		||||
    value synchronously.
 | 
			
		||||
    Default: `'[Redacted]'`
 | 
			
		||||
  * `remove` (Boolean): Optional. Instead of censoring the value, remove both the key and the value. Default: `false`
 | 
			
		||||
 | 
			
		||||
**WARNING**: Never allow user input to define redacted paths.
 | 
			
		||||
 | 
			
		||||
* See the [redaction ⇗](/docs/redaction.md) documentation.
 | 
			
		||||
* See [fast-redact#caveat ⇗](http://github.com/davidmarkclements/fast-redact#caveat)
 | 
			
		||||
 | 
			
		||||
<a id=opt-serializers></a>
 | 
			
		||||
#### `serializers` (Object)
 | 
			
		||||
 | 
			
		||||
Default: `{err: pino.stdSerializers.err}`
 | 
			
		||||
 | 
			
		||||
An object containing functions for custom serialization of objects.
 | 
			
		||||
These functions should return an JSONifiable object and they
 | 
			
		||||
should never throw. When logging an object, each top-level property
 | 
			
		||||
matching the exact key of a serializer will be serialized using the defined serializer.
 | 
			
		||||
 | 
			
		||||
* See [pino.stdSerializers](#pino-stdserializers)
 | 
			
		||||
 | 
			
		||||
##### `serializers[Symbol.for('pino.*')]` (Function)
 | 
			
		||||
 | 
			
		||||
Default: `undefined`
 | 
			
		||||
 | 
			
		||||
The `serializers` object may contain a key which is the global symbol: `Symbol.for('pino.*')`.
 | 
			
		||||
This will act upon the complete log object rather than corresponding to a particular key.
 | 
			
		||||
 | 
			
		||||
#### `base` (Object)
 | 
			
		||||
 | 
			
		||||
Default: `{pid: process.pid, hostname: os.hostname}`
 | 
			
		||||
 | 
			
		||||
Key-value object added as child logger to each log line.
 | 
			
		||||
 | 
			
		||||
Set to `null` to avoid adding `pid`, `hostname` and `name` properties to each log.
 | 
			
		||||
 | 
			
		||||
#### `enabled` (Boolean)
 | 
			
		||||
 | 
			
		||||
Default: `true`
 | 
			
		||||
 | 
			
		||||
Set to `false` to disable logging.
 | 
			
		||||
 | 
			
		||||
#### `crlf` (Boolean)
 | 
			
		||||
 | 
			
		||||
Default: `false`
 | 
			
		||||
 | 
			
		||||
Set to `true` to logs newline delimited JSON with `\r\n` instead of `\n`.
 | 
			
		||||
 | 
			
		||||
<a id=opt-timestamp></a>
 | 
			
		||||
#### `timestamp` (Boolean | Function)
 | 
			
		||||
 | 
			
		||||
Default: `true`
 | 
			
		||||
 | 
			
		||||
Enables or disables the inclusion of a timestamp in the
 | 
			
		||||
log message. If a function is supplied, it must synchronously return a JSON string
 | 
			
		||||
representation of the time, e.g. `,"time":1493426328206` (which is the default).
 | 
			
		||||
 | 
			
		||||
If set to `false`, no timestamp will be included in the output.
 | 
			
		||||
See [stdTimeFunctions](#pino-stdtimefunctions) for a set of available functions
 | 
			
		||||
for passing in as a value for this option.
 | 
			
		||||
 | 
			
		||||
**Caution**: attempting to format time in-process will significantly impact logging performance.
 | 
			
		||||
 | 
			
		||||
<a id=opt-messagekey></a>
 | 
			
		||||
#### `messageKey` (String)
 | 
			
		||||
 | 
			
		||||
Default: `'msg'`
 | 
			
		||||
 | 
			
		||||
The string key for the 'message' in the JSON object.
 | 
			
		||||
 | 
			
		||||
<a id=opt-nestedkey></a>
 | 
			
		||||
#### `nestedKey` (String)
 | 
			
		||||
 | 
			
		||||
Default: `null`
 | 
			
		||||
 | 
			
		||||
If there's a chance that objects being logged have properties that conflict with those from pino itself (`level`, `timestamp`, `v`, `pid`, etc)
 | 
			
		||||
and duplicate keys in your log records are undesirable, pino can be configured with a `nestedKey` option that causes any `object`s that are logged
 | 
			
		||||
to be placed under a key whose name is the value of `nestedKey`.
 | 
			
		||||
 | 
			
		||||
This way, when searching something like Kibana for values, one can consistently search under the configured `nestedKey` value instead of the root log record keys.
 | 
			
		||||
 | 
			
		||||
For example,
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')({
 | 
			
		||||
  nestedKey: 'payload'
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const thing = { level: 'hi', time: 'never', foo: 'bar'} // has pino-conflicting properties!
 | 
			
		||||
logger.info(thing)
 | 
			
		||||
 | 
			
		||||
// logs the following:
 | 
			
		||||
// {"level":30,"time":1578357790020,"pid":91736,"hostname":"x","payload":{"level":"hi","time":"never","foo":"bar"},"v":1}
 | 
			
		||||
```
 | 
			
		||||
In this way, logged objects' properties don't conflict with pino's standard logging properties,
 | 
			
		||||
and searching for logged objects can start from a consistent path.
 | 
			
		||||
 | 
			
		||||
<a id=prettyPrint></a>
 | 
			
		||||
#### `prettyPrint` (Boolean | Object)
 | 
			
		||||
 | 
			
		||||
Default: `false`
 | 
			
		||||
 | 
			
		||||
Enables pretty printing log logs. This is intended for non-production
 | 
			
		||||
configurations. This may be set to a configuration object as outlined in the
 | 
			
		||||
[`pino-pretty` documentation](https://github.com/pinojs/pino-pretty).
 | 
			
		||||
 | 
			
		||||
The options object may additionally contain a `prettifier` property to define
 | 
			
		||||
which prettifier module to use. When not present, `prettifier` defaults to
 | 
			
		||||
`'pino-pretty'`. Regardless of the value, the specified prettifier module
 | 
			
		||||
must be installed as a separate dependency:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install pino-pretty
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="useLevelLabels"></a>
 | 
			
		||||
#### `useLevelLabels` (Boolean)
 | 
			
		||||
 | 
			
		||||
Default: `false`
 | 
			
		||||
 | 
			
		||||
Enables printing of level labels instead of level values in the printed logs.
 | 
			
		||||
Warning: this option may not be supported by downstream transports.
 | 
			
		||||
 | 
			
		||||
<a id="changeLevelName"></a>
 | 
			
		||||
#### `changeLevelName` (String) - DEPRECATED
 | 
			
		||||
Use `levelKey` instead. This will be removed in v7.
 | 
			
		||||
 | 
			
		||||
<a id="levelKey"></a>
 | 
			
		||||
#### `levelKey` (String)
 | 
			
		||||
 | 
			
		||||
Default: `'level'`
 | 
			
		||||
 | 
			
		||||
Changes the property `level` to any string value you pass in:
 | 
			
		||||
```js
 | 
			
		||||
const logger = pino({
 | 
			
		||||
  levelKey: 'priority'
 | 
			
		||||
})
 | 
			
		||||
logger.info('hello world')
 | 
			
		||||
// {"priority":30,"time":1531257112193,"msg":"hello world","pid":55956,"hostname":"x","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `browser` (Object)
 | 
			
		||||
 | 
			
		||||
Browser only, may have `asObject` and `write` keys. This option is separately
 | 
			
		||||
documented in the [Browser API ⇗](/docs/browser.md) documentation.
 | 
			
		||||
 | 
			
		||||
* See [Browser API ⇗](/docs/browser.md)
 | 
			
		||||
 | 
			
		||||
<a id="destination"></a>
 | 
			
		||||
### `destination` (SonicBoom | WritableStream | String)
 | 
			
		||||
 | 
			
		||||
Default: `pino.destination(1)` (STDOUT)
 | 
			
		||||
 | 
			
		||||
The `destination` parameter, at a minimum must be an object with a `write` method.
 | 
			
		||||
An ordinary Node.js `stream` can be passed as the destination (such as the result
 | 
			
		||||
of `fs.createWriteStream`) but for peak log writing performance it is strongly
 | 
			
		||||
recommended to use `pino.destination` or `pino.extreme` to create the destination stream.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// pino.destination(1) by default
 | 
			
		||||
const stdoutLogger = require('pino')()
 | 
			
		||||
 | 
			
		||||
// destination param may be in first position when no options:
 | 
			
		||||
const fileLogger = require('pino')( pino.destination('/log/path'))
 | 
			
		||||
 | 
			
		||||
// use the stderr file handle to log to stderr:
 | 
			
		||||
const opts = {name: 'my-logger'}
 | 
			
		||||
const stderrLogger = require('pino')(opts, pino.destination(2))
 | 
			
		||||
 | 
			
		||||
// automatic wrapping in pino.destination
 | 
			
		||||
const fileLogger = require('pino')('/log/path')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
However, there are some special instances where `pino.destination` is not used as the default:
 | 
			
		||||
 | 
			
		||||
+ When something, e.g a process manager, has monkey-patched `process.stdout.write`.
 | 
			
		||||
 | 
			
		||||
In these cases `process.stdout` is used instead.
 | 
			
		||||
 | 
			
		||||
* See [`pino.destination`](#pino-destination)
 | 
			
		||||
* See [`pino.extreme`](#pino-extreme)
 | 
			
		||||
 | 
			
		||||
<a id="metadata"></a>
 | 
			
		||||
#### `destination[Symbol.for('pino.metadata')]`
 | 
			
		||||
 | 
			
		||||
Default: `false`
 | 
			
		||||
 | 
			
		||||
Using the global symbol `Symbol.for('pino.metadata')` as a key on the `destination` parameter and
 | 
			
		||||
setting the key it to `true`, indicates that the following properties should be
 | 
			
		||||
set on the `destination` object after each log line is written:
 | 
			
		||||
 | 
			
		||||
* the last logging level as `destination.lastLevel`
 | 
			
		||||
* the last logging message as `destination.lastMsg`
 | 
			
		||||
* the last logging object as `destination.lastObj`
 | 
			
		||||
* the last time as `destination.lastTime`, which will be the partial string returned
 | 
			
		||||
  by the time function.
 | 
			
		||||
* the last logger instance as `destination.lastLogger` (to support child
 | 
			
		||||
  loggers)
 | 
			
		||||
 | 
			
		||||
For a full reference for using `Symbol.for('pino.metadata')`, see the [`pino-multi-stream` ⇗](https://github.com/pinojs/pino-multi-stream)
 | 
			
		||||
module.
 | 
			
		||||
 | 
			
		||||
The following is a succinct usage example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const dest = pino.destination('/dev/null')
 | 
			
		||||
dest[Symbol.for('pino.metadata')] = true
 | 
			
		||||
const logger = pino(dest)
 | 
			
		||||
logger.info({a: 1}, 'hi')
 | 
			
		||||
const { lastMsg, lastLevel, lastObj, lastTime} = dest
 | 
			
		||||
console.log(
 | 
			
		||||
  'Logged message "%s" at level %d with object %o at time %s',
 | 
			
		||||
  lastMsg, lastLevel, lastObj, lastTime
 | 
			
		||||
) // Logged message "hi" at level 30 with object { a: 1 } at time 1531590545089
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [`pino-multi-stream` ⇗](https://github.com/pinojs/pino-multi-stream)
 | 
			
		||||
 | 
			
		||||
<a id="logger"></a>
 | 
			
		||||
## Logger Instance
 | 
			
		||||
 | 
			
		||||
The logger instance is the object returned by the main exported
 | 
			
		||||
[`pino`](#export) function.
 | 
			
		||||
 | 
			
		||||
The primary purpose of the logger instance is to provide logging methods.
 | 
			
		||||
 | 
			
		||||
The default logging methods are `trace`, `debug`, `info`, `warn`, `error`, and `fatal`.
 | 
			
		||||
 | 
			
		||||
Each logging method has the following signature:
 | 
			
		||||
`([mergingObject], [message], [...interpolationValues])`.
 | 
			
		||||
 | 
			
		||||
The parameters are explained below using the `logger.info` method but the same applies to all logging methods.
 | 
			
		||||
 | 
			
		||||
### Logging Method Parameters
 | 
			
		||||
 | 
			
		||||
<a id=mergingobject></a>
 | 
			
		||||
#### `mergingObject` (Object)
 | 
			
		||||
 | 
			
		||||
An object can optionally be supplied as the first parameter. Each enumerable key and value
 | 
			
		||||
of the `mergingObject` is copied in to the JSON log line.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
logger.info({MIX: {IN: true}})
 | 
			
		||||
// {"level":30,"time":1531254555820,"pid":55956,"hostname":"x","MIX":{"IN":true},"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id=message></a>
 | 
			
		||||
#### `message` (String)
 | 
			
		||||
 | 
			
		||||
A `message` string can optionally be supplied as the first parameter, or
 | 
			
		||||
as the second parameter after supplying a `mergingObject`.
 | 
			
		||||
 | 
			
		||||
By default, the contents of the `message` parameter will be merged into the
 | 
			
		||||
JSON log line under the `msg` key:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
logger.info('hello world')
 | 
			
		||||
// {"level":30,"time":1531257112193,"msg":"hello world","pid":55956,"hostname":"x","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `message` parameter takes precedence over the `mergedObject`.
 | 
			
		||||
That is, if a `mergedObject` contains a `msg` property, and a `message` parameter
 | 
			
		||||
is supplied in addition, the `msg` property in the output log will be the value of
 | 
			
		||||
the `message` parameter not the value of the `msg` property on the `mergedObject`.
 | 
			
		||||
 | 
			
		||||
The `messageKey` option can be used at instantiation time to change the namespace
 | 
			
		||||
from `msg` to another string as preferred.
 | 
			
		||||
 | 
			
		||||
The `message` string may contain a printf style string with support for
 | 
			
		||||
the following placeholders:
 | 
			
		||||
 | 
			
		||||
* `%s` – string placeholder
 | 
			
		||||
* `%d` – digit placeholder
 | 
			
		||||
* `%O`, `%o` and `%j` – object placeholder
 | 
			
		||||
 | 
			
		||||
Values supplied as additional arguments to the logger method will
 | 
			
		||||
then be interpolated accordingly.
 | 
			
		||||
 | 
			
		||||
* See [`messageKey` pino option](#opt-messagekey)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id=interpolationvalues></a>
 | 
			
		||||
#### `...interpolationValues` (Any)
 | 
			
		||||
 | 
			
		||||
All arguments supplied after `message` are serialized and interpolated according
 | 
			
		||||
to any supplied printf-style placeholders (`%s`, `%d`, `%o`|`%O`|`%j`)
 | 
			
		||||
or else concatenated together with the `message` string to form the final
 | 
			
		||||
output `msg` value for the JSON log line.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
logger.info('hello', 'world')
 | 
			
		||||
// {"level":30,"time":1531257618044,"msg":"hello world","pid":55956,"hostname":"x","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
logger.info('hello', {worldly: 1})
 | 
			
		||||
// {"level":30,"time":1531257797727,"msg":"hello {\"worldly\":1}","pid":55956,"hostname":"x","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
logger.info('%o hello', {worldly: 1})
 | 
			
		||||
// {"level":30,"time":1531257826880,"msg":"{\"worldly\":1} hello","pid":55956,"hostname":"x","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
 | 
			
		||||
<a id="trace"></a>
 | 
			
		||||
### `logger.trace([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write a `'trace'` level log, if the configured [`level`](#level) allows for it.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id="debug"></a>
 | 
			
		||||
### `logger.debug([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write a `'debug'` level log, if the configured `level` allows for it.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id="info"></a>
 | 
			
		||||
### `logger.info([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write an `'info'` level log, if the configured `level` allows for it.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id="warn"></a>
 | 
			
		||||
### `logger.warn([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write a `'warn'` level log, if the configured `level` allows for it.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id="error"></a>
 | 
			
		||||
### `logger.error([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write a `'error'` level log, if the configured `level` allows for it.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
<a id="fatal"></a>
 | 
			
		||||
### `logger.fatal([mergingObject], [message], [...interpolationValues])`
 | 
			
		||||
 | 
			
		||||
Write a `'fatal'` level log, if the configured `level` allows for it.
 | 
			
		||||
 | 
			
		||||
Since `'fatal'` level messages are intended to be logged just prior to the process exiting the `fatal`
 | 
			
		||||
method will always sync flush the destination.
 | 
			
		||||
Therefore it's important not to misuse `fatal` since
 | 
			
		||||
it will cause performance overhead if used for any
 | 
			
		||||
other purpose than writing final log messages before
 | 
			
		||||
the process crashes or exits.
 | 
			
		||||
 | 
			
		||||
* See [`mergingObject` log method parameter](#mergingobject)
 | 
			
		||||
* See [`message` log method parameter](#message)
 | 
			
		||||
* See [`...interpolationValues` log method parameter](#interpolationvalues)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<a id="child"></a>
 | 
			
		||||
### `logger.child(bindings) => logger`
 | 
			
		||||
 | 
			
		||||
The `logger.child` method allows for the creation of stateful loggers,
 | 
			
		||||
where key-value pairs can be pinned to a logger causing them to be output
 | 
			
		||||
on every log line.
 | 
			
		||||
 | 
			
		||||
Child loggers use the same output stream as the parent and inherit
 | 
			
		||||
the current log level of the parent at the time they are spawned.
 | 
			
		||||
 | 
			
		||||
The log level of a child is mutable. It can be set independently
 | 
			
		||||
of the parent either by setting the [`level`](#level) accessor after creating
 | 
			
		||||
the child logger or using the reserved [`bindings.level`](#bindingslevel-string) key.
 | 
			
		||||
 | 
			
		||||
#### `bindings` (Object)
 | 
			
		||||
 | 
			
		||||
An object of key-value pairs to include in every log line output
 | 
			
		||||
via the returned child logger.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const child = logger.child({ MIX: {IN: 'always'} })
 | 
			
		||||
child.info('hello')
 | 
			
		||||
// {"level":30,"time":1531258616689,"msg":"hello","pid":64849,"hostname":"x","MIX":{"IN":"always"},"v":1}
 | 
			
		||||
child.info('child!')
 | 
			
		||||
// {"level":30,"time":1531258617401,"msg":"child!","pid":64849,"hostname":"x","MIX":{"IN":"always"},"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `bindings` object may contain any key except for reserved configuration keys `level` and `serializers`.
 | 
			
		||||
 | 
			
		||||
##### `bindings.level` (String)
 | 
			
		||||
 | 
			
		||||
If a `level` property is present in the `bindings` object passed to `logger.child`
 | 
			
		||||
it will override the child logger level.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = pino()
 | 
			
		||||
logger.debug('nope') // will not log, since default level is info
 | 
			
		||||
const child = logger.child({foo: 'bar', level: 'debug'})
 | 
			
		||||
child.debug('debug!') // will log as the `level` property set the level to debug
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### `bindings.serializers` (Object)
 | 
			
		||||
 | 
			
		||||
Child loggers inherit the [serializers](#opt-serializers) from the parent logger.
 | 
			
		||||
 | 
			
		||||
Setting the `serializers` key of the `bindings` object will override
 | 
			
		||||
any configured parent serializers.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')()
 | 
			
		||||
logger.info({test: 'will appear'})
 | 
			
		||||
// {"level":30,"time":1531259759482,"pid":67930,"hostname":"x","test":"will appear","v":1}
 | 
			
		||||
const child = logger.child({serializers: {test: () => `child-only serializer`}})
 | 
			
		||||
child.info({test: 'will be overwritten'})
 | 
			
		||||
// {"level":30,"time":1531259784008,"pid":67930,"hostname":"x","test":"child-only serializer","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [`serializers` option](#opt-serializers)
 | 
			
		||||
* See [pino.stdSerializers](#pino-stdSerializers)
 | 
			
		||||
 | 
			
		||||
<a id="bindings"></a>
 | 
			
		||||
### `logger.bindings()`
 | 
			
		||||
 | 
			
		||||
Returns an object containing all the current bindings, cloned from the ones passed in via `logger.child()`.
 | 
			
		||||
```js
 | 
			
		||||
const child = logger.child({ foo: 'bar' })
 | 
			
		||||
console.log(child.bindings())
 | 
			
		||||
// { foo: 'bar' }
 | 
			
		||||
const anotherChild = child.child({ MIX: { IN: 'always' } })
 | 
			
		||||
console.log(anotherChild.bindings())
 | 
			
		||||
// { foo: 'bar', MIX: { IN: 'always' } }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="flush"></a>
 | 
			
		||||
### `logger.flush()`
 | 
			
		||||
 | 
			
		||||
Flushes the content of the buffer when using a `pino.extreme` destination.
 | 
			
		||||
 | 
			
		||||
This is an asynchronous, fire and forget, operation.
 | 
			
		||||
 | 
			
		||||
The use case is primarily for Extreme mode logging, which may hold up to
 | 
			
		||||
4KiB of logs. The `logger.flush` method can be used to flush the logs
 | 
			
		||||
on an long interval, say ten seconds. Such a strategy can provide an
 | 
			
		||||
optimium balance between extremely efficient logging at high demand periods
 | 
			
		||||
and safer logging at low demand periods.
 | 
			
		||||
 | 
			
		||||
* See [`pino.extreme`](#pino-extreme)
 | 
			
		||||
* See [`destination` parameter](#destination)
 | 
			
		||||
* See [Extreme mode ⇗](/docs/extreme.md)
 | 
			
		||||
 | 
			
		||||
<a id="level"></a>
 | 
			
		||||
### `logger.level` (String) [Getter/Setter]
 | 
			
		||||
 | 
			
		||||
Set this property to the desired logging level.
 | 
			
		||||
 | 
			
		||||
The core levels and their values are as follows:
 | 
			
		||||
 | 
			
		||||
|            |       |       |      |      |       |       |          |
 | 
			
		||||
|:-----------|-------|-------|------|------|-------|-------|---------:|
 | 
			
		||||
| **Level:** | trace | debug | info | warn | error | fatal | silent   |
 | 
			
		||||
| **Value:** | 10    | 20    | 30   | 40   | 50    | 60    | Infinity |
 | 
			
		||||
 | 
			
		||||
The logging level is a *minimum* level based on the associated value of that level.
 | 
			
		||||
 | 
			
		||||
For instance if `logger.level` is `info` *(30)* then `info` *(30)*, `warn` *(40)*, `error` *(50)* and `fatal` *(60)* log methods will be enabled but the `trace` *(10)* and `debug` *(20)* methods, being less than 30, will not.
 | 
			
		||||
 | 
			
		||||
The `silent` logging level is a specialized level which will disable all logging,
 | 
			
		||||
there is no `silent` log method.
 | 
			
		||||
 | 
			
		||||
<a id="islevelenabled"></a>
 | 
			
		||||
### `logger.isLevelEnabled(level)`
 | 
			
		||||
 | 
			
		||||
A utility method for determining if a given log level will write to the destination.
 | 
			
		||||
 | 
			
		||||
#### `level` (String)
 | 
			
		||||
 | 
			
		||||
The given level to check against:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
if (logger.isLevelEnabled('debug')) logger.debug('conditional log')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `levelLabel` (String)
 | 
			
		||||
 | 
			
		||||
Defines the method name of the new level.
 | 
			
		||||
 | 
			
		||||
* See [`logger.level`](#level)
 | 
			
		||||
 | 
			
		||||
#### `levelValue` (Number)
 | 
			
		||||
 | 
			
		||||
Defines the associated minimum threshold value for the level, and
 | 
			
		||||
therefore where it sits in order of priority among other levels.
 | 
			
		||||
 | 
			
		||||
* See [`logger.level`](#level)
 | 
			
		||||
 | 
			
		||||
<a id="levelVal"></a>
 | 
			
		||||
### `logger.levelVal` (Number)
 | 
			
		||||
 | 
			
		||||
Supplies the integer value for the current logging level.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
if (logger.levelVal === 30) {
 | 
			
		||||
  console.log('logger level is `info`')
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="levels"></a>
 | 
			
		||||
### `logger.levels` (Object)
 | 
			
		||||
 | 
			
		||||
Levels are mapped to values to determine the minimum threshold that a
 | 
			
		||||
logging method should be enabled at (see [`logger.level`](#level)).
 | 
			
		||||
 | 
			
		||||
The `logger.levels` property holds the mappings between levels and values,
 | 
			
		||||
and vice versa.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node -p "require('pino')().levels"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{ labels:
 | 
			
		||||
   { '10': 'trace',
 | 
			
		||||
     '20': 'debug',
 | 
			
		||||
     '30': 'info',
 | 
			
		||||
     '40': 'warn',
 | 
			
		||||
     '50': 'error',
 | 
			
		||||
     '60': 'fatal' },
 | 
			
		||||
  values:
 | 
			
		||||
   { fatal: 60, error: 50, warn: 40, info: 30, debug: 20, trace: 10 } }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [`logger.level`](#level)
 | 
			
		||||
 | 
			
		||||
<a id="serializers"></a>
 | 
			
		||||
### logger\[Symbol.for('pino.serializers')\]
 | 
			
		||||
 | 
			
		||||
Returns the serializers as applied to the current logger instance. If a child logger did not
 | 
			
		||||
register it's own serializer upon instantiation the serializers of the parent will be returned.
 | 
			
		||||
 | 
			
		||||
<a id="level-change"></a>
 | 
			
		||||
### Event: 'level-change'
 | 
			
		||||
 | 
			
		||||
The logger instance is also an [`EventEmitter ⇗`](https://nodejs.org/dist/latest/docs/api/events.html#events_class_eventemitter)
 | 
			
		||||
 | 
			
		||||
A listener function can be attached to a logger via the `level-change` event
 | 
			
		||||
 | 
			
		||||
The listener is passed four arguments:
 | 
			
		||||
 | 
			
		||||
* `levelLabel` – the new level string, e.g `trace`
 | 
			
		||||
* `levelValue` – the new level number, e.g `10`
 | 
			
		||||
* `previousLevelLabel` – the prior level string, e.g `info`
 | 
			
		||||
* `previousLevelValue` – the prior level numbebr, e.g `30`
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')()
 | 
			
		||||
logger.on('level-change', (lvl, val, prevLvl, prevVal) => {
 | 
			
		||||
  console.log('%s (%d) was changed to %s (%d)', lvl, val, prevLvl, prevVal)
 | 
			
		||||
})
 | 
			
		||||
logger.level = 'trace' // trigger event
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="version"></a>
 | 
			
		||||
### `logger.version` (String)
 | 
			
		||||
 | 
			
		||||
Exposes the Pino package version. Also available on the exported `pino` function.
 | 
			
		||||
 | 
			
		||||
* See [`pino.version`](#pino-version)
 | 
			
		||||
 | 
			
		||||
<a id="log_version"></a>
 | 
			
		||||
### `logger.LOG_VERSION` (Number)
 | 
			
		||||
 | 
			
		||||
Holds the current log format version as output in the `v` property of each log record.
 | 
			
		||||
Also available on the exported `pino` function.
 | 
			
		||||
 | 
			
		||||
* See [`pino.LOG_VERSION`](#pino-LOG_VERSION)
 | 
			
		||||
 | 
			
		||||
## Statics
 | 
			
		||||
 | 
			
		||||
<a id="pino-destination"></a>
 | 
			
		||||
### `pino.destination([target]) => SonicBoom`
 | 
			
		||||
 | 
			
		||||
Create a Pino Destination instance: a stream-like object with
 | 
			
		||||
significantly more throughput (over 30%) than a standard Node.js stream.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')
 | 
			
		||||
const logger = pino(pino.destination('./my-file'))
 | 
			
		||||
const logger2 = pino(pino.destination())
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `pino.destination` method may be passed a file path or a numerical file descriptor.
 | 
			
		||||
By default, `pino.destination` will use `process.stdout.fd` (1) as the file descriptor.
 | 
			
		||||
 | 
			
		||||
`pino.destination` is implemented on [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom).
 | 
			
		||||
 | 
			
		||||
A `pino.destination` instance can also be used to reopen closed files
 | 
			
		||||
(for example, for some log rotation scenarios), see [Reopening log files](/docs/help.md#reopening).
 | 
			
		||||
 | 
			
		||||
* See [`destination` parameter](#destination)
 | 
			
		||||
* See [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom)
 | 
			
		||||
* See [Reopening log files](/docs/help.md#reopening)
 | 
			
		||||
 | 
			
		||||
<a id="pino-extreme"></a>
 | 
			
		||||
### `pino.extreme([target]) => SonicBoom`
 | 
			
		||||
 | 
			
		||||
Create an extreme mode destination. This yields an additional 60% performance boost.
 | 
			
		||||
There are trade-offs that should be understood before usage.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')
 | 
			
		||||
const logger = pino(pino.extreme('./my-file'))
 | 
			
		||||
const logger2 = pino(pino.extreme())
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `pino.extreme` method may be passed a file path or a numerical file descriptor.
 | 
			
		||||
By default, `pino.extreme` will use `process.stdout.fd` (1) as the file descriptor.
 | 
			
		||||
 | 
			
		||||
`pino.extreme` is implemented with the [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom)
 | 
			
		||||
module.
 | 
			
		||||
 | 
			
		||||
A `pino.extreme` instance can also be used to reopen closed files
 | 
			
		||||
(for example, for some log rotation scenarios), see [Reopening log files](/docs/help.md#reopening).
 | 
			
		||||
 | 
			
		||||
On AWS Lambda we recommend to call `extreme.flushSync()` at the end
 | 
			
		||||
of each function execution to avoid losing data.
 | 
			
		||||
 | 
			
		||||
* See [`destination` parameter](#destination)
 | 
			
		||||
* See [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom)
 | 
			
		||||
* See [Extreme mode ⇗](/docs/extreme.md)
 | 
			
		||||
* See [Reopening log files](/docs/help.md#reopening)
 | 
			
		||||
 | 
			
		||||
<a id="pino-final"></a>
 | 
			
		||||
 | 
			
		||||
### `pino.final(logger, [handler]) => Function | FinalLogger`
 | 
			
		||||
 | 
			
		||||
The `pino.final` method can be used to acquire a final logger instance
 | 
			
		||||
or create an exit listener function.
 | 
			
		||||
 | 
			
		||||
The `finalLogger` is a specialist logger that synchronously flushes
 | 
			
		||||
on every write. This is important to guarantee final log writes,
 | 
			
		||||
both when using `pino.extreme` target.
 | 
			
		||||
 | 
			
		||||
Since final log writes cannot be guaranteed with normal Node.js streams,
 | 
			
		||||
if the `destination` parameter of the `logger` supplied to `pino.final`
 | 
			
		||||
is a Node.js stream `pino.final` will throw.
 | 
			
		||||
 | 
			
		||||
The use of `pino.final` with `pino.destination` is not needed, as
 | 
			
		||||
`pino.destination` writes things synchronously.
 | 
			
		||||
 | 
			
		||||
#### `pino.final(logger, handler) => Function`
 | 
			
		||||
 | 
			
		||||
In this case the `pino.final` method supplies an exit listener function that can be
 | 
			
		||||
supplied to process exit events such as `exit`, `uncaughtException`,
 | 
			
		||||
`SIGHUP` and so on.
 | 
			
		||||
 | 
			
		||||
The exit listener function will call the supplied `handler` function
 | 
			
		||||
with an error object (or else `null`), a `finalLogger` instance followed
 | 
			
		||||
by any additional arguments the `handler` may be called with.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
process.on('uncaughtException', pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
  finalLogger.error(err, 'uncaughtException')
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
}))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `pino.final(logger) => FinalLogger`
 | 
			
		||||
 | 
			
		||||
In this case the `pino.final` method returns a finalLogger instance.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var finalLogger = pino.final(logger)
 | 
			
		||||
finalLogger.info('exiting...')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [`destination` parameter](#destination)
 | 
			
		||||
* See [Exit logging help](/docs/help.md#exit-logging)
 | 
			
		||||
* See [Extreme mode ⇗](/docs/extreme.md)
 | 
			
		||||
* See [Log loss prevention ⇗](/docs/extreme.md#log-loss-prevention)
 | 
			
		||||
 | 
			
		||||
<a id="pino-stdserializers"></a>
 | 
			
		||||
### `pino.stdSerializers` (Object)
 | 
			
		||||
 | 
			
		||||
The `pino.stdSerializers` object provides functions for serializing objects common to many projects. The standard serializers are directly imported from [pino-std-serializers](https://github.com/pinojs/pino-std-serializers).
 | 
			
		||||
 | 
			
		||||
* See [pino-std-serializers ⇗](https://github.com/pinojs/pino-std-serializers)
 | 
			
		||||
 | 
			
		||||
<a id="pino-stdtimefunctions"></a>
 | 
			
		||||
### `pino.stdTimeFunctions` (Object)
 | 
			
		||||
 | 
			
		||||
The [`timestamp`](#opt-timestamp) option can accept a function which determines the
 | 
			
		||||
`timestamp` value in a log line.
 | 
			
		||||
 | 
			
		||||
The `pino.stdTimeFunctions` object provides a very small set of common functions for generating the
 | 
			
		||||
`timestamp` property. These consist of the following
 | 
			
		||||
 | 
			
		||||
* `pino.stdTimeFunctions.epochTime`: Milliseconds since Unix epoch (Default)
 | 
			
		||||
* `pino.stdTimeFunctions.unixTime`: Seconds since Unix epoch
 | 
			
		||||
* `pino.stdTimeFunctions.nullTime`: Clears timestamp property (Used when `timestamp: false`)
 | 
			
		||||
* `pino.stdTimeFunctions.isoTime`: ISO 8601-formatted time in UTC
 | 
			
		||||
 | 
			
		||||
* See [`timestamp` option](#opt-timestamp)
 | 
			
		||||
 | 
			
		||||
<a id="pino-symbols"></a>
 | 
			
		||||
### `pino.symbols` (Object)
 | 
			
		||||
 | 
			
		||||
For integration purposes with ecosystem and third party libraries `pino.symbols`
 | 
			
		||||
exposes the symbols used to hold non-public state and methods on the logger instance.
 | 
			
		||||
 | 
			
		||||
Access to the symbols allows logger state to be adjusted, and methods to be overridden or
 | 
			
		||||
proxied for performant integration where necessary.
 | 
			
		||||
 | 
			
		||||
The `pino.symbols` object is intended for library implementers and shouldn't be utilized
 | 
			
		||||
for general use.
 | 
			
		||||
 | 
			
		||||
<a id="pino-version"></a>
 | 
			
		||||
### `pino.version` (String)
 | 
			
		||||
 | 
			
		||||
Exposes the Pino package version. Also available on the logger instance.
 | 
			
		||||
 | 
			
		||||
* See [`logger.version`](#version)
 | 
			
		||||
 | 
			
		||||
<a id="pino-log_version"></a>
 | 
			
		||||
### `pino.LOG_VERSION` (Number)
 | 
			
		||||
 | 
			
		||||
Holds the current log format version as output in the `v` property of each log record. Also available on the logger instance.
 | 
			
		||||
 | 
			
		||||
* See [`logger.LOG_VERSION`](#log_version)
 | 
			
		||||
							
								
								
									
										58
									
								
								node_modules/pino/docs/benchmarks.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								node_modules/pino/docs/benchmarks.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
# Benchmarks
 | 
			
		||||
 | 
			
		||||
`pino.info('hello world')`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
BASIC benchmark averages
 | 
			
		||||
Bunyan average: 549.042ms
 | 
			
		||||
Winston average: 467.873ms
 | 
			
		||||
Bole average: 201.529ms
 | 
			
		||||
Debug average: 253.724ms
 | 
			
		||||
LogLevel average: 282.653ms
 | 
			
		||||
Pino average: 188.956ms
 | 
			
		||||
PinoExtreme average: 108.809ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`pino.info({'hello': 'world'})`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
OBJECT benchmark averages
 | 
			
		||||
BunyanObj average: 564.363ms
 | 
			
		||||
WinstonObj average: 464.824ms
 | 
			
		||||
BoleObj average: 230.220ms
 | 
			
		||||
LogLevelObject average: 474.857ms
 | 
			
		||||
PinoObj average: 201.442ms
 | 
			
		||||
PinoUnsafeObj average: 202.687ms
 | 
			
		||||
PinoExtremeObj average: 108.689ms
 | 
			
		||||
PinoUnsafeExtremeObj average: 106.718ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`pino.info(aBigDeeplyNestedObject)`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
DEEPOBJECT benchmark averages
 | 
			
		||||
BunyanDeepObj average: 5293.279ms
 | 
			
		||||
WinstonDeepObj average: 9020.292ms
 | 
			
		||||
BoleDeepObj average: 9169.043ms
 | 
			
		||||
LogLevelDeepObj average: 15260.917ms
 | 
			
		||||
PinoDeepObj average: 8467.807ms
 | 
			
		||||
PinoUnsafeDeepObj average: 6159.227ms
 | 
			
		||||
PinoExtremeDeepObj average: 8354.557ms
 | 
			
		||||
PinoUnsafeExtremeDeepObj average: 6214.073ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`pino.info('hello %s %j %d', 'world', {obj: true}, 4, {another: 'obj'})`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
BunyanInterpolateExtra average: 778.408ms
 | 
			
		||||
WinstonInterpolateExtra average: 627.956ms
 | 
			
		||||
BoleInterpolateExtra average: 429.757ms
 | 
			
		||||
PinoInterpolateExtra average: 316.043ms
 | 
			
		||||
PinoUnsafeInterpolateExtra average: 316.809ms
 | 
			
		||||
PinoExtremeInterpolateExtra average: 218.468ms
 | 
			
		||||
PinoUnsafeExtremeInterpolateExtra average: 215.040ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For a fair comparison, [LogLevel](http://npm.im/loglevel) was extended
 | 
			
		||||
to include a timestamp and [bole](http://npm.im/bole) had
 | 
			
		||||
`fastTime` mode switched on.
 | 
			
		||||
							
								
								
									
										199
									
								
								node_modules/pino/docs/browser.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								node_modules/pino/docs/browser.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,199 @@
 | 
			
		|||
# Browser API
 | 
			
		||||
 | 
			
		||||
Pino is compatible with [`browserify`](http://npm.im/browserify) for browser side usage:
 | 
			
		||||
 | 
			
		||||
This can be useful with isomorphic/universal JavaScript code.
 | 
			
		||||
 | 
			
		||||
By default, in the browser,
 | 
			
		||||
`pino` uses corresponding [Log4j](https://en.wikipedia.org/wiki/Log4j) `console` methods (`console.error`, `console.warn`, `console.info`, `console.debug`, `console.trace`) and uses `console.error` for any `fatal` level logs.
 | 
			
		||||
 | 
			
		||||
## Options
 | 
			
		||||
 | 
			
		||||
Pino can be passed a `browser` object in the options object,
 | 
			
		||||
which can have the following properties:
 | 
			
		||||
 | 
			
		||||
### `asObject` (Boolean)
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({browser: {asObject: true}})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `asObject` option will create a pino-like log object instead of
 | 
			
		||||
passing all arguments to a console method, for instance:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
pino.info('hi') // creates and logs {msg: 'hi', level: 30, time: <ts>}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When `write` is set, `asObject` will always be `true`.
 | 
			
		||||
 | 
			
		||||
### `write` (Function | Object)
 | 
			
		||||
 | 
			
		||||
Instead of passing log messages to `console.log` they can be passed to
 | 
			
		||||
a supplied function.
 | 
			
		||||
 | 
			
		||||
If `write` is set to a single function, all logging objects are passed
 | 
			
		||||
to this function.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  browser: {
 | 
			
		||||
    write: (o) => {
 | 
			
		||||
      // do something with o
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If `write` is an object, it can have methods that correspond to the
 | 
			
		||||
levels. When a message is logged at a given level, the corresponding
 | 
			
		||||
method is called. If a method isn't present, the logging falls back
 | 
			
		||||
to using the `console`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  browser: {
 | 
			
		||||
    write: {
 | 
			
		||||
      info: function (o) {
 | 
			
		||||
        //process info log object
 | 
			
		||||
      },
 | 
			
		||||
      error: function (o) {
 | 
			
		||||
        //process error log object
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `serialize`: (Boolean | Array)
 | 
			
		||||
 | 
			
		||||
The serializers provided to `pino` are ignored by default in the browser, including
 | 
			
		||||
the standard serializers provided with Pino. Since the default destination for log
 | 
			
		||||
messages is the console, values such as `Error` objects are enhanced for inspection,
 | 
			
		||||
which they otherwise wouldn't be if the Error serializer was enabled.
 | 
			
		||||
 | 
			
		||||
We can turn all serializers on,
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  browser: {
 | 
			
		||||
    serialize: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or we can selectively enable them via an array:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  serializers: {
 | 
			
		||||
    custom: myCustomSerializer,
 | 
			
		||||
    another: anotherSerializer
 | 
			
		||||
  },
 | 
			
		||||
  browser: {
 | 
			
		||||
    serialize: ['custom']
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
// following will apply myCustomSerializer to the custom property,
 | 
			
		||||
// but will not apply anotherSerializer to another key
 | 
			
		||||
pino.info({custom: 'a', another: 'b'})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When `serialize` is `true` the standard error serializer is also enabled (see https://github.com/pinojs/pino/blob/master/docs/api.md#stdSerializers).
 | 
			
		||||
This is a global serializer which will apply to any `Error` objects passed to the logger methods.
 | 
			
		||||
 | 
			
		||||
If `serialize` is an array the standard error serializer is also automatically enabled, it can
 | 
			
		||||
be explicitly disabled by including a string in the serialize array: `!stdSerializers.err`, like so:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  serializers: {
 | 
			
		||||
    custom: myCustomSerializer,
 | 
			
		||||
    another: anotherSerializer
 | 
			
		||||
  },
 | 
			
		||||
  browser: {
 | 
			
		||||
    serialize: ['!stdSerializers.err', 'custom'] //will not serialize Errors, will serialize `custom` keys
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `serialize` array also applies to any child logger serializers (see https://github.com/pinojs/pino/blob/master/docs/api.md#discussion-2
 | 
			
		||||
for how to set child-bound serializers).
 | 
			
		||||
 | 
			
		||||
Unlike server pino the serializers apply to every object passed to the logger method,
 | 
			
		||||
if the `asObject` option is `true`, this results in the serializers applying to the
 | 
			
		||||
first object (as in server pino).
 | 
			
		||||
 | 
			
		||||
For more info on serializers see https://github.com/pinojs/pino/blob/master/docs/api.md#parameters.
 | 
			
		||||
 | 
			
		||||
### `transmit` (Object)
 | 
			
		||||
 | 
			
		||||
An object with `send` and `level` properties.
 | 
			
		||||
 | 
			
		||||
The `transmit.level` property specifies the minimum level (inclusive) of when the `send` function
 | 
			
		||||
should be called, if not supplied the `send` function be called based on the main logging `level`
 | 
			
		||||
(set via `options.level`, defaulting to `info`).
 | 
			
		||||
 | 
			
		||||
The `transmit` object must have a `send` function which will be called after
 | 
			
		||||
writing the log message. The `send` function is passed the level of the log
 | 
			
		||||
message and a `logEvent` object.
 | 
			
		||||
 | 
			
		||||
The `logEvent` object is a data structure representing a log message, it represents
 | 
			
		||||
the arguments passed to a logger statement, the level
 | 
			
		||||
at which they were logged and the hierarchy of child bindings.
 | 
			
		||||
 | 
			
		||||
The `logEvent` format is structured like so:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{
 | 
			
		||||
  ts = Number,
 | 
			
		||||
  messages = Array,
 | 
			
		||||
  bindings = Array,
 | 
			
		||||
  level: { label = String, value = Number}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `ts` property is a unix epoch timestamp in milliseconds, the time is taken from the moment the
 | 
			
		||||
logger method is called.
 | 
			
		||||
 | 
			
		||||
The `messages` array is all arguments passed to logger method, (for instance `logger.info('a', 'b', 'c')`
 | 
			
		||||
would result in `messages` array `['a', 'b', 'c']`).
 | 
			
		||||
 | 
			
		||||
The `bindings` array represents each child logger (if any), and the relevant bindings.
 | 
			
		||||
For instance given `logger.child({a: 1}).child({b: 2}).info({c: 3})`, the bindings array
 | 
			
		||||
would hold `[{a: 1}, {b: 2}]` and the `messages` array would be `[{c: 3}]`. The `bindings`
 | 
			
		||||
are ordered according to their position in the child logger hierarchy, with the lowest index
 | 
			
		||||
being the top of the hierarchy.
 | 
			
		||||
 | 
			
		||||
By default serializers are not applied to log output in the browser, but they will *always* be
 | 
			
		||||
applied to `messages` and `bindings` in the `logEvent` object. This allows us to ensure a consistent
 | 
			
		||||
format for all values between server and client.
 | 
			
		||||
 | 
			
		||||
The `level` holds the label (for instance `info`), and the corresponding numerical value
 | 
			
		||||
(for instance `30`). This could be important in cases where client side level values and
 | 
			
		||||
labels differ from server side.
 | 
			
		||||
 | 
			
		||||
The point of the `send` function is to remotely record log messages:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')({
 | 
			
		||||
  browser: {
 | 
			
		||||
    transmit: {
 | 
			
		||||
      level: 'warn',
 | 
			
		||||
      send: function (level, logEvent) {
 | 
			
		||||
        if (level === 'warn') {
 | 
			
		||||
          // maybe send the logEvent to a separate endpoint
 | 
			
		||||
          // or maybe analyse the messages further before sending
 | 
			
		||||
        }
 | 
			
		||||
        // we could also use the `logEvent.level.value` property to determine
 | 
			
		||||
        // numerical value
 | 
			
		||||
        if (logEvent.level.value >= 50) { // covers error and fatal
 | 
			
		||||
 | 
			
		||||
          // send the logEvent somewhere
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										95
									
								
								node_modules/pino/docs/child-loggers.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								node_modules/pino/docs/child-loggers.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
# 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","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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","v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										72
									
								
								node_modules/pino/docs/ecosystem.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								node_modules/pino/docs/ecosystem.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
# Pino Ecosystem
 | 
			
		||||
 | 
			
		||||
This is a list of ecosystem modules that integrate with `pino`.
 | 
			
		||||
 | 
			
		||||
Modules listed under [Core](#core) are maintained by the Pino team. Modules
 | 
			
		||||
listed under [Community](#community) are maintained by independent community
 | 
			
		||||
members.
 | 
			
		||||
 | 
			
		||||
Please send a PR to add new modules!
 | 
			
		||||
 | 
			
		||||
<a id="core"></a>
 | 
			
		||||
## Core
 | 
			
		||||
 | 
			
		||||
+ [`express-pino-logger`](https://github.com/pinojs/express-pino-logger): use
 | 
			
		||||
Pino to log requests within [express](https://expressjs.com/).
 | 
			
		||||
+ [`koa-pino-logger`](https://github.com/pinojs/koa-pino-logger): use Pino to
 | 
			
		||||
log requests within [Koa](http://koajs.com/).
 | 
			
		||||
+ [`pino-arborsculpture`](https://github.com/pinojs/pino-arborsculpture): change
 | 
			
		||||
log levels at runtime.
 | 
			
		||||
+ [`pino-caller`](https://github.com/pinojs/pino-caller): add callsite to the log line.
 | 
			
		||||
+ [`pino-clf`](https://github.com/pinojs/pino-clf): reformat Pino logs into
 | 
			
		||||
Common Log Format.
 | 
			
		||||
+ [`pino-debug`](https://github.com/pinojs/pino-debug): use Pino to interpret
 | 
			
		||||
[`debug`](https://npm.im/debug) logs.
 | 
			
		||||
+ [`pino-elasticsearch`](https://github.com/pinojs/pino-elasticsearch): send
 | 
			
		||||
Pino logs to an Elasticsearch instance.
 | 
			
		||||
+ [`pino-eventhub`](https://github.com/pinojs/pino-eventhub): send Pino logs
 | 
			
		||||
to an [Event Hub](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-what-is-event-hubs).
 | 
			
		||||
+ [`pino-filter`](https://github.com/pinojs/pino-filter): filter Pino logs in
 | 
			
		||||
the same fashion as the [`debug`](https://npm.im/debug) module.
 | 
			
		||||
+ [`pino-gelf`](https://github.com/pinojs/pino-gelf): reformat Pino logs into
 | 
			
		||||
GELF format for Graylog.
 | 
			
		||||
+ [`pino-hapi`](https://github.com/pinojs/hapi-pino): use Pino as the logger
 | 
			
		||||
for [Hapi](https://hapijs.com/).
 | 
			
		||||
+ [`pino-http`](https://github.com/pinojs/pino-http): easily use Pino to log
 | 
			
		||||
requests with the core `http` module.
 | 
			
		||||
+ [`pino-http-print`](https://github.com/pinojs/pino-http-print): reformat Pino
 | 
			
		||||
logs into traditional [HTTPD](https://httpd.apache.org/) style request logs.
 | 
			
		||||
+ [`pino-multi-stream`](https://github.com/pinojs/pino-multi-stream): send
 | 
			
		||||
logs to multiple destination streams (slow!).
 | 
			
		||||
+ [`pino-mongodb`](https://github.com/pinojs/pino-mongodb): store Pino logs
 | 
			
		||||
in a MongoDB database.
 | 
			
		||||
+ [`pino-noir`](https://github.com/pinojs/pino-noir): redact sensitive information
 | 
			
		||||
in logs.
 | 
			
		||||
+ [`pino-pretty`](https://github.com/pinojs/pino-pretty): basic prettifier to
 | 
			
		||||
make log lines human readable.
 | 
			
		||||
+ [`pino-socket`](https://github.com/pinojs/pino-socket): send logs to TCP or UDP
 | 
			
		||||
destinations.
 | 
			
		||||
+ [`pino-std-serializers`](https://github.com/pinojs/pino-std-serializers): the
 | 
			
		||||
core object serializers used within Pino.
 | 
			
		||||
+ [`pino-syslog`](https://github.com/pinojs/pino-syslog): reformat Pino logs
 | 
			
		||||
to standard syslog format.
 | 
			
		||||
+ [`pino-tee`](https://github.com/pinojs/pino-tee): pipe Pino logs into files
 | 
			
		||||
based upon log levels.
 | 
			
		||||
+ [`pino-toke`](https://github.com/pinojs/pino-toke): reformat Pino logs
 | 
			
		||||
according to a given format string.
 | 
			
		||||
+ [`restify-pino-logger`](https://github.com/pinojs/restify-pino-logger): use
 | 
			
		||||
Pino to log requests within [restify](http://restify.com/).
 | 
			
		||||
+ [`rill-pino-logger`](https://github.com/pinojs/rill-pino-logger): use Pino as
 | 
			
		||||
the logger for the [Rill framework](https://rill.site/).
 | 
			
		||||
 | 
			
		||||
<a id="community"></a>
 | 
			
		||||
## Community
 | 
			
		||||
 | 
			
		||||
+ [`pino-colada`](https://github.com/lrlna/pino-colada): cute ndjson formatter for pino.
 | 
			
		||||
+ [`pino-fluentd`](https://github.com/davidedantonio/pino-fluentd): send Pino logs to Elasticsearch, 
 | 
			
		||||
MongoDB and many [others](https://www.fluentd.org/dataoutputs) via Fluentd.
 | 
			
		||||
+ [`pino-pretty-min`](https://github.com/unjello/pino-pretty-min): a minimal
 | 
			
		||||
prettifier inspired by the [logrus](https://github.com/sirupsen/logrus) logger.
 | 
			
		||||
+ [`pino-rotating-file`](https://github.com/homeaway/pino-rotating-file): a hapi-pino log transport for splitting logs into separate, automatically rotating files.
 | 
			
		||||
+ [`cls-proxify`](https://github.com/keenondrums/cls-proxify): integration of pino and [CLS](https://github.com/jeff-lewis/cls-hooked). Useful for creating dynamically configured child loggers (e.g. with added trace ID) for each request. 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										95
									
								
								node_modules/pino/docs/extreme.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								node_modules/pino/docs/extreme.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
# Extreme Mode
 | 
			
		||||
 | 
			
		||||
In essence, extreme mode enables even faster performance by Pino.
 | 
			
		||||
 | 
			
		||||
In Pino's standard mode of operation log messages are directly written to the
 | 
			
		||||
output stream as the messages are generated. Extreme mode works by buffering
 | 
			
		||||
log messages and writing them in larger chunks.
 | 
			
		||||
 | 
			
		||||
## Caveats
 | 
			
		||||
 | 
			
		||||
This has a couple of important caveats:
 | 
			
		||||
 | 
			
		||||
* 4KB of spare RAM will be needed for logging
 | 
			
		||||
* As opposed to the default mode, there is not a one-to-one relationship between
 | 
			
		||||
  calls to logging methods (e.g. `logger.info`) and writes to a log file
 | 
			
		||||
* There is a possibility of the most recently buffered log messages being lost
 | 
			
		||||
  (up to 4KB of logs)
 | 
			
		||||
  * For instance, a power cut will mean up to 4KB of buffered logs will be lost
 | 
			
		||||
 | 
			
		||||
So in summary, only use extreme mode when performing an extreme amount of
 | 
			
		||||
logging and it is acceptable to potentially lose the most recent logs.
 | 
			
		||||
 | 
			
		||||
* Pino will register handlers for the following process events/signals so that
 | 
			
		||||
  Pino can flush the extreme mode buffer:
 | 
			
		||||
 | 
			
		||||
  + `beforeExit`
 | 
			
		||||
  + `exit`
 | 
			
		||||
  + `uncaughtException`
 | 
			
		||||
  + `SIGHUP`
 | 
			
		||||
  + `SIGINT`
 | 
			
		||||
  + `SIGQUIT`
 | 
			
		||||
  + `SIGTERM`
 | 
			
		||||
 | 
			
		||||
  In all of these cases, except `SIGHUP`, the process is in a state that it
 | 
			
		||||
  *must* terminate. Thus, if an `onTerminated` function isn't registered when
 | 
			
		||||
  constructing a Pino instance (see [pino#constructor](api.md#constructor)),
 | 
			
		||||
  then Pino will invoke `process.exit(0)` when no error has occurred, or
 | 
			
		||||
  `process.exit(1)` otherwise. If an `onTerminated` function is supplied, it
 | 
			
		||||
  is the responsibility of the `onTerminated` function to manually exit the process.
 | 
			
		||||
 | 
			
		||||
  In the case of `SIGHUP`, we will look to see if any other handlers are
 | 
			
		||||
  registered for the event. If not, we will proceed as we do with all other
 | 
			
		||||
  signals. If there are more handlers registered than just our own, we will
 | 
			
		||||
  simply flush the extreme mode buffer.
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
The `pino.extreme()` method will provide an Extreme Mode destination.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')
 | 
			
		||||
const dest = pino.extreme() // logs to stdout with no args
 | 
			
		||||
const logger = pino(dest)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id='log-loss-prevention'></a>
 | 
			
		||||
## Log loss prevention
 | 
			
		||||
 | 
			
		||||
The following strategy can be used to minimize log loss:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')
 | 
			
		||||
const dest = pino.extreme() // no arguments
 | 
			
		||||
const logger = pino(dest)
 | 
			
		||||
 | 
			
		||||
// asynchronously flush every 10 seconds to keep the buffer empty
 | 
			
		||||
// in periods of low activity
 | 
			
		||||
setInterval(function () {
 | 
			
		||||
  logger.flush()
 | 
			
		||||
}, 10000).unref()
 | 
			
		||||
 | 
			
		||||
// use pino.final to create a special logger that
 | 
			
		||||
// guarantees final tick writes
 | 
			
		||||
const handler = pino.final(logger, (err, finalLogger, evt) => {
 | 
			
		||||
  finalLogger.info(`${evt} caught`)
 | 
			
		||||
  if (err) finalLogger.error(err, 'error caused exit')
 | 
			
		||||
  process.exit(err ? 1 : 0)
 | 
			
		||||
})
 | 
			
		||||
// catch all the ways node might exit
 | 
			
		||||
process.on('beforeExit', () => handler(null, 'beforeExit'))
 | 
			
		||||
process.on('exit', () => handler(null, 'exit'))
 | 
			
		||||
process.on('uncaughtException', (err) => handler(err, 'uncaughtException'))
 | 
			
		||||
process.on('SIGINT', () => handler(null, 'SIGINT'))
 | 
			
		||||
process.on('SIGQUIT', () => handler(null, 'SIGQUIT'))
 | 
			
		||||
process.on('SIGTERM', () => handler(null, 'SIGTERM'))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
An extreme destination is an instance of
 | 
			
		||||
[`SonicBoom`](https://github.com/mcollina/sonic-boom) with `4096`
 | 
			
		||||
buffering.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* See [`pino.extreme` api](/docs/api.md#pino-extreme)
 | 
			
		||||
* See [`pino.final` api](/docs/api.md#pino-final)
 | 
			
		||||
* See [`destination` parameter](/docs/api.md#destination)
 | 
			
		||||
							
								
								
									
										215
									
								
								node_modules/pino/docs/help.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								node_modules/pino/docs/help.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,215 @@
 | 
			
		|||
# Help
 | 
			
		||||
 | 
			
		||||
* [Exit logging](#exit-logging)
 | 
			
		||||
* [Log rotation](#rotate)
 | 
			
		||||
* [Reopening log files](#reopening)
 | 
			
		||||
* [Saving to multiple files](#multiple)
 | 
			
		||||
* [Log filtering](#filter-logs)
 | 
			
		||||
* [Transports and systemd](#transport-systemd)
 | 
			
		||||
* [Duplicate keys](#dupe-keys)
 | 
			
		||||
* [Log levels as labels instead of numbers](#level-string)
 | 
			
		||||
* [Pino with `debug`](#debug)
 | 
			
		||||
* [Unicode and Windows terminal](#windows)
 | 
			
		||||
 | 
			
		||||
<a id="exit-logging"></a>
 | 
			
		||||
## Exit logging
 | 
			
		||||
 | 
			
		||||
When a Node process crashes from uncaught exception, exits due to a signal,
 | 
			
		||||
or exits of it's own accord we may want to write some final logs – particularly
 | 
			
		||||
in cases of error.
 | 
			
		||||
 | 
			
		||||
Writing to a Node.js stream on exit is not necessarily guaranteed, and naively writing
 | 
			
		||||
to an Extreme Mode logger on exit will definitely lead to lost logs.
 | 
			
		||||
 | 
			
		||||
To write logs in an exit handler, create the handler with [`pino.final`](/docs/api.md#pino-final):
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
process.on('uncaughtException', pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
  finalLogger.error(err, 'uncaughtException')
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
process.on('unhandledRejection', pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
  finalLogger.error(err, 'unhandledRejection')
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
}))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `finalLogger` is a special logger instance that will synchronously and reliably
 | 
			
		||||
flush every log line. This is important in exit handlers, since no more asynchronous
 | 
			
		||||
activity may be scheduled.
 | 
			
		||||
 | 
			
		||||
<a id="rotate"></a>
 | 
			
		||||
## Log rotation
 | 
			
		||||
 | 
			
		||||
Use a separate tool for log rotation:
 | 
			
		||||
We recommend [logrotate](https://github.com/logrotate/logrotate).
 | 
			
		||||
Consider we output our logs to `/var/log/myapp.log` like so:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ node server.js > /var/log/myapp.log
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
We would rotate our log files with logrotate, by adding the following to `/etc/logrotate.d/myapp`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
/var/log/myapp.log {
 | 
			
		||||
       su root
 | 
			
		||||
       daily
 | 
			
		||||
       rotate 7
 | 
			
		||||
       delaycompress
 | 
			
		||||
       compress
 | 
			
		||||
       notifempty
 | 
			
		||||
       missingok
 | 
			
		||||
       copytruncate
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `copytruncate` configuration has a very slight possibility of lost log lines due
 | 
			
		||||
to a gap between copying and truncating - the truncate may occur after additional lines
 | 
			
		||||
have been written. To perform log rotation without `copytruncate`, see the [Reopening log files](#reopening)
 | 
			
		||||
help.
 | 
			
		||||
 | 
			
		||||
<a id="reopening"></a>
 | 
			
		||||
## Reopening log files
 | 
			
		||||
 | 
			
		||||
In cases where a log rotation tool doesn't offer a copy-truncate capabilities,
 | 
			
		||||
or where using them is deemed inappropriate `pino.destination` and `pino.extreme`
 | 
			
		||||
destinations are able to reopen file paths after a file has been moved away.
 | 
			
		||||
 | 
			
		||||
One way to use this is to set up a `SIGUSR2` or `SIGHUP` signal handler that
 | 
			
		||||
reopens the log file destination, making sure to write the process PID out
 | 
			
		||||
somewhere so the log rotation tool knows where to send the signal.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// write the process pid to a well known location for later
 | 
			
		||||
const fs = require('fs')
 | 
			
		||||
fs.writeFileSync('/var/run/myapp.pid', process.pid)
 | 
			
		||||
 | 
			
		||||
const dest = pino.destination('/log/file') // pino.extreme will also work
 | 
			
		||||
const logger = require('pino')(dest)
 | 
			
		||||
process.on('SIGHUP', () => dest.reopen())
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The log rotation tool can then be configured to send this signal to the process
 | 
			
		||||
after a log rotation event has occurred.
 | 
			
		||||
 | 
			
		||||
Given a similar scenario as in the [Log rotation](#rotate) section a basic
 | 
			
		||||
`logrotate` config that aligns with this strategy would look similar to the following:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
/var/log/myapp.log {
 | 
			
		||||
       su root
 | 
			
		||||
       daily
 | 
			
		||||
       rotate 7
 | 
			
		||||
       delaycompress
 | 
			
		||||
       compress
 | 
			
		||||
       notifempty
 | 
			
		||||
       missingok
 | 
			
		||||
       postrotate
 | 
			
		||||
           kill -HUP `cat /var/run/myapp.pid`
 | 
			
		||||
       endscript
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="multiple"></a>
 | 
			
		||||
## Saving to multiple files
 | 
			
		||||
 | 
			
		||||
Let's assume we want to store all error messages to a separate log file.
 | 
			
		||||
 | 
			
		||||
Install [pino-tee](http://npm.im/pino-tee) with:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npm i pino-tee -g
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The following writes the log output of `app.js` to `./all-logs`, while
 | 
			
		||||
writing only warnings and errors to `./warn-log:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node app.js | pino-tee warn ./warn-logs > ./all-logs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="filter-logs"></a>
 | 
			
		||||
## Log Filtering
 | 
			
		||||
The Pino philosophy advocates common, pre-existing, system utilities.
 | 
			
		||||
 | 
			
		||||
Some recommendations in line with this philosophy are:
 | 
			
		||||
 | 
			
		||||
1. Use [`grep`](https://linux.die.net/man/1/grep):
 | 
			
		||||
    ```sh
 | 
			
		||||
    $ # View all "INFO" level logs
 | 
			
		||||
    $ node app.js | grep '"level":30'
 | 
			
		||||
    ```
 | 
			
		||||
1. Use [`jq`](https://stedolan.github.io/jq/):
 | 
			
		||||
    ```sh
 | 
			
		||||
    $ # View all "ERROR" level logs
 | 
			
		||||
    $ node app.js | jq 'select(.level == 50)'
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
<a id="transport-systemd"></a>
 | 
			
		||||
## Transports and systemd
 | 
			
		||||
`systemd` makes it complicated to use pipes in services. One method for overcoming
 | 
			
		||||
this challenge is to use a subshell:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
ExecStart=/bin/sh -c '/path/to/node app.js | pino-transport'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<a id="dupe-keys"></a>
 | 
			
		||||
## How Pino handles duplicate keys
 | 
			
		||||
 | 
			
		||||
Duplicate keys are possibly when a child logger logs an object with a key that
 | 
			
		||||
collides with a key in the child loggers bindings.
 | 
			
		||||
 | 
			
		||||
See the [child logger duplicate keys caveat](/docs/child-loggers.md#duplicate-keys-caveat)
 | 
			
		||||
for information on this is handled.
 | 
			
		||||
 | 
			
		||||
<a id="level-string"></a>
 | 
			
		||||
## Log levels as labels instead of numbers
 | 
			
		||||
Pino log lines are meant to be parseable. Thus, Pino's default mode of operation
 | 
			
		||||
is to print the level value instead of the string name. However, while it is
 | 
			
		||||
possible to set the `useLevelLabels` option, we recommend using one of these
 | 
			
		||||
options instead if you are able:
 | 
			
		||||
 | 
			
		||||
1. If the only change desired is the name then a transport can be used. One such
 | 
			
		||||
transport is [`pino-text-level-transport`](https://npm.im/pino-text-level-transport).
 | 
			
		||||
1. Use a prettifier like [`pino-pretty`](https://npm.im/pino-pretty) to make
 | 
			
		||||
the logs human friendly.
 | 
			
		||||
 | 
			
		||||
<a id="debug"></a>
 | 
			
		||||
## Pino with `debug`
 | 
			
		||||
 | 
			
		||||
The popular [`debug`](http://npm.im/debug) is used in many modules across the ecosystem.
 | 
			
		||||
 | 
			
		||||
The [`pino-debug`](http://github.com/pinojs/pino-debug) module
 | 
			
		||||
can capture calls to `debug` loggers and run them
 | 
			
		||||
through `pino` instead. This results in a 10x (20x in extreme mode)
 | 
			
		||||
performance improvement - even though `pino-debug` is logging additional
 | 
			
		||||
data and wrapping it in JSON.
 | 
			
		||||
 | 
			
		||||
To quickly enable this install [`pino-debug`](http://github.com/pinojs/pino-debug)
 | 
			
		||||
and preload it with the `-r` flag, enabling any `debug` logs with the
 | 
			
		||||
`DEBUG` environment variable:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ npm i pino-debug
 | 
			
		||||
$ DEBUG=* node -r pino-debug app.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[`pino-debug`](http://github.com/pinojs/pino-debug) also offers fine grain control to map specific `debug`
 | 
			
		||||
namespaces to `pino` log levels. See [`pino-debug`](http://github.com/pinojs/pino-debug)
 | 
			
		||||
for more.
 | 
			
		||||
 | 
			
		||||
<a id="windows"></a>
 | 
			
		||||
## Unicode and Windows terminal
 | 
			
		||||
 | 
			
		||||
Pino uses [sonic-boom](https://github.com/mcollina/sonic-boom) to speed
 | 
			
		||||
up logging. Internally, it uses [`fs.write`](https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_write_fd_string_position_encoding_callback) to write log lines directly to a file
 | 
			
		||||
descriptor. On Windows, unicode output is not handled properly in the
 | 
			
		||||
terminal (both `cmd.exe` and powershell), and as such the output could
 | 
			
		||||
be visualized incorrectly if the log lines include utf8 characters. It
 | 
			
		||||
is possible to configure the terminal to visualize those characters
 | 
			
		||||
correctly with the use of [`chcp`](https://ss64.com/nt/chcp.html) by
 | 
			
		||||
executing in the terminal `chcp 65001`. This is a known limitation of
 | 
			
		||||
Node.js.
 | 
			
		||||
							
								
								
									
										167
									
								
								node_modules/pino/docs/legacy.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								node_modules/pino/docs/legacy.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,167 @@
 | 
			
		|||
# Legacy
 | 
			
		||||
 | 
			
		||||
## Legacy Node Support
 | 
			
		||||
 | 
			
		||||
### Node v4
 | 
			
		||||
 | 
			
		||||
Node v4 is supported on the [Pino v4](#pino-v4-documentation) line.
 | 
			
		||||
 | 
			
		||||
### Node v0.10-v0.12
 | 
			
		||||
 | 
			
		||||
Node v0.10 or Node v0.12 is supported on the [Pino v2](#pino-v2-documentation) line.
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
### Pino v4 Documentation
 | 
			
		||||
 | 
			
		||||
<https://github.com/pinojs/pino/tree/v4.x.x/docs>
 | 
			
		||||
 | 
			
		||||
### Pino v3 Documentation
 | 
			
		||||
 | 
			
		||||
<https://github.com/pinojs/pino/tree/v3.x.x/docs>
 | 
			
		||||
 | 
			
		||||
### Pino v2 Documentation
 | 
			
		||||
 | 
			
		||||
<https://github.com/pinojs/pino/tree/v2.x.x/docs>
 | 
			
		||||
 | 
			
		||||
## Migration
 | 
			
		||||
 | 
			
		||||
### Pino v4 to to Pino v5
 | 
			
		||||
 | 
			
		||||
#### Logging Destination
 | 
			
		||||
 | 
			
		||||
In Pino v4 the destination could be set by passing a stream as the
 | 
			
		||||
second parameter to the exported `pino` function. This is still the
 | 
			
		||||
case in v5. However it's strongly recommended to use `pino.destination`
 | 
			
		||||
which will write logs ~30% faster.
 | 
			
		||||
 | 
			
		||||
##### v4
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const stdoutLogger = require('pino')()
 | 
			
		||||
const stderrLogger = require('pino')(process.stderr)
 | 
			
		||||
const fileLogger = require('pino')(fs.createWriteStream('/log/path'))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### v5
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const stdoutLogger = require('pino')() // pino.destination by default
 | 
			
		||||
const stderrLogger = require('pino')(pino.destination(2))
 | 
			
		||||
const fileLogger = require('pino')(pino.destination('/log/path'))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note: This is not a breaking change, `WritableStream` instances are still
 | 
			
		||||
supported, but are slower than `pino.destination` which
 | 
			
		||||
uses the high speed [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom) library.
 | 
			
		||||
 | 
			
		||||
* See [`destination` parameter](/docs/api.md#destination)
 | 
			
		||||
 | 
			
		||||
#### Extreme Mode
 | 
			
		||||
 | 
			
		||||
The `extreme` setting does not exist as an option in Pino v5, instead use
 | 
			
		||||
a `pino.extreme` destination.
 | 
			
		||||
 | 
			
		||||
##### v4
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const stdoutLogger = require('pino')({extreme: true})
 | 
			
		||||
const stderrLogger = require('pino')({extreme: true}, process.stderr)
 | 
			
		||||
const fileLogger = require('pino')({extreme: true}, fs.createWriteStream('/log/path'))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### v5
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const stdoutLogger = require('pino')(pino.extreme())
 | 
			
		||||
const stderrLogger = require('pino')(pino.extreme(2))
 | 
			
		||||
const fileLogger = require('pino')(pino.extreme('/log/path'))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [pino.extreme](/docs/api.md#pino-extreme)
 | 
			
		||||
* See [Extreme mode ⇗](/docs/extreme.md)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Pino CLI is now pino-pretty CLI
 | 
			
		||||
 | 
			
		||||
The Pino CLI is provided with Pino v4 for basic log prettification.
 | 
			
		||||
 | 
			
		||||
From Pino v5 the CLI is installed separately with `pino-pretty`.
 | 
			
		||||
 | 
			
		||||
##### v4
 | 
			
		||||
```sh
 | 
			
		||||
$ npm install -g pino
 | 
			
		||||
$ node app.js | pino
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### v5
 | 
			
		||||
```sh
 | 
			
		||||
$ npm install -g pino-pretty
 | 
			
		||||
$ node app.js | pino-pretty
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [Pretty Printing documentation](/docs/pretty.md)
 | 
			
		||||
 | 
			
		||||
#### Programmatic Pretty Printing
 | 
			
		||||
 | 
			
		||||
The [`pino.pretty()`](https://github.com/pinojs/pino/blob/v4.x.x/docs/API.md#prettyoptions)
 | 
			
		||||
method has also been removed from Pino v5.
 | 
			
		||||
 | 
			
		||||
##### v4
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var pino = require('pino')
 | 
			
		||||
var pretty = pino.pretty()
 | 
			
		||||
pretty.pipe(process.stdout)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### v5
 | 
			
		||||
 | 
			
		||||
Instead use the `prettyPrint` option (also available in v4):
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')({
 | 
			
		||||
  prettyPrint: process.env.NODE_ENV !== 'production'
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In v5 the `pretty-print` module must be installed to use the `prettyPrint` option:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install --save-dev pino-pretty
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* See [prettyPrint option](/docs/api.md#prettyPrint)
 | 
			
		||||
* See [Pretty Printing documentation](/docs/pretty.md)
 | 
			
		||||
 | 
			
		||||
#### Slowtime
 | 
			
		||||
 | 
			
		||||
In Pino v4 a `slowtime` option was supplied, which allowed for full ISO dates
 | 
			
		||||
in the timestamps instead of milliseconds since the Epoch. In Pino v5 this
 | 
			
		||||
has been completely removed, along with the `pino.stdTimeFunctions.slowTime`
 | 
			
		||||
function. In order to achieve the equivalent in v5, a custom
 | 
			
		||||
time function should be supplied:
 | 
			
		||||
 | 
			
		||||
##### v4
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const pino = require('pino')
 | 
			
		||||
const logger = pino({slowtime: true})
 | 
			
		||||
// following avoids deprecation warning in v4:
 | 
			
		||||
const loggerAlt = pino({timestamp: pino.stdTimeFunctions.slowTime})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### v5
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('pino')({
 | 
			
		||||
  timestamp: () => ',"time":"' + (new Date()).toISOString() + '"'
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The practice of creating ISO dates in-process for logging purposes is strongly
 | 
			
		||||
recommended against. Instead consider post-processing the logs or using a transport
 | 
			
		||||
to convert the timestamps.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* See [timestamp option](/docs/api.md#timestamp)
 | 
			
		||||
							
								
								
									
										93
									
								
								node_modules/pino/docs/pretty.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								node_modules/pino/docs/pretty.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
# Pretty Printing
 | 
			
		||||
 | 
			
		||||
By default, Pino log lines are newline delimited JSON (NDJSON). This is perfect
 | 
			
		||||
for production usage and long term storage. It's not so great for development
 | 
			
		||||
environments. Thus, Pino logs can be prettified by using a Pino prettifier
 | 
			
		||||
module like [`pino-pretty`][pp]:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ cat app.log | pino-pretty
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For almost all situations, this is the recommended way to prettify logs. The
 | 
			
		||||
programmatic API, described in the next section, is primarily for integration
 | 
			
		||||
purposes with other CLI based prettifiers.
 | 
			
		||||
 | 
			
		||||
## Prettifier API
 | 
			
		||||
 | 
			
		||||
Pino prettifier modules are extra modules that provide a CLI for parsing NDJSON
 | 
			
		||||
log lines piped via `stdin` and expose an API which conforms to the Pino
 | 
			
		||||
[metadata streams](api.md#metadata) API.
 | 
			
		||||
 | 
			
		||||
The API requires modules provide a factory function which returns a prettifier
 | 
			
		||||
function. This prettifier function must accept either a string of NDJSON or
 | 
			
		||||
a Pino log object. A psuedo-example of such a prettifier is:
 | 
			
		||||
 | 
			
		||||
The uninitialized Pino instance is passed as `this` into prettifier factory function,
 | 
			
		||||
so it can be accessed via closure by the returned prettifier function.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
module.exports = function myPrettifier (options) {
 | 
			
		||||
  // `this` is bound to the pino instance
 | 
			
		||||
  // Deal with whatever options are supplied.
 | 
			
		||||
  return function prettifier (inputData) {
 | 
			
		||||
    let logObject
 | 
			
		||||
    if (typeof inputData === 'string') {
 | 
			
		||||
      const parsedData = someJsonParser(inputData)
 | 
			
		||||
      logObject = (isPinoLog(parsedData)) ? parsedData : undefined
 | 
			
		||||
    } else if (isObject(inputData) && isPinoLog(inputData)) {
 | 
			
		||||
      logObject = inputData
 | 
			
		||||
    }
 | 
			
		||||
    if (!logObject) return inputData
 | 
			
		||||
    // implement prettification
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function isObject (input) {
 | 
			
		||||
    return Object.prototype.toString.apply(input) === '[object Object]'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function isPinoLog (log) {
 | 
			
		||||
    return log && (log.hasOwnProperty('v') && log.v === 1)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The reference implementation of such a module is the [`pino-pretty`][pp] module.
 | 
			
		||||
To learn more about creating a custom prettifier module, refer to the
 | 
			
		||||
`pino-pretty` source code.
 | 
			
		||||
 | 
			
		||||
Note: if the prettifier returns `undefined`, instead of a formatted line, nothing
 | 
			
		||||
will be written to the destination stream.
 | 
			
		||||
 | 
			
		||||
### API Example
 | 
			
		||||
 | 
			
		||||
> #### NOTE:
 | 
			
		||||
> For general usage, it is highly recommended that logs are piped into
 | 
			
		||||
> the prettifier instead. Prettified logs are not easily parsed and cannot
 | 
			
		||||
> be easily investigated at a later date.
 | 
			
		||||
 | 
			
		||||
1. Install a prettifier module as a separate dependency, e.g. `npm install pino-pretty`.
 | 
			
		||||
1. Instantiate the logger with pretty printing enabled:
 | 
			
		||||
  ```js
 | 
			
		||||
  const pino = require('pino')
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    prettyPrint: {
 | 
			
		||||
      levelFirst: true
 | 
			
		||||
    },
 | 
			
		||||
    prettifier: require('pino-pretty')
 | 
			
		||||
  })
 | 
			
		||||
  ```
 | 
			
		||||
  Note: the default prettifier module is `pino-pretty`, so the preceding
 | 
			
		||||
  example could be:
 | 
			
		||||
  ```js
 | 
			
		||||
  const pino = require('pino')
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    prettyPrint: {
 | 
			
		||||
      levelFirst: true
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  ```
 | 
			
		||||
  See the [`pino-pretty` documentation][pp] for more information on the options
 | 
			
		||||
  that can be passed via `prettyPrint`.
 | 
			
		||||
 | 
			
		||||
  [pp]: https://github.com/pinojs/pino-pretty
 | 
			
		||||
							
								
								
									
										133
									
								
								node_modules/pino/docs/redaction.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								node_modules/pino/docs/redaction.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
# Redaction
 | 
			
		||||
 | 
			
		||||
> Redaction is not supported in the browser [#670](https://github.com/pinojs/pino/issues/670)
 | 
			
		||||
 | 
			
		||||
To redact sensitive information, supply paths to keys that hold sensitive data
 | 
			
		||||
using the `redact` option:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('.')({
 | 
			
		||||
  redact: ['key', 'path.to.key', 'stuff.thats[*].secret']
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
logger.info({
 | 
			
		||||
  key: 'will be redacted',
 | 
			
		||||
  path: {
 | 
			
		||||
    to: {key: 'sensitive', another: 'thing'}
 | 
			
		||||
  },
 | 
			
		||||
  stuff: {
 | 
			
		||||
    thats: [
 | 
			
		||||
      {secret: 'will be redacted', logme: 'will be logged'},
 | 
			
		||||
      {secret: 'as will this', logme: 'as will this'}
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This will output:
 | 
			
		||||
 | 
			
		||||
```JSON
 | 
			
		||||
{"level":30,"time":1527777350011,"pid":3186,"hostname":"Davids-MacBook-Pro-3.local","key":"[Redacted]","path":{"to":{"key":"[Redacted]","another":"thing"}},"stuff":{"thats":[{"secret":"[Redacted]","logme":"will be logged"},{"secret":"[Redacted]","logme":"as will this"}]},"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `redact` option can take an array (as shown in the above example) or
 | 
			
		||||
an object. This allows control over *how* information is redacted.
 | 
			
		||||
 | 
			
		||||
For instance, setting the censor:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('.')({
 | 
			
		||||
  redact: {
 | 
			
		||||
    paths: ['key', 'path.to.key', 'stuff.thats[*].secret'],
 | 
			
		||||
    censor: '**GDPR COMPLIANT**'
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
logger.info({
 | 
			
		||||
  key: 'will be redacted',
 | 
			
		||||
  path: {
 | 
			
		||||
    to: {key: 'sensitive', another: 'thing'}
 | 
			
		||||
  },
 | 
			
		||||
  stuff: {
 | 
			
		||||
    thats: [
 | 
			
		||||
      {secret: 'will be redacted', logme: 'will be logged'},
 | 
			
		||||
      {secret: 'as will this', logme: 'as will this'}
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This will output:
 | 
			
		||||
 | 
			
		||||
```JSON
 | 
			
		||||
{"level":30,"time":1527778563934,"pid":3847,"hostname":"Davids-MacBook-Pro-3.local","key":"**GDPR COMPLIANT**","path":{"to":{"key":"**GDPR COMPLIANT**","another":"thing"}},"stuff":{"thats":[{"secret":"**GDPR COMPLIANT**","logme":"will be logged"},{"secret":"**GDPR COMPLIANT**","logme":"as will this"}]},"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `redact.remove` option also allows for the key and value to be removed from output:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const logger = require('.')({
 | 
			
		||||
  redact: {
 | 
			
		||||
    paths: ['key', 'path.to.key', 'stuff.thats[*].secret'],
 | 
			
		||||
    remove: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
logger.info({
 | 
			
		||||
  key: 'will be redacted',
 | 
			
		||||
  path: {
 | 
			
		||||
    to: {key: 'sensitive', another: 'thing'}
 | 
			
		||||
  },
 | 
			
		||||
  stuff: {
 | 
			
		||||
    thats: [
 | 
			
		||||
      {secret: 'will be redacted', logme: 'will be logged'},
 | 
			
		||||
      {secret: 'as will this', logme: 'as will this'}
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This will output
 | 
			
		||||
 | 
			
		||||
```JSON
 | 
			
		||||
{"level":30,"time":1527782356751,"pid":5758,"hostname":"Davids-MacBook-Pro-3.local","path":{"to":{"another":"thing"}},"stuff":{"thats":[{"logme":"will be logged"},{"logme":"as will this"}]},"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See [pino options in API](/docs/api.md#redact-array-object) for `redact` API details.
 | 
			
		||||
 | 
			
		||||
<a name="paths"></a>
 | 
			
		||||
## Path Syntax
 | 
			
		||||
 | 
			
		||||
The syntax for paths supplied to the `redact` option conform to the syntax in path lookups
 | 
			
		||||
in standard EcmaScript, with two additions:
 | 
			
		||||
 | 
			
		||||
* paths may start with bracket notation
 | 
			
		||||
* paths may contain the asterisk `*` to denote a wildcard
 | 
			
		||||
 | 
			
		||||
By way of example, the following are all valid paths:
 | 
			
		||||
 | 
			
		||||
* `a.b.c`
 | 
			
		||||
* `a["b-c"].d`
 | 
			
		||||
* `["a-b"].c`
 | 
			
		||||
* `a.b.*`
 | 
			
		||||
* `a[*].b`
 | 
			
		||||
 | 
			
		||||
## Overhead
 | 
			
		||||
 | 
			
		||||
Pino's redaction functionality is built on top of [`fast-redact`](http://github.com/davidmarkclements/fast-redact)
 | 
			
		||||
which adds about 2% overhead to `JSON.stringify` when using paths without wildcards.
 | 
			
		||||
 | 
			
		||||
When used with pino logger with a single redacted path, any overhead is within noise -
 | 
			
		||||
a way to deterministically measure it's effect has not been found. This is because its not a bottleneck.
 | 
			
		||||
 | 
			
		||||
However, wildcard redaction does carry a non-trivial cost relative to explicitly declaring the keys
 | 
			
		||||
(50% in a case where four keys are redacted across two objects). See
 | 
			
		||||
the [`fast-redact` benchmarks](https://github.com/davidmarkclements/fast-redact#benchmarks) for details.
 | 
			
		||||
 | 
			
		||||
## Safety
 | 
			
		||||
 | 
			
		||||
The `redact` option is intended as an initialization time configuration option.
 | 
			
		||||
It's extremely important that path strings do not originate from user input.
 | 
			
		||||
The `fast-redact` module uses a VM context to syntax check the paths, user input
 | 
			
		||||
should never be combined with such an approach. See the [`fast-redact` Caveat](https://github.com/davidmarkclements/fast-redact#caveat)
 | 
			
		||||
and the [`fast-redact` Approach](https://github.com/davidmarkclements/fast-redact#approach) for in-depth information.
 | 
			
		||||
							
								
								
									
										387
									
								
								node_modules/pino/docs/transports.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								node_modules/pino/docs/transports.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,387 @@
 | 
			
		|||
# Transports
 | 
			
		||||
 | 
			
		||||
A "transport" for Pino is supplementary tool which consumes Pino logs.
 | 
			
		||||
 | 
			
		||||
Consider the following example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const split = require('split2')
 | 
			
		||||
const pump = require('pump')
 | 
			
		||||
const through = require('through2')
 | 
			
		||||
 | 
			
		||||
const myTransport = through.obj(function (chunk, enc, cb) {
 | 
			
		||||
  // do the necessary
 | 
			
		||||
  console.log(chunk)
 | 
			
		||||
  cb()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
pump(process.stdin, split(JSON.parse), myTransport)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The above defines our "transport" as the file `my-transport-process.js`.
 | 
			
		||||
 | 
			
		||||
Logs can now be consumed using shell piping:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
node my-app-which-logs-stuff-to-stdout.js | node my-transport-process.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Ideally, a transport should consume logs in a separate process to the application,
 | 
			
		||||
Using transports in the same process causes unnecessary load and slows down
 | 
			
		||||
Node's single threaded event loop.
 | 
			
		||||
 | 
			
		||||
## In-process transports
 | 
			
		||||
 | 
			
		||||
> **Pino *does not* natively support in-process transports.**
 | 
			
		||||
 | 
			
		||||
Pino does not support in-process transports because Node processes are
 | 
			
		||||
single threaded processes (ignoring some technical details). Given this
 | 
			
		||||
restriction, one of the methods Pino employs to achieve its speed is to
 | 
			
		||||
purposefully offload the handling of logs, and their ultimate destination, to
 | 
			
		||||
external processes so that the threading capabilities of the OS can be
 | 
			
		||||
used (or other CPUs).
 | 
			
		||||
 | 
			
		||||
One consequence of this methodology is that "error" logs do not get written to
 | 
			
		||||
`stderr`. However, since Pino logs are in a parseable format, it is possible to
 | 
			
		||||
use tools like [pino-tee][pino-tee] or [jq][jq] to work with the logs. For
 | 
			
		||||
example, to view only logs marked as "error" logs:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ node an-app.js | jq 'select(.level == 50)'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In short, the way Pino generates logs:
 | 
			
		||||
 | 
			
		||||
1. Reduces the impact of logging on an application to the absolute minimum.
 | 
			
		||||
2. Gives greater flexibility in how logs are processed and stored.
 | 
			
		||||
 | 
			
		||||
Given all of the above, Pino recommends out-of-process log processing.
 | 
			
		||||
 | 
			
		||||
However, it is possible to wrap Pino and perform processing in-process.
 | 
			
		||||
For an example of this, see [pino-multi-stream][pinoms].
 | 
			
		||||
 | 
			
		||||
[pino-tee]: https://npm.im/pino-tee
 | 
			
		||||
[jq]: https://stedolan.github.io/jq/
 | 
			
		||||
[pinoms]: https://npm.im/pino-multi-stream
 | 
			
		||||
 | 
			
		||||
## Known Transports
 | 
			
		||||
 | 
			
		||||
PR's to this document are welcome for any new transports!
 | 
			
		||||
 | 
			
		||||
+ [pino-applicationinsights](#pino-applicationinsights)
 | 
			
		||||
+ [pino-azuretable](#pino-azuretable)
 | 
			
		||||
+ [pino-cloudwatch](#pino-cloudwatch)
 | 
			
		||||
+ [pino-couch](#pino-couch)
 | 
			
		||||
+ [pino-datadog](#pino-datadog)
 | 
			
		||||
+ [pino-elasticsearch](#pino-elasticsearch)
 | 
			
		||||
+ [pino-mq](#pino-mq)
 | 
			
		||||
+ [pino-mysql](#pino-mysql)
 | 
			
		||||
+ [pino-papertrail](#pino-papertrail)
 | 
			
		||||
+ [pino-redis](#pino-redis)
 | 
			
		||||
+ [pino-sentry](#pino-sentry)
 | 
			
		||||
+ [pino-socket](#pino-socket)
 | 
			
		||||
+ [pino-stackdriver](#pino-stackdriver)
 | 
			
		||||
+ [pino-syslog](#pino-syslog)
 | 
			
		||||
+ [pino-websocket](#pino-websocket)
 | 
			
		||||
+ [pino-http-send](#pino-http-send)
 | 
			
		||||
 | 
			
		||||
<a id="pino-applicationinsights"></a>
 | 
			
		||||
### pino-applicationinsights
 | 
			
		||||
The [pino-applicationinsights](https://www.npmjs.com/package/pino-applicationinsights) module is a transport that will forward logs to [Azure Application Insights](https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview).
 | 
			
		||||
 | 
			
		||||
Given an application `foo` that logs via pino, you would use `pino-applicationinsights` like so:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
$ node foo | pino-applicationinsights --key blablabla
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches read [readme](https://github.com/ovhemert/pino-applicationinsights#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-azuretable"></a>
 | 
			
		||||
### pino-azuretable
 | 
			
		||||
The [pino-azuretable](https://www.npmjs.com/package/pino-azuretable) module is a transport that will forward logs to the [Azure Table Storage](https://azure.microsoft.com/en-us/services/storage/tables/).
 | 
			
		||||
 | 
			
		||||
Given an application `foo` that logs via pino, you would use `pino-azuretable` like so:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
$ node foo | pino-azuretable --account storageaccount --key blablabla
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches read [readme](https://github.com/ovhemert/pino-azuretable#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-cloudwatch"></a>
 | 
			
		||||
### pino-cloudwatch
 | 
			
		||||
 | 
			
		||||
[pino-cloudwatch][pino-cloudwatch] is a transport that buffers and forwards logs to [Amazon CloudWatch][].
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-cloudwatch --group my-log-group
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[pino-cloudwatch]: https://github.com/dbhowell/pino-cloudwatch
 | 
			
		||||
[Amazon CloudWatch]: https://aws.amazon.com/cloudwatch/
 | 
			
		||||
 | 
			
		||||
<a id="pino-couch"></a>
 | 
			
		||||
### pino-couch
 | 
			
		||||
 | 
			
		||||
[pino-couch][pino-couch] uploads each log line as a [CouchDB][CouchDB] document.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-couch -U https://couch-server -d mylogs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[pino-couch]: https://github.com/IBM/pino-couch
 | 
			
		||||
[CouchDB]: https://couchdb.apache.org
 | 
			
		||||
 | 
			
		||||
<a id="pino-datadog"></a>
 | 
			
		||||
### pino-datadog
 | 
			
		||||
The [pino-datadog](https://www.npmjs.com/package/pino-datadog) module is a transport that will forward logs to [DataDog](https://www.datadoghq.com/) through it's API.
 | 
			
		||||
 | 
			
		||||
Given an application `foo` that logs via pino, you would use `pino-datadog` like so:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
$ node foo | pino-datadog --key blablabla
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches read [readme](https://github.com/ovhemert/pino-datadog#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-elasticsearch"></a>
 | 
			
		||||
### pino-elasticsearch
 | 
			
		||||
 | 
			
		||||
[pino-elasticsearch][pino-elasticsearch] uploads the log lines in bulk
 | 
			
		||||
to [Elasticsearch][elasticsearch], to be displayed in [Kibana][kibana].
 | 
			
		||||
 | 
			
		||||
It is extremely simple to use and setup
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-elasticsearch
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Assuming Elasticsearch is running on localhost.
 | 
			
		||||
 | 
			
		||||
To connect to an external elasticsearch instance (recommended for production):
 | 
			
		||||
 | 
			
		||||
* Check that `network.host` is defined in the `elasticsearch.yml` configuration file. See [elasticsearch Network Settings documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html#common-network-settings) for more details.
 | 
			
		||||
* Launch:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-elasticsearch --node http://192.168.1.42:9200
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Assuming Elasticsearch is running on `192.168.1.42`.
 | 
			
		||||
 | 
			
		||||
To connect to AWS Elasticsearch:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-elasticsearch --node https://es-url.us-east-1.es.amazonaws.com --es-version 6
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then [create an index pattern](https://www.elastic.co/guide/en/kibana/current/setup.html) on `'pino'` (the default index key for `pino-elasticsearch`) on the Kibana instance.
 | 
			
		||||
 | 
			
		||||
[pino-elasticsearch]: https://github.com/pinojs/pino-elasticsearch
 | 
			
		||||
[elasticsearch]: https://www.elastic.co/products/elasticsearch
 | 
			
		||||
[kibana]: https://www.elastic.co/products/kibana
 | 
			
		||||
 | 
			
		||||
<a id="pino-mq"></a>
 | 
			
		||||
### pino-mq
 | 
			
		||||
 | 
			
		||||
The `pino-mq` transport will take all messages received on `process.stdin` and send them over a message bus using JSON serialization.
 | 
			
		||||
 | 
			
		||||
This useful for:
 | 
			
		||||
 | 
			
		||||
* moving backpressure from application to broker
 | 
			
		||||
* transforming messages pressure to another component
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
node app.js | pino-mq -u "amqp://guest:guest@localhost/" -q "pino-logs"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively a configuration file can be used:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
node app.js | pino-mq -c pino-mq.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
A base configuration file can be initialized with:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
pino-mq -g
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches and configuration see [the `pino-mq` readme](https://github.com/itavy/pino-mq#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-papertrail"></a>
 | 
			
		||||
### pino-papertrail
 | 
			
		||||
pino-papertrail is a transport that will forward logs to the [papertrail](https://papertrailapp.com) log service through an UDPv4 socket.
 | 
			
		||||
 | 
			
		||||
Given an application `foo` that logs via pino, and a papertrail destination that collects logs on port UDP `12345` on address `bar.papertrailapp.com`, you would use `pino-papertrail`
 | 
			
		||||
like so:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
node yourapp.js | pino-papertrail --host bar.papertrailapp.com --port 12345 --appname foo
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
for full documentation of command line switches read [readme](https://github.com/ovhemert/pino-papertrail#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-mysql"></a>
 | 
			
		||||
### pino-mysql
 | 
			
		||||
 | 
			
		||||
[pino-mysql][pino-mysql] loads pino logs into [MySQL][MySQL] and [MariaDB][MariaDB].
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-mysql -c db-configuration.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`pino-mysql` can extract and save log fields into corresponding database field
 | 
			
		||||
and/or save the entire log stream as a [JSON Data Type][JSONDT].
 | 
			
		||||
 | 
			
		||||
For full documentation and command line switches read the [readme][pino-mysql].
 | 
			
		||||
 | 
			
		||||
[pino-mysql]: https://www.npmjs.com/package/pino-mysql
 | 
			
		||||
[MySQL]: https://www.mysql.com/
 | 
			
		||||
[MariaDB]: https://mariadb.org/
 | 
			
		||||
[JSONDT]: https://dev.mysql.com/doc/refman/8.0/en/json.html
 | 
			
		||||
 | 
			
		||||
<a id="pino-redis"></a>
 | 
			
		||||
### pino-redis
 | 
			
		||||
 | 
			
		||||
[pino-redis][pino-redis] loads pino logs into [Redis][Redis].
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-redis -U redis://username:password@localhost:6379
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[pino-redis]: https://github.com/buianhthang/pino-redis
 | 
			
		||||
[Redis]: https://redis.io/
 | 
			
		||||
 | 
			
		||||
<a id="pino-sentry"></a>
 | 
			
		||||
### pino-sentry
 | 
			
		||||
 | 
			
		||||
[pino-sentry][pino-sentry] loads pino logs into [Sentry][Sentry].
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-sentry --dsn=https://******@sentry.io/12345
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches see the [pino-sentry readme](https://github.com/aandrewww/pino-sentry/blob/master/README.md)
 | 
			
		||||
 | 
			
		||||
[pino-sentry]: https://www.npmjs.com/package/pino-sentry
 | 
			
		||||
[Sentry]: https://sentry.io/
 | 
			
		||||
 | 
			
		||||
<a id="pino-socket"></a>
 | 
			
		||||
### pino-socket
 | 
			
		||||
 | 
			
		||||
[pino-socket][pino-socket] is a transport that will forward logs to a IPv4
 | 
			
		||||
UDP or TCP socket.
 | 
			
		||||
 | 
			
		||||
As an example, use `socat` to fake a listener:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ socat -v udp4-recvfrom:6000,fork exec:'/bin/cat'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then run an application that uses `pino` for logging:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-socket -p 6000
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Logs from the application should be observed on both consoles.
 | 
			
		||||
 | 
			
		||||
[pino-socket]: https://www.npmjs.com/package/pino-socket
 | 
			
		||||
 | 
			
		||||
#### Logstash
 | 
			
		||||
 | 
			
		||||
The [pino-socket][pino-socket] module can also be used to upload logs to
 | 
			
		||||
[Logstash][logstash] via:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ node app.js | pino-socket -a 127.0.0.1 -p 5000 -m tcp
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Assuming logstash is running on the same host and configured as
 | 
			
		||||
follows:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
input {
 | 
			
		||||
  tcp {
 | 
			
		||||
    port => 5000
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
filter {
 | 
			
		||||
  json {
 | 
			
		||||
    source => "message"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
output {
 | 
			
		||||
  elasticsearch {
 | 
			
		||||
    hosts => "127.0.0.1:9200"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See <https://www.elastic.co/guide/en/kibana/current/setup.html> to learn
 | 
			
		||||
how to setup [Kibana][kibana].
 | 
			
		||||
 | 
			
		||||
For Docker users, see
 | 
			
		||||
https://github.com/deviantony/docker-elk to setup an ELK stack.
 | 
			
		||||
 | 
			
		||||
<a id="pino-stackdriver"></a>
 | 
			
		||||
### pino-stackdriver
 | 
			
		||||
The [pino-stackdriver](https://www.npmjs.com/package/pino-stackdriver) module is a transport that will forward logs to the [Google Stackdriver](https://cloud.google.com/logging/) log service through it's API.
 | 
			
		||||
 | 
			
		||||
Given an application `foo` that logs via pino, a stackdriver log project `bar` and credentials in the file `/credentials.json`, you would use `pino-stackdriver`
 | 
			
		||||
like so:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
$ node foo | pino-stackdriver --project bar --credentials /credentials.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches read [readme](https://github.com/ovhemert/pino-stackdriver#readme)
 | 
			
		||||
 | 
			
		||||
<a id="pino-syslog"></a>
 | 
			
		||||
### pino-syslog
 | 
			
		||||
 | 
			
		||||
[pino-syslog][pino-syslog] is a transforming transport that converts
 | 
			
		||||
`pino` NDJSON logs to [RFC3164][rfc3164] compatible log messages. The `pino-syslog` module does not
 | 
			
		||||
forward the logs anywhere, it merely re-writes the messages to `stdout`. But
 | 
			
		||||
when used in combination with `pino-socket` the log messages can be relayed to a syslog server:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-syslog | pino-socket -a syslog.example.com
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Example output for the "hello world" log:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
<134>Apr  1 16:44:58 MacBook-Pro-3 none[94473]: {"pid":94473,"hostname":"MacBook-Pro-3","level":30,"msg":"hello world","time":1459529098958,"v":1}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[pino-syslog]: https://www.npmjs.com/package/pino-syslog
 | 
			
		||||
[rfc3164]: https://tools.ietf.org/html/rfc3164
 | 
			
		||||
[logstash]: https://www.elastic.co/products/logstash
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<a id="pino-websocket"></a>
 | 
			
		||||
### pino-websocket
 | 
			
		||||
 | 
			
		||||
[pino-websocket](https://www.npmjs.com/package/@abeai/pino-websocket) is a transport that will forward each log line to a websocket server.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
$ node app.js | pino-websocket -a my-websocket-server.example.com -p 3004
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For full documentation of command line switches read [readme](https://github.com/abeai/pino-webscoket#README)
 | 
			
		||||
 | 
			
		||||
<a id="pino-http-send"></a>
 | 
			
		||||
### pino-http-send
 | 
			
		||||
 | 
			
		||||
[pino-http-send](https://npmjs.com/package/pino-http-send) is a configurable and low overhead
 | 
			
		||||
transport that will batch logs and send to a specified URL.
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
$ node app.js | pino-http-send -u http://localhost:8080/logs
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										230
									
								
								node_modules/pino/docs/web.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								node_modules/pino/docs/web.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,230 @@
 | 
			
		|||
# Web Frameworks
 | 
			
		||||
 | 
			
		||||
Since HTTP logging is a primary use case, Pino has first class support for the Node.js
 | 
			
		||||
web framework ecosystem.
 | 
			
		||||
 | 
			
		||||
+ [Pino with Fastify](#fastify)
 | 
			
		||||
+ [Pino with Express](#express)
 | 
			
		||||
+ [Pino with Hapi](#hapi)
 | 
			
		||||
+ [Pino with Restify](#restify)
 | 
			
		||||
+ [Pino with Koa](#koa)
 | 
			
		||||
+ [Pino with Node core `http`](#http)
 | 
			
		||||
+ [Pino with Nest](#nest)
 | 
			
		||||
 | 
			
		||||
<a id="fastify"></a>
 | 
			
		||||
## Pino with Fastify
 | 
			
		||||
 | 
			
		||||
The Fastify web framework comes bundled with Pino by default, simply set Fastify's
 | 
			
		||||
`logger` option to `true` and use `request.log` or `reply.log` for log messages that correspond
 | 
			
		||||
to each individual request:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastify = require('fastify')({
 | 
			
		||||
  logger: true
 | 
			
		||||
})
 | 
			
		||||
fastify.get('/', async (request, reply) => {
 | 
			
		||||
  request.log.info('something')
 | 
			
		||||
  return { hello: 'world' }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `logger` option can also be set to an object, which will be passed through directly
 | 
			
		||||
as the [`pino` options object](/docs/api.md#options-object).
 | 
			
		||||
 | 
			
		||||
See the [fastify documentation](https://www.fastify.io/docs/latest/Logging/) for more information.
 | 
			
		||||
 | 
			
		||||
<a id="express"></a>
 | 
			
		||||
## Pino with Express
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install express-pino-logger
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const app = require('express')()
 | 
			
		||||
const pino = require('express-pino-logger')()
 | 
			
		||||
 | 
			
		||||
app.use(pino)
 | 
			
		||||
 | 
			
		||||
app.get('/', function (req, res) {
 | 
			
		||||
  req.log.info('something')
 | 
			
		||||
  res.send('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
app.listen(3000)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [express-pino-logger readme](http://npm.im/express-pino-logger) for more info.
 | 
			
		||||
 | 
			
		||||
<a id="hapi"></a>
 | 
			
		||||
## Pino with Hapi
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install hapi-pino
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
require('make-promises-safe')
 | 
			
		||||
 | 
			
		||||
const Hapi = require('hapi')
 | 
			
		||||
 | 
			
		||||
async function start () {
 | 
			
		||||
  // Create a server with a host and port
 | 
			
		||||
  const server = Hapi.server({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: 3000
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  // Add the route
 | 
			
		||||
  server.route({
 | 
			
		||||
    method: 'GET',
 | 
			
		||||
    path: '/',
 | 
			
		||||
    handler: async function (request, h) {
 | 
			
		||||
      // request.log is HAPI standard way of logging
 | 
			
		||||
      request.log(['a', 'b'], 'Request into hello world')
 | 
			
		||||
 | 
			
		||||
      // a pino instance can also be used, which will be faster
 | 
			
		||||
      request.logger.info('In handler %s', request.path)
 | 
			
		||||
 | 
			
		||||
      return 'hello world'
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  await server.register({
 | 
			
		||||
    plugin: require('.'),
 | 
			
		||||
    options: {
 | 
			
		||||
      prettyPrint: process.env.NODE_ENV !== 'production'
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  // also as a decorated API
 | 
			
		||||
  server.logger().info('another way for accessing it')
 | 
			
		||||
 | 
			
		||||
  // and through Hapi standard logging system
 | 
			
		||||
  server.log(['subsystem'], 'third way for accessing it')
 | 
			
		||||
 | 
			
		||||
  await server.start()
 | 
			
		||||
 | 
			
		||||
  return server
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start().catch((err) => {
 | 
			
		||||
  console.log(err)
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [hapi-pino readme](http://npm.im/hapi-pino) for more info.
 | 
			
		||||
 | 
			
		||||
<a id="restify"></a>
 | 
			
		||||
## Pino with Restify
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install restify-pino-logger
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const server = require('restify').createServer({name: 'server'})
 | 
			
		||||
const pino = require('restify-pino-logger')()
 | 
			
		||||
 | 
			
		||||
server.use(pino)
 | 
			
		||||
 | 
			
		||||
server.get('/', function (req, res) {
 | 
			
		||||
  req.log.info('something')
 | 
			
		||||
  res.send('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
server.listen(3000)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [restify-pino-logger readme](http://npm.im/restify-pino-logger) for more info.
 | 
			
		||||
 | 
			
		||||
<a id="koa"></a>
 | 
			
		||||
## Pino with Koa
 | 
			
		||||
 | 
			
		||||
### Koa
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install koa-pino-logger
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const Koa = require('koa')
 | 
			
		||||
const app = new Koa()
 | 
			
		||||
const pino = require('koa-pino-logger')()
 | 
			
		||||
 | 
			
		||||
app.use(pino)
 | 
			
		||||
 | 
			
		||||
app.use((ctx) => {
 | 
			
		||||
  ctx.log.info('something else')
 | 
			
		||||
  ctx.body = 'hello world'
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
app.listen(3000)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [koa-pino-logger readme](https://github.com/pinojs/koa-pino-logger) for more info.
 | 
			
		||||
 | 
			
		||||
<a id="http"></a>
 | 
			
		||||
## Pino with Node core `http`
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install pino-http
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const http = require('http')
 | 
			
		||||
const server = http.createServer(handle)
 | 
			
		||||
const logger = require('pino-http')()
 | 
			
		||||
 | 
			
		||||
function handle (req, res) {
 | 
			
		||||
  logger(req, res)
 | 
			
		||||
  req.log.info('something else')
 | 
			
		||||
  res.end('hello world')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
server.listen(3000)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [pino-http readme](http://npm.im/pino-http) for more info.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<a id="nest"></a>
 | 
			
		||||
## Pino with Nest
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install nestjs-pino
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```ts
 | 
			
		||||
import { NestFactory } from '@nestjs/core'
 | 
			
		||||
import { Controller, Get, Module } from '@nestjs/common'
 | 
			
		||||
import { LoggerModule, Logger } from 'nestjs-pino'
 | 
			
		||||
 | 
			
		||||
@Controller()
 | 
			
		||||
export class AppController {
 | 
			
		||||
  constructor(private readonly logger: Logger) {}
 | 
			
		||||
 | 
			
		||||
  @Get()
 | 
			
		||||
  getHello() {
 | 
			
		||||
    this.logger.log('something')
 | 
			
		||||
    return `Hello world`
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Module({
 | 
			
		||||
  controllers: [AppController],
 | 
			
		||||
  imports: [LoggerModule.forRoot()]
 | 
			
		||||
})
 | 
			
		||||
class MyModule {}
 | 
			
		||||
 | 
			
		||||
async function bootstrap() {
 | 
			
		||||
  const app = await NestFactory.create(MyModule)
 | 
			
		||||
  await app.listen(3000)
 | 
			
		||||
}
 | 
			
		||||
bootstrap()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [nestjs-pino readme](http://npm.im/nestjs-pino) for more info.
 | 
			
		||||
							
								
								
									
										35
									
								
								node_modules/pino/example.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								node_modules/pino/example.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const pino = require('./')()
 | 
			
		||||
 | 
			
		||||
pino.info('hello world')
 | 
			
		||||
pino.error('this is at error level')
 | 
			
		||||
pino.info('the answer is %d', 42)
 | 
			
		||||
pino.info({ obj: 42 }, 'hello world')
 | 
			
		||||
pino.info({ obj: 42, b: 2 }, 'hello world')
 | 
			
		||||
pino.info({ nested: { obj: 42 } }, 'nested')
 | 
			
		||||
setImmediate(() => {
 | 
			
		||||
  pino.info('after setImmediate')
 | 
			
		||||
})
 | 
			
		||||
pino.error(new Error('an error'))
 | 
			
		||||
 | 
			
		||||
const child = pino.child({ a: 'property' })
 | 
			
		||||
child.info('hello child!')
 | 
			
		||||
 | 
			
		||||
const childsChild = child.child({ another: 'property' })
 | 
			
		||||
childsChild.info('hello baby..')
 | 
			
		||||
 | 
			
		||||
pino.debug('this should be mute')
 | 
			
		||||
 | 
			
		||||
pino.level = 'trace'
 | 
			
		||||
 | 
			
		||||
pino.debug('this is a debug statement')
 | 
			
		||||
 | 
			
		||||
pino.child({ another: 'property' }).debug('this is a debug statement via child')
 | 
			
		||||
pino.trace('this is a trace statement')
 | 
			
		||||
 | 
			
		||||
pino.debug('this is a "debug" statement with "')
 | 
			
		||||
 | 
			
		||||
pino.info(new Error('kaboom'))
 | 
			
		||||
 | 
			
		||||
pino.info(new Error('kaboom'), 'with', 'a', 'message')
 | 
			
		||||
							
								
								
									
										183
									
								
								node_modules/pino/lib/levels.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								node_modules/pino/lib/levels.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,183 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const flatstr = require('flatstr')
 | 
			
		||||
const {
 | 
			
		||||
  lsCacheSym,
 | 
			
		||||
  levelValSym,
 | 
			
		||||
  useLevelLabelsSym,
 | 
			
		||||
  levelKeySym,
 | 
			
		||||
  useOnlyCustomLevelsSym,
 | 
			
		||||
  streamSym
 | 
			
		||||
} = require('./symbols')
 | 
			
		||||
const { noop, genLog } = require('./tools')
 | 
			
		||||
 | 
			
		||||
const levels = {
 | 
			
		||||
  trace: 10,
 | 
			
		||||
  debug: 20,
 | 
			
		||||
  info: 30,
 | 
			
		||||
  warn: 40,
 | 
			
		||||
  error: 50,
 | 
			
		||||
  fatal: 60
 | 
			
		||||
}
 | 
			
		||||
const logFatal = genLog(levels.fatal)
 | 
			
		||||
const levelMethods = {
 | 
			
		||||
  fatal (...args) {
 | 
			
		||||
    const stream = this[streamSym]
 | 
			
		||||
    logFatal.call(this, ...args)
 | 
			
		||||
    if (typeof stream.flushSync === 'function') {
 | 
			
		||||
      try {
 | 
			
		||||
        stream.flushSync()
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        // https://github.com/pinojs/pino/pull/740#discussion_r346788313
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  error: genLog(levels.error),
 | 
			
		||||
  warn: genLog(levels.warn),
 | 
			
		||||
  info: genLog(levels.info),
 | 
			
		||||
  debug: genLog(levels.debug),
 | 
			
		||||
  trace: genLog(levels.trace)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const nums = Object.keys(levels).reduce((o, k) => {
 | 
			
		||||
  o[levels[k]] = k
 | 
			
		||||
  return o
 | 
			
		||||
}, {})
 | 
			
		||||
 | 
			
		||||
const initialLsCache = Object.keys(nums).reduce((o, k) => {
 | 
			
		||||
  o[k] = flatstr('{"level":' + Number(k))
 | 
			
		||||
  return o
 | 
			
		||||
}, {})
 | 
			
		||||
 | 
			
		||||
function genLsCache (instance) {
 | 
			
		||||
  const levelName = instance[levelKeySym]
 | 
			
		||||
  instance[lsCacheSym] = Object.keys(instance.levels.labels).reduce((o, k) => {
 | 
			
		||||
    o[k] = instance[useLevelLabelsSym]
 | 
			
		||||
      ? `{"${levelName}":"${instance.levels.labels[k]}"`
 | 
			
		||||
      : flatstr(`{"${levelName}":` + Number(k))
 | 
			
		||||
    return o
 | 
			
		||||
  }, Object.assign({}, instance[lsCacheSym]))
 | 
			
		||||
  return instance
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function isStandardLevel (level, useOnlyCustomLevels) {
 | 
			
		||||
  if (useOnlyCustomLevels) {
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  switch (level) {
 | 
			
		||||
    case 'fatal':
 | 
			
		||||
    case 'error':
 | 
			
		||||
    case 'warn':
 | 
			
		||||
    case 'info':
 | 
			
		||||
    case 'debug':
 | 
			
		||||
    case 'trace':
 | 
			
		||||
      return true
 | 
			
		||||
    default:
 | 
			
		||||
      return false
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setLevel (level) {
 | 
			
		||||
  const { labels, values } = this.levels
 | 
			
		||||
  if (typeof level === 'number') {
 | 
			
		||||
    if (labels[level] === undefined) throw Error('unknown level value' + level)
 | 
			
		||||
    level = labels[level]
 | 
			
		||||
  }
 | 
			
		||||
  if (values[level] === undefined) throw Error('unknown level ' + level)
 | 
			
		||||
  const preLevelVal = this[levelValSym]
 | 
			
		||||
  const levelVal = this[levelValSym] = values[level]
 | 
			
		||||
  const useOnlyCustomLevelsVal = this[useOnlyCustomLevelsSym]
 | 
			
		||||
 | 
			
		||||
  for (var key in values) {
 | 
			
		||||
    if (levelVal > values[key]) {
 | 
			
		||||
      this[key] = noop
 | 
			
		||||
      continue
 | 
			
		||||
    }
 | 
			
		||||
    this[key] = isStandardLevel(key, useOnlyCustomLevelsVal) ? levelMethods[key] : genLog(values[key])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.emit(
 | 
			
		||||
    'level-change',
 | 
			
		||||
    level,
 | 
			
		||||
    levelVal,
 | 
			
		||||
    labels[preLevelVal],
 | 
			
		||||
    preLevelVal
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getLevel (level) {
 | 
			
		||||
  const { levels, levelVal } = this
 | 
			
		||||
  return levels.labels[levelVal]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function isLevelEnabled (logLevel) {
 | 
			
		||||
  const { values } = this.levels
 | 
			
		||||
  const logLevelVal = values[logLevel]
 | 
			
		||||
  return logLevelVal !== undefined && (logLevelVal >= this[levelValSym])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mappings (customLevels = null, useOnlyCustomLevels = false) {
 | 
			
		||||
  const customNums = customLevels ? Object.keys(customLevels).reduce((o, k) => {
 | 
			
		||||
    o[customLevels[k]] = k
 | 
			
		||||
    return o
 | 
			
		||||
  }, {}) : null
 | 
			
		||||
 | 
			
		||||
  const labels = Object.assign(
 | 
			
		||||
    Object.create(Object.prototype, { Infinity: { value: 'silent' } }),
 | 
			
		||||
    useOnlyCustomLevels ? null : nums,
 | 
			
		||||
    customNums
 | 
			
		||||
  )
 | 
			
		||||
  const values = Object.assign(
 | 
			
		||||
    Object.create(Object.prototype, { silent: { value: Infinity } }),
 | 
			
		||||
    useOnlyCustomLevels ? null : levels,
 | 
			
		||||
    customLevels
 | 
			
		||||
  )
 | 
			
		||||
  return { labels, values }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function assertDefaultLevelFound (defaultLevel, customLevels, useOnlyCustomLevels) {
 | 
			
		||||
  if (typeof defaultLevel === 'number') {
 | 
			
		||||
    const values = [].concat(
 | 
			
		||||
      Object.keys(customLevels || {}).map(key => customLevels[key]),
 | 
			
		||||
      useOnlyCustomLevels ? [] : Object.keys(nums).map(level => +level),
 | 
			
		||||
      Infinity
 | 
			
		||||
    )
 | 
			
		||||
    if (!values.includes(defaultLevel)) {
 | 
			
		||||
      throw Error(`default level:${defaultLevel} must be included in custom levels`)
 | 
			
		||||
    }
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const labels = Object.assign(
 | 
			
		||||
    Object.create(Object.prototype, { silent: { value: Infinity } }),
 | 
			
		||||
    useOnlyCustomLevels ? null : levels,
 | 
			
		||||
    customLevels
 | 
			
		||||
  )
 | 
			
		||||
  if (!(defaultLevel in labels)) {
 | 
			
		||||
    throw Error(`default level:${defaultLevel} must be included in custom levels`)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function assertNoLevelCollisions (levels, customLevels) {
 | 
			
		||||
  const { labels, values } = levels
 | 
			
		||||
  for (const k in customLevels) {
 | 
			
		||||
    if (k in values) {
 | 
			
		||||
      throw Error('levels cannot be overridden')
 | 
			
		||||
    }
 | 
			
		||||
    if (customLevels[k] in labels) {
 | 
			
		||||
      throw Error('pre-existing level values cannot be used for new levels')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  initialLsCache,
 | 
			
		||||
  genLsCache,
 | 
			
		||||
  levelMethods,
 | 
			
		||||
  getLevel,
 | 
			
		||||
  setLevel,
 | 
			
		||||
  isLevelEnabled,
 | 
			
		||||
  mappings,
 | 
			
		||||
  assertNoLevelCollisions,
 | 
			
		||||
  assertDefaultLevelFound
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								node_modules/pino/lib/meta.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/pino/lib/meta.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { version } = require('../package.json')
 | 
			
		||||
 | 
			
		||||
const LOG_VERSION = 1
 | 
			
		||||
 | 
			
		||||
module.exports = { version, LOG_VERSION }
 | 
			
		||||
							
								
								
									
										167
									
								
								node_modules/pino/lib/proto.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								node_modules/pino/lib/proto.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,167 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* eslint no-prototype-builtins: 0 */
 | 
			
		||||
 | 
			
		||||
const { EventEmitter } = require('events')
 | 
			
		||||
const SonicBoom = require('sonic-boom')
 | 
			
		||||
const flatstr = require('flatstr')
 | 
			
		||||
const {
 | 
			
		||||
  lsCacheSym,
 | 
			
		||||
  levelValSym,
 | 
			
		||||
  setLevelSym,
 | 
			
		||||
  getLevelSym,
 | 
			
		||||
  chindingsSym,
 | 
			
		||||
  mixinSym,
 | 
			
		||||
  asJsonSym,
 | 
			
		||||
  messageKeySym,
 | 
			
		||||
  writeSym,
 | 
			
		||||
  timeSym,
 | 
			
		||||
  timeSliceIndexSym,
 | 
			
		||||
  streamSym,
 | 
			
		||||
  serializersSym,
 | 
			
		||||
  useOnlyCustomLevelsSym,
 | 
			
		||||
  needsMetadataGsym
 | 
			
		||||
} = require('./symbols')
 | 
			
		||||
const {
 | 
			
		||||
  getLevel,
 | 
			
		||||
  setLevel,
 | 
			
		||||
  isLevelEnabled,
 | 
			
		||||
  mappings,
 | 
			
		||||
  initialLsCache,
 | 
			
		||||
  genLsCache,
 | 
			
		||||
  assertNoLevelCollisions
 | 
			
		||||
} = require('./levels')
 | 
			
		||||
const {
 | 
			
		||||
  asChindings,
 | 
			
		||||
  asJson
 | 
			
		||||
} = require('./tools')
 | 
			
		||||
const {
 | 
			
		||||
  version,
 | 
			
		||||
  LOG_VERSION
 | 
			
		||||
} = require('./meta')
 | 
			
		||||
 | 
			
		||||
// note: use of class is satirical
 | 
			
		||||
// https://github.com/pinojs/pino/pull/433#pullrequestreview-127703127
 | 
			
		||||
const constructor = class Pino {}
 | 
			
		||||
const prototype = {
 | 
			
		||||
  constructor,
 | 
			
		||||
  child,
 | 
			
		||||
  bindings,
 | 
			
		||||
  setBindings,
 | 
			
		||||
  flush,
 | 
			
		||||
  isLevelEnabled,
 | 
			
		||||
  version,
 | 
			
		||||
  get level () { return this[getLevelSym]() },
 | 
			
		||||
  set level (lvl) { return this[setLevelSym](lvl) },
 | 
			
		||||
  get levelVal () { return this[levelValSym] },
 | 
			
		||||
  set levelVal (n) { throw Error('levelVal is read-only') },
 | 
			
		||||
  [lsCacheSym]: initialLsCache,
 | 
			
		||||
  [writeSym]: write,
 | 
			
		||||
  [asJsonSym]: asJson,
 | 
			
		||||
  [getLevelSym]: getLevel,
 | 
			
		||||
  [setLevelSym]: setLevel,
 | 
			
		||||
  LOG_VERSION
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Object.setPrototypeOf(prototype, EventEmitter.prototype)
 | 
			
		||||
 | 
			
		||||
module.exports = prototype
 | 
			
		||||
 | 
			
		||||
function child (bindings) {
 | 
			
		||||
  const { level } = this
 | 
			
		||||
  const serializers = this[serializersSym]
 | 
			
		||||
  const chindings = asChindings(this, bindings)
 | 
			
		||||
  const instance = Object.create(this)
 | 
			
		||||
  if (bindings.hasOwnProperty('serializers') === true) {
 | 
			
		||||
    instance[serializersSym] = Object.create(null)
 | 
			
		||||
 | 
			
		||||
    for (var k in serializers) {
 | 
			
		||||
      instance[serializersSym][k] = serializers[k]
 | 
			
		||||
    }
 | 
			
		||||
    const parentSymbols = Object.getOwnPropertySymbols(serializers)
 | 
			
		||||
    for (var i = 0; i < parentSymbols.length; i++) {
 | 
			
		||||
      const ks = parentSymbols[i]
 | 
			
		||||
      instance[serializersSym][ks] = serializers[ks]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (var bk in bindings.serializers) {
 | 
			
		||||
      instance[serializersSym][bk] = bindings.serializers[bk]
 | 
			
		||||
    }
 | 
			
		||||
    const bindingsSymbols = Object.getOwnPropertySymbols(bindings.serializers)
 | 
			
		||||
    for (var bi = 0; bi < bindingsSymbols.length; bi++) {
 | 
			
		||||
      const bks = bindingsSymbols[bi]
 | 
			
		||||
      instance[serializersSym][bks] = bindings.serializers[bks]
 | 
			
		||||
    }
 | 
			
		||||
  } else instance[serializersSym] = serializers
 | 
			
		||||
  if (bindings.hasOwnProperty('customLevels') === true) {
 | 
			
		||||
    assertNoLevelCollisions(this.levels, bindings.customLevels)
 | 
			
		||||
    instance.levels = mappings(bindings.customLevels, instance[useOnlyCustomLevelsSym])
 | 
			
		||||
    genLsCache(instance)
 | 
			
		||||
  }
 | 
			
		||||
  instance[chindingsSym] = chindings
 | 
			
		||||
  const childLevel = bindings.level || level
 | 
			
		||||
  instance[setLevelSym](childLevel)
 | 
			
		||||
 | 
			
		||||
  return instance
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function bindings () {
 | 
			
		||||
  const chindings = this[chindingsSym]
 | 
			
		||||
  var chindingsJson = `{${chindings.substr(1)}}` // at least contains ,"pid":7068,"hostname":"myMac"
 | 
			
		||||
  var bindingsFromJson = JSON.parse(chindingsJson)
 | 
			
		||||
  delete bindingsFromJson.pid
 | 
			
		||||
  delete bindingsFromJson.hostname
 | 
			
		||||
  return bindingsFromJson
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setBindings (newBindings) {
 | 
			
		||||
  const chindings = asChindings(this, newBindings)
 | 
			
		||||
  this[chindingsSym] = chindings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function write (_obj, msg, num) {
 | 
			
		||||
  const t = this[timeSym]()
 | 
			
		||||
  const messageKey = this[messageKeySym]
 | 
			
		||||
  const mixin = this[mixinSym]
 | 
			
		||||
  const objError = _obj instanceof Error
 | 
			
		||||
  var obj
 | 
			
		||||
 | 
			
		||||
  if (_obj === undefined || _obj === null) {
 | 
			
		||||
    obj = mixin ? mixin() : {}
 | 
			
		||||
    obj[messageKey] = msg
 | 
			
		||||
  } else {
 | 
			
		||||
    obj = Object.assign(mixin ? mixin() : {}, _obj)
 | 
			
		||||
    if (msg) {
 | 
			
		||||
      obj[messageKey] = msg
 | 
			
		||||
    } else if (objError) {
 | 
			
		||||
      obj[messageKey] = _obj.message
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (objError) {
 | 
			
		||||
      obj.stack = _obj.stack
 | 
			
		||||
      if (!obj.type) {
 | 
			
		||||
        obj.type = 'Error'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const s = this[asJsonSym](obj, num, t)
 | 
			
		||||
 | 
			
		||||
  const stream = this[streamSym]
 | 
			
		||||
  if (stream[needsMetadataGsym] === true) {
 | 
			
		||||
    stream.lastLevel = num
 | 
			
		||||
    // TODO remove in the next major release,
 | 
			
		||||
    // it is not needed anymore
 | 
			
		||||
    stream.lastMsg = msg
 | 
			
		||||
    stream.lastObj = obj
 | 
			
		||||
    stream.lastTime = t.slice(this[timeSliceIndexSym])
 | 
			
		||||
    stream.lastLogger = this // for child loggers
 | 
			
		||||
  }
 | 
			
		||||
  if (stream instanceof SonicBoom) stream.write(s)
 | 
			
		||||
  else stream.write(flatstr(s))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function flush () {
 | 
			
		||||
  const stream = this[streamSym]
 | 
			
		||||
  if ('flush' in stream) stream.flush()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								node_modules/pino/lib/redaction.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								node_modules/pino/lib/redaction.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const fastRedact = require('fast-redact')
 | 
			
		||||
const { redactFmtSym, wildcardFirstSym } = require('./symbols')
 | 
			
		||||
const { rx, validator } = fastRedact
 | 
			
		||||
 | 
			
		||||
const validate = validator({
 | 
			
		||||
  ERR_PATHS_MUST_BE_STRINGS: () => 'pino – redacted paths must be strings',
 | 
			
		||||
  ERR_INVALID_PATH: (s) => `pino – redact paths array contains an invalid path (${s})`
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const CENSOR = '[Redacted]'
 | 
			
		||||
const strict = false // TODO should this be configurable?
 | 
			
		||||
 | 
			
		||||
function redaction (opts, serialize) {
 | 
			
		||||
  const { paths, censor } = handle(opts)
 | 
			
		||||
 | 
			
		||||
  const shape = paths.reduce((o, str) => {
 | 
			
		||||
    rx.lastIndex = 0
 | 
			
		||||
    const first = rx.exec(str)
 | 
			
		||||
    const next = rx.exec(str)
 | 
			
		||||
 | 
			
		||||
    // ns is the top-level path segment, brackets + quoting removed.
 | 
			
		||||
    let ns = first[1] !== undefined
 | 
			
		||||
      ? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, '$1')
 | 
			
		||||
      : first[0]
 | 
			
		||||
 | 
			
		||||
    if (ns === '*') {
 | 
			
		||||
      ns = wildcardFirstSym
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // top level key:
 | 
			
		||||
    if (next === null) {
 | 
			
		||||
      o[ns] = null
 | 
			
		||||
      return o
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // path with at least two segments:
 | 
			
		||||
    // if ns is already redacted at the top level, ignore lower level redactions
 | 
			
		||||
    if (o[ns] === null) {
 | 
			
		||||
      return o
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const { index } = next
 | 
			
		||||
    const nextPath = `${str.substr(index, str.length - 1)}`
 | 
			
		||||
 | 
			
		||||
    o[ns] = o[ns] || []
 | 
			
		||||
 | 
			
		||||
    // shape is a mix of paths beginning with literal values and wildcard
 | 
			
		||||
    // paths [ "a.b.c", "*.b.z" ] should reduce to a shape of
 | 
			
		||||
    // { "a": [ "b.c", "b.z" ], *: [ "b.z" ] }
 | 
			
		||||
    // note: "b.z" is in both "a" and * arrays because "a" matches the wildcard.
 | 
			
		||||
    // (* entry has wildcardFirstSym as key)
 | 
			
		||||
    if (ns !== wildcardFirstSym && o[ns].length === 0) {
 | 
			
		||||
      // first time ns's get all '*' redactions so far
 | 
			
		||||
      o[ns].push(...(o[wildcardFirstSym] || []))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ns === wildcardFirstSym) {
 | 
			
		||||
      // new * path gets added to all previously registered literal ns's.
 | 
			
		||||
      Object.keys(o).forEach(function (k) {
 | 
			
		||||
        if (o[k]) {
 | 
			
		||||
          o[k].push(nextPath)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    o[ns].push(nextPath)
 | 
			
		||||
    return o
 | 
			
		||||
  }, {})
 | 
			
		||||
 | 
			
		||||
  // the redactor assigned to the format symbol key
 | 
			
		||||
  // provides top level redaction for instances where
 | 
			
		||||
  // an object is interpolated into the msg string
 | 
			
		||||
  const result = {
 | 
			
		||||
    [redactFmtSym]: fastRedact({ paths, censor, serialize, strict })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const topCensor = (...args) =>
 | 
			
		||||
    typeof censor === 'function' ? serialize(censor(...args)) : serialize(censor)
 | 
			
		||||
 | 
			
		||||
  return [...Object.keys(shape), ...Object.getOwnPropertySymbols(shape)].reduce((o, k) => {
 | 
			
		||||
    // top level key:
 | 
			
		||||
    if (shape[k] === null) o[k] = topCensor
 | 
			
		||||
    else o[k] = fastRedact({ paths: shape[k], censor, serialize, strict })
 | 
			
		||||
    return o
 | 
			
		||||
  }, result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handle (opts) {
 | 
			
		||||
  if (Array.isArray(opts)) {
 | 
			
		||||
    opts = { paths: opts, censor: CENSOR }
 | 
			
		||||
    validate(opts)
 | 
			
		||||
    return opts
 | 
			
		||||
  }
 | 
			
		||||
  var { paths, censor = CENSOR, remove } = opts
 | 
			
		||||
  if (Array.isArray(paths) === false) { throw Error('pino – redact must contain an array of strings') }
 | 
			
		||||
  if (remove === true) censor = undefined
 | 
			
		||||
  validate({ paths, censor })
 | 
			
		||||
 | 
			
		||||
  return { paths, censor }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = redaction
 | 
			
		||||
							
								
								
									
										64
									
								
								node_modules/pino/lib/symbols.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								node_modules/pino/lib/symbols.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const setLevelSym = Symbol('pino.setLevel')
 | 
			
		||||
const getLevelSym = Symbol('pino.getLevel')
 | 
			
		||||
const levelValSym = Symbol('pino.levelVal')
 | 
			
		||||
const useLevelLabelsSym = Symbol('pino.useLevelLabels')
 | 
			
		||||
const levelKeySym = Symbol('pino.levelKey')
 | 
			
		||||
const useOnlyCustomLevelsSym = Symbol('pino.useOnlyCustomLevels')
 | 
			
		||||
const mixinSym = Symbol('pino.mixin')
 | 
			
		||||
 | 
			
		||||
const lsCacheSym = Symbol('pino.lsCache')
 | 
			
		||||
const chindingsSym = Symbol('pino.chindings')
 | 
			
		||||
const parsedChindingsSym = Symbol('pino.parsedChindings')
 | 
			
		||||
 | 
			
		||||
const asJsonSym = Symbol('pino.asJson')
 | 
			
		||||
const writeSym = Symbol('pino.write')
 | 
			
		||||
const redactFmtSym = Symbol('pino.redactFmt')
 | 
			
		||||
 | 
			
		||||
const timeSym = Symbol('pino.time')
 | 
			
		||||
const timeSliceIndexSym = Symbol('pino.timeSliceIndex')
 | 
			
		||||
const streamSym = Symbol('pino.stream')
 | 
			
		||||
const stringifySym = Symbol('pino.stringify')
 | 
			
		||||
const stringifiersSym = Symbol('pino.stringifiers')
 | 
			
		||||
const endSym = Symbol('pino.end')
 | 
			
		||||
const formatOptsSym = Symbol('pino.formatOpts')
 | 
			
		||||
const messageKeySym = Symbol('pino.messageKey')
 | 
			
		||||
const nestedKeySym = Symbol('pino.nestedKey')
 | 
			
		||||
 | 
			
		||||
const wildcardFirstSym = Symbol('pino.wildcardFirst')
 | 
			
		||||
 | 
			
		||||
// public symbols, no need to use the same pino
 | 
			
		||||
// version for these
 | 
			
		||||
const serializersSym = Symbol.for('pino.serializers')
 | 
			
		||||
const wildcardGsym = Symbol.for('pino.*')
 | 
			
		||||
const needsMetadataGsym = Symbol.for('pino.metadata')
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  setLevelSym,
 | 
			
		||||
  getLevelSym,
 | 
			
		||||
  levelValSym,
 | 
			
		||||
  useLevelLabelsSym,
 | 
			
		||||
  mixinSym,
 | 
			
		||||
  lsCacheSym,
 | 
			
		||||
  chindingsSym,
 | 
			
		||||
  parsedChindingsSym,
 | 
			
		||||
  asJsonSym,
 | 
			
		||||
  writeSym,
 | 
			
		||||
  serializersSym,
 | 
			
		||||
  redactFmtSym,
 | 
			
		||||
  timeSym,
 | 
			
		||||
  timeSliceIndexSym,
 | 
			
		||||
  streamSym,
 | 
			
		||||
  stringifySym,
 | 
			
		||||
  stringifiersSym,
 | 
			
		||||
  endSym,
 | 
			
		||||
  formatOptsSym,
 | 
			
		||||
  messageKeySym,
 | 
			
		||||
  nestedKeySym,
 | 
			
		||||
  wildcardFirstSym,
 | 
			
		||||
  levelKeySym,
 | 
			
		||||
  wildcardGsym,
 | 
			
		||||
  needsMetadataGsym,
 | 
			
		||||
  useOnlyCustomLevelsSym
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								node_modules/pino/lib/time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								node_modules/pino/lib/time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const nullTime = () => ''
 | 
			
		||||
 | 
			
		||||
const epochTime = () => `,"time":${Date.now()}`
 | 
			
		||||
 | 
			
		||||
const unixTime = () => `,"time":${Math.round(Date.now() / 1000.0)}`
 | 
			
		||||
 | 
			
		||||
const isoTime = () => `,"time":"${new Date(Date.now()).toISOString()}"` // using Date.now() for testability
 | 
			
		||||
 | 
			
		||||
module.exports = { nullTime, epochTime, unixTime, isoTime }
 | 
			
		||||
							
								
								
									
										386
									
								
								node_modules/pino/lib/tools.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										386
									
								
								node_modules/pino/lib/tools.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,386 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* eslint no-prototype-builtins: 0 */
 | 
			
		||||
 | 
			
		||||
const format = require('quick-format-unescaped')
 | 
			
		||||
const { mapHttpRequest, mapHttpResponse } = require('pino-std-serializers')
 | 
			
		||||
const SonicBoom = require('sonic-boom')
 | 
			
		||||
const stringifySafe = require('fast-safe-stringify')
 | 
			
		||||
const {
 | 
			
		||||
  lsCacheSym,
 | 
			
		||||
  chindingsSym,
 | 
			
		||||
  parsedChindingsSym,
 | 
			
		||||
  writeSym,
 | 
			
		||||
  serializersSym,
 | 
			
		||||
  formatOptsSym,
 | 
			
		||||
  endSym,
 | 
			
		||||
  stringifiersSym,
 | 
			
		||||
  stringifySym,
 | 
			
		||||
  wildcardFirstSym,
 | 
			
		||||
  needsMetadataGsym,
 | 
			
		||||
  wildcardGsym,
 | 
			
		||||
  redactFmtSym,
 | 
			
		||||
  streamSym,
 | 
			
		||||
  nestedKeySym
 | 
			
		||||
} = require('./symbols')
 | 
			
		||||
 | 
			
		||||
function noop () {}
 | 
			
		||||
 | 
			
		||||
function genLog (z) {
 | 
			
		||||
  return function LOG (o, ...n) {
 | 
			
		||||
    if (typeof o === 'object' && o !== null) {
 | 
			
		||||
      if (o.method && o.headers && o.socket) {
 | 
			
		||||
        o = mapHttpRequest(o)
 | 
			
		||||
      } else if (typeof o.setHeader === 'function') {
 | 
			
		||||
        o = mapHttpResponse(o)
 | 
			
		||||
      }
 | 
			
		||||
      if (this[nestedKeySym]) o = { [this[nestedKeySym]]: o }
 | 
			
		||||
      this[writeSym](o, format(null, n, this[formatOptsSym]), z)
 | 
			
		||||
    } else this[writeSym](null, format(o, n, this[formatOptsSym]), z)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// magically escape strings for json
 | 
			
		||||
// relying on their charCodeAt
 | 
			
		||||
// everything below 32 needs JSON.stringify()
 | 
			
		||||
// 34 and 92 happens all the time, so we
 | 
			
		||||
// have a fast case for them
 | 
			
		||||
function asString (str) {
 | 
			
		||||
  var result = ''
 | 
			
		||||
  var last = 0
 | 
			
		||||
  var found = false
 | 
			
		||||
  var point = 255
 | 
			
		||||
  const l = str.length
 | 
			
		||||
  if (l > 100) {
 | 
			
		||||
    return JSON.stringify(str)
 | 
			
		||||
  }
 | 
			
		||||
  for (var i = 0; i < l && point >= 32; i++) {
 | 
			
		||||
    point = str.charCodeAt(i)
 | 
			
		||||
    if (point === 34 || point === 92) {
 | 
			
		||||
      result += str.slice(last, i) + '\\'
 | 
			
		||||
      last = i
 | 
			
		||||
      found = true
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (!found) {
 | 
			
		||||
    result = str
 | 
			
		||||
  } else {
 | 
			
		||||
    result += str.slice(last)
 | 
			
		||||
  }
 | 
			
		||||
  return point < 32 ? JSON.stringify(str) : '"' + result + '"'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function asJson (obj, num, time) {
 | 
			
		||||
  const stringify = this[stringifySym]
 | 
			
		||||
  const stringifiers = this[stringifiersSym]
 | 
			
		||||
  const end = this[endSym]
 | 
			
		||||
  const chindings = this[chindingsSym]
 | 
			
		||||
  const serializers = this[serializersSym]
 | 
			
		||||
  var data = this[lsCacheSym][num] + time
 | 
			
		||||
 | 
			
		||||
  // we need the child bindings added to the output first so instance logged
 | 
			
		||||
  // objects can take precedence when JSON.parse-ing the resulting log line
 | 
			
		||||
  data = data + chindings
 | 
			
		||||
 | 
			
		||||
  var value
 | 
			
		||||
  var notHasOwnProperty = obj.hasOwnProperty === undefined
 | 
			
		||||
  if (serializers[wildcardGsym]) {
 | 
			
		||||
    obj = serializers[wildcardGsym](obj)
 | 
			
		||||
  }
 | 
			
		||||
  const wildcardStringifier = stringifiers[wildcardFirstSym]
 | 
			
		||||
  for (var key in obj) {
 | 
			
		||||
    value = obj[key]
 | 
			
		||||
    if ((notHasOwnProperty || obj.hasOwnProperty(key)) && value !== undefined) {
 | 
			
		||||
      value = serializers[key] ? serializers[key](value) : value
 | 
			
		||||
 | 
			
		||||
      const stringifier = stringifiers[key] || wildcardStringifier
 | 
			
		||||
 | 
			
		||||
      switch (typeof value) {
 | 
			
		||||
        case 'undefined':
 | 
			
		||||
        case 'function':
 | 
			
		||||
          continue
 | 
			
		||||
        case 'number':
 | 
			
		||||
          /* eslint no-fallthrough: "off" */
 | 
			
		||||
          if (Number.isFinite(value) === false) {
 | 
			
		||||
            value = null
 | 
			
		||||
          }
 | 
			
		||||
        // this case explicity falls through to the next one
 | 
			
		||||
        case 'boolean':
 | 
			
		||||
          if (stringifier) value = stringifier(value)
 | 
			
		||||
          break
 | 
			
		||||
        case 'string':
 | 
			
		||||
          value = (stringifier || asString)(value)
 | 
			
		||||
          break
 | 
			
		||||
        default:
 | 
			
		||||
          value = (stringifier || stringify)(value)
 | 
			
		||||
      }
 | 
			
		||||
      if (value === undefined) continue
 | 
			
		||||
      data += ',"' + key + '":' + value
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return data + end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function asChindings (instance, bindings) {
 | 
			
		||||
  if (!bindings) {
 | 
			
		||||
    throw Error('missing bindings for child Pino')
 | 
			
		||||
  }
 | 
			
		||||
  var key
 | 
			
		||||
  var value
 | 
			
		||||
  var data = instance[chindingsSym]
 | 
			
		||||
  const stringify = instance[stringifySym]
 | 
			
		||||
  const stringifiers = instance[stringifiersSym]
 | 
			
		||||
  const serializers = instance[serializersSym]
 | 
			
		||||
  if (serializers[wildcardGsym]) {
 | 
			
		||||
    bindings = serializers[wildcardGsym](bindings)
 | 
			
		||||
  }
 | 
			
		||||
  for (key in bindings) {
 | 
			
		||||
    value = bindings[key]
 | 
			
		||||
    const valid = key !== 'level' &&
 | 
			
		||||
      key !== 'serializers' &&
 | 
			
		||||
      key !== 'customLevels' &&
 | 
			
		||||
      bindings.hasOwnProperty(key) &&
 | 
			
		||||
      value !== undefined
 | 
			
		||||
    if (valid === true) {
 | 
			
		||||
      value = serializers[key] ? serializers[key](value) : value
 | 
			
		||||
      value = (stringifiers[key] || stringify)(value)
 | 
			
		||||
      if (value === undefined) continue
 | 
			
		||||
      data += ',"' + key + '":' + value
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getPrettyStream (opts, prettifier, dest, instance) {
 | 
			
		||||
  if (prettifier && typeof prettifier === 'function') {
 | 
			
		||||
    prettifier = prettifier.bind(instance)
 | 
			
		||||
    return prettifierMetaWrapper(prettifier(opts), dest)
 | 
			
		||||
  }
 | 
			
		||||
  try {
 | 
			
		||||
    var prettyFactory = require('pino-pretty')
 | 
			
		||||
    prettyFactory.asMetaWrapper = prettifierMetaWrapper
 | 
			
		||||
    return prettifierMetaWrapper(prettyFactory(opts), dest)
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    throw Error('Missing `pino-pretty` module: `pino-pretty` must be installed separately')
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function prettifierMetaWrapper (pretty, dest) {
 | 
			
		||||
  var warned = false
 | 
			
		||||
  return {
 | 
			
		||||
    [needsMetadataGsym]: true,
 | 
			
		||||
    lastLevel: 0,
 | 
			
		||||
    lastMsg: null,
 | 
			
		||||
    lastObj: null,
 | 
			
		||||
    lastLogger: null,
 | 
			
		||||
    flushSync () {
 | 
			
		||||
      if (warned) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      warned = true
 | 
			
		||||
      setMetadataProps(dest, this)
 | 
			
		||||
      dest.write(pretty(Object.assign({
 | 
			
		||||
        level: 40, // warn
 | 
			
		||||
        msg: 'pino.final with prettyPrint does not support flushing',
 | 
			
		||||
        time: Date.now()
 | 
			
		||||
      }, this.chindings())))
 | 
			
		||||
    },
 | 
			
		||||
    chindings () {
 | 
			
		||||
      const lastLogger = this.lastLogger
 | 
			
		||||
      var chindings = null
 | 
			
		||||
 | 
			
		||||
      // protection against flushSync being called before logging
 | 
			
		||||
      // anything
 | 
			
		||||
      if (!lastLogger) {
 | 
			
		||||
        return null
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (lastLogger.hasOwnProperty(parsedChindingsSym)) {
 | 
			
		||||
        chindings = lastLogger[parsedChindingsSym]
 | 
			
		||||
      } else {
 | 
			
		||||
        chindings = JSON.parse('{"v":1' + lastLogger[chindingsSym] + '}')
 | 
			
		||||
        lastLogger[parsedChindingsSym] = chindings
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return chindings
 | 
			
		||||
    },
 | 
			
		||||
    write (chunk) {
 | 
			
		||||
      const lastLogger = this.lastLogger
 | 
			
		||||
      const chindings = this.chindings()
 | 
			
		||||
 | 
			
		||||
      var time = this.lastTime
 | 
			
		||||
 | 
			
		||||
      if (time.match(/^\d+/)) {
 | 
			
		||||
        time = parseInt(time)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var lastObj = this.lastObj
 | 
			
		||||
      var errorProps = null
 | 
			
		||||
 | 
			
		||||
      const obj = Object.assign({
 | 
			
		||||
        level: this.lastLevel,
 | 
			
		||||
        time
 | 
			
		||||
      }, chindings, lastObj, errorProps)
 | 
			
		||||
 | 
			
		||||
      const serializers = lastLogger[serializersSym]
 | 
			
		||||
      const keys = Object.keys(serializers)
 | 
			
		||||
      var key
 | 
			
		||||
 | 
			
		||||
      for (var i = 0; i < keys.length; i++) {
 | 
			
		||||
        key = keys[i]
 | 
			
		||||
        if (obj[key] !== undefined) {
 | 
			
		||||
          obj[key] = serializers[key](obj[key])
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const stringifiers = lastLogger[stringifiersSym]
 | 
			
		||||
      const redact = stringifiers[redactFmtSym]
 | 
			
		||||
 | 
			
		||||
      const formatted = pretty(typeof redact === 'function' ? redact(obj) : obj)
 | 
			
		||||
      if (formatted === undefined) return
 | 
			
		||||
 | 
			
		||||
      setMetadataProps(dest, this)
 | 
			
		||||
      dest.write(formatted)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hasBeenTampered (stream) {
 | 
			
		||||
  return stream.write !== stream.constructor.prototype.write
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function buildSafeSonicBoom (dest, buffer = 0, sync = true) {
 | 
			
		||||
  const stream = new SonicBoom(dest, buffer, sync)
 | 
			
		||||
  stream.on('error', filterBrokenPipe)
 | 
			
		||||
  return stream
 | 
			
		||||
 | 
			
		||||
  function filterBrokenPipe (err) {
 | 
			
		||||
    // TODO verify on Windows
 | 
			
		||||
    if (err.code === 'EPIPE') {
 | 
			
		||||
      // If we get EPIPE, we should stop logging here
 | 
			
		||||
      // however we have no control to the consumer of
 | 
			
		||||
      // SonicBoom, so we just overwrite the write method
 | 
			
		||||
      stream.write = noop
 | 
			
		||||
      stream.end = noop
 | 
			
		||||
      stream.flushSync = noop
 | 
			
		||||
      stream.destroy = noop
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    stream.removeListener('error', filterBrokenPipe)
 | 
			
		||||
    stream.emit('error', err)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createArgsNormalizer (defaultOptions) {
 | 
			
		||||
  return function normalizeArgs (instance, opts = {}, stream) {
 | 
			
		||||
    // support stream as a string
 | 
			
		||||
    if (typeof opts === 'string') {
 | 
			
		||||
      stream = buildSafeSonicBoom(opts)
 | 
			
		||||
      opts = {}
 | 
			
		||||
    } else if (typeof stream === 'string') {
 | 
			
		||||
      stream = buildSafeSonicBoom(stream)
 | 
			
		||||
    } else if (opts instanceof SonicBoom || opts.writable || opts._writableState) {
 | 
			
		||||
      stream = opts
 | 
			
		||||
      opts = null
 | 
			
		||||
    }
 | 
			
		||||
    opts = Object.assign({}, defaultOptions, opts)
 | 
			
		||||
    if ('extreme' in opts) {
 | 
			
		||||
      throw Error('The extreme option has been removed, use pino.extreme instead')
 | 
			
		||||
    }
 | 
			
		||||
    if ('onTerminated' in opts) {
 | 
			
		||||
      throw Error('The onTerminated option has been removed, use pino.final instead')
 | 
			
		||||
    }
 | 
			
		||||
    if ('changeLevelName' in opts) {
 | 
			
		||||
      process.emitWarning(
 | 
			
		||||
        'The changeLevelName option is deprecated and will be removed in v7. Use levelKey instead.',
 | 
			
		||||
        { code: 'changeLevelName_deprecation' }
 | 
			
		||||
      )
 | 
			
		||||
      opts.levelKey = opts.changeLevelName
 | 
			
		||||
      delete opts.changeLevelName
 | 
			
		||||
    }
 | 
			
		||||
    const { enabled, prettyPrint, prettifier, messageKey } = opts
 | 
			
		||||
    if (enabled === false) opts.level = 'silent'
 | 
			
		||||
    stream = stream || process.stdout
 | 
			
		||||
    if (stream === process.stdout && stream.fd >= 0 && !hasBeenTampered(stream)) {
 | 
			
		||||
      stream = buildSafeSonicBoom(stream.fd)
 | 
			
		||||
    }
 | 
			
		||||
    if (prettyPrint) {
 | 
			
		||||
      const prettyOpts = Object.assign({ messageKey }, prettyPrint)
 | 
			
		||||
      stream = getPrettyStream(prettyOpts, prettifier, stream, instance)
 | 
			
		||||
    }
 | 
			
		||||
    return { opts, stream }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function final (logger, handler) {
 | 
			
		||||
  if (typeof logger === 'undefined' || typeof logger.child !== 'function') {
 | 
			
		||||
    throw Error('expected a pino logger instance')
 | 
			
		||||
  }
 | 
			
		||||
  const hasHandler = (typeof handler !== 'undefined')
 | 
			
		||||
  if (hasHandler && typeof handler !== 'function') {
 | 
			
		||||
    throw Error('if supplied, the handler parameter should be a function')
 | 
			
		||||
  }
 | 
			
		||||
  const stream = logger[streamSym]
 | 
			
		||||
  if (typeof stream.flushSync !== 'function') {
 | 
			
		||||
    throw Error('final requires a stream that has a flushSync method, such as pino.destination and pino.extreme')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const finalLogger = new Proxy(logger, {
 | 
			
		||||
    get: (logger, key) => {
 | 
			
		||||
      if (key in logger.levels.values) {
 | 
			
		||||
        return (...args) => {
 | 
			
		||||
          logger[key](...args)
 | 
			
		||||
          stream.flushSync()
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return logger[key]
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  if (!hasHandler) {
 | 
			
		||||
    return finalLogger
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (err = null, ...args) => {
 | 
			
		||||
    try {
 | 
			
		||||
      stream.flushSync()
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      // it's too late to wait for the stream to be ready
 | 
			
		||||
      // because this is a final tick scenario.
 | 
			
		||||
      // in practice there shouldn't be a situation where it isn't
 | 
			
		||||
      // however, swallow the error just in case (and for easier testing)
 | 
			
		||||
    }
 | 
			
		||||
    return handler(err, finalLogger, ...args)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function stringify (obj) {
 | 
			
		||||
  try {
 | 
			
		||||
    return JSON.stringify(obj)
 | 
			
		||||
  } catch (_) {
 | 
			
		||||
    return stringifySafe(obj)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setMetadataProps (dest, that) {
 | 
			
		||||
  if (dest[needsMetadataGsym] === true) {
 | 
			
		||||
    dest.lastLevel = that.lastLevel
 | 
			
		||||
    dest.lastMsg = that.lastMsg
 | 
			
		||||
    dest.lastObj = that.lastObj
 | 
			
		||||
    dest.lastTime = that.lastTime
 | 
			
		||||
    dest.lastLogger = that.lastLogger
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  noop,
 | 
			
		||||
  buildSafeSonicBoom,
 | 
			
		||||
  getPrettyStream,
 | 
			
		||||
  asChindings,
 | 
			
		||||
  asJson,
 | 
			
		||||
  genLog,
 | 
			
		||||
  createArgsNormalizer,
 | 
			
		||||
  final,
 | 
			
		||||
  stringify
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								node_modules/pino/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								node_modules/pino/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,135 @@
 | 
			
		|||
{
 | 
			
		||||
  "_from": "pino@5.17.0",
 | 
			
		||||
  "_id": "pino@5.17.0",
 | 
			
		||||
  "_inBundle": false,
 | 
			
		||||
  "_integrity": "sha512-LqrqmRcJz8etUjyV0ddqB6OTUutCgQULPFg2b4dtijRHUsucaAdBgSUW58vY6RFSX+NT8963F+q0tM6lNwGShA==",
 | 
			
		||||
  "_location": "/pino",
 | 
			
		||||
  "_phantomChildren": {},
 | 
			
		||||
  "_requested": {
 | 
			
		||||
    "type": "version",
 | 
			
		||||
    "registry": true,
 | 
			
		||||
    "raw": "pino@5.17.0",
 | 
			
		||||
    "name": "pino",
 | 
			
		||||
    "escapedName": "pino",
 | 
			
		||||
    "rawSpec": "5.17.0",
 | 
			
		||||
    "saveSpec": null,
 | 
			
		||||
    "fetchSpec": "5.17.0"
 | 
			
		||||
  },
 | 
			
		||||
  "_requiredBy": [
 | 
			
		||||
    "/docker-hub-utils"
 | 
			
		||||
  ],
 | 
			
		||||
  "_resolved": "https://registry.npmjs.org/pino/-/pino-5.17.0.tgz",
 | 
			
		||||
  "_shasum": "b9def314e82402154f89a25d76a31f20ca84b4c8",
 | 
			
		||||
  "_spec": "pino@5.17.0",
 | 
			
		||||
  "_where": "/home/dawidd6/github/dawidd6/action-debian-package/node_modules/docker-hub-utils",
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "Matteo Collina",
 | 
			
		||||
    "email": "hello@matteocollina.com"
 | 
			
		||||
  },
 | 
			
		||||
  "bin": {
 | 
			
		||||
    "pino": "bin.js"
 | 
			
		||||
  },
 | 
			
		||||
  "browser": "./browser.js",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/pinojs/pino/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "bundleDependencies": false,
 | 
			
		||||
  "contributors": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "David Mark Clements",
 | 
			
		||||
      "email": "huperekchuno@googlemail.com"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "James Sumners",
 | 
			
		||||
      "email": "james.sumners@gmail.com"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Thomas Watson Steen",
 | 
			
		||||
      "email": "w@tson.dk",
 | 
			
		||||
      "url": "https://twitter.com/wa7son"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "fast-redact": "^2.0.0",
 | 
			
		||||
    "fast-safe-stringify": "^2.0.7",
 | 
			
		||||
    "flatstr": "^1.0.12",
 | 
			
		||||
    "pino-std-serializers": "^2.4.2",
 | 
			
		||||
    "quick-format-unescaped": "^3.0.3",
 | 
			
		||||
    "sonic-boom": "^0.7.5"
 | 
			
		||||
  },
 | 
			
		||||
  "deprecated": false,
 | 
			
		||||
  "description": "super fast, all natural json logger",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "airtap": "2.0.2",
 | 
			
		||||
    "benchmark": "^2.1.4",
 | 
			
		||||
    "bole": "^3.0.2",
 | 
			
		||||
    "bunyan": "^1.8.12",
 | 
			
		||||
    "cross-env": "^5.2.1",
 | 
			
		||||
    "docsify-cli": "^4.2.1",
 | 
			
		||||
    "execa": "^1.0.0",
 | 
			
		||||
    "fastbench": "^1.0.1",
 | 
			
		||||
    "flush-write-stream": "^2.0.0",
 | 
			
		||||
    "import-fresh": "^3.0.0",
 | 
			
		||||
    "log": "^5.0.0",
 | 
			
		||||
    "loglevel": "^1.6.4",
 | 
			
		||||
    "pino-pretty": "^2.6.1",
 | 
			
		||||
    "pre-commit": "^1.2.2",
 | 
			
		||||
    "proxyquire": "^2.1.3",
 | 
			
		||||
    "pump": "^3.0.0",
 | 
			
		||||
    "qodaa": "^1.0.1",
 | 
			
		||||
    "semver": "^6.3.0",
 | 
			
		||||
    "snazzy": "^8.0.0",
 | 
			
		||||
    "split2": "^3.1.1",
 | 
			
		||||
    "standard": "^14.2.0",
 | 
			
		||||
    "steed": "^1.1.3",
 | 
			
		||||
    "tap": "^12.7.0",
 | 
			
		||||
    "tape": "^4.11.0",
 | 
			
		||||
    "through2": "^3.0.1",
 | 
			
		||||
    "winston": "^3.2.1"
 | 
			
		||||
  },
 | 
			
		||||
  "files": [
 | 
			
		||||
    "pino.js",
 | 
			
		||||
    "bin.js",
 | 
			
		||||
    "browser.js",
 | 
			
		||||
    "pretty.js",
 | 
			
		||||
    "usage.txt",
 | 
			
		||||
    "test",
 | 
			
		||||
    "docs",
 | 
			
		||||
    "example.js",
 | 
			
		||||
    "lib"
 | 
			
		||||
  ],
 | 
			
		||||
  "homepage": "http://getpino.io",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "fast",
 | 
			
		||||
    "logger",
 | 
			
		||||
    "stream",
 | 
			
		||||
    "json"
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "main": "pino.js",
 | 
			
		||||
  "name": "pino",
 | 
			
		||||
  "precommit": "test",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git+https://github.com/pinojs/pino.git"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "bench": "node benchmarks/utils/runbench all",
 | 
			
		||||
    "bench-basic": "node benchmarks/utils/runbench basic",
 | 
			
		||||
    "bench-child": "node benchmarks/utils/runbench child",
 | 
			
		||||
    "bench-child-child": "node benchmarks/utils/runbench child-child",
 | 
			
		||||
    "bench-child-creation": "node benchmarks/utils/runbench child-creation",
 | 
			
		||||
    "bench-deep-object": "node benchmarks/utils/runbench deep-object",
 | 
			
		||||
    "bench-longs-tring": "node benchmarks/utils/runbench long-string",
 | 
			
		||||
    "bench-multi-arg": "node benchmarks/utils/runbench multi-arg",
 | 
			
		||||
    "bench-object": "node benchmarks/utils/runbench object",
 | 
			
		||||
    "browser-test": "airtap --local 8080 test/browser*test.js",
 | 
			
		||||
    "ci": "standard | snazzy && cross-env TAP_TIMEOUT=480000 NODE_OPTIONS=\"--no-warnings -r qodaa\" tap --no-esm -j 4 --100 test/*test.js",
 | 
			
		||||
    "cov-ci": "cross-env TAP_TIMEOUT=480000 NODE_OPTIONS=\"--no-warnings -r qodaa\" tap --no-esm -j 4 --100 --coverage-report=lcov test/*test.js",
 | 
			
		||||
    "cov-ui": "cross-env NODE_OPTIONS=\"--no-warnings -r qodaa\" tap --no-esm -j 4 --coverage-report=html test/*test.js",
 | 
			
		||||
    "docs": "docsify serve",
 | 
			
		||||
    "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--no-warnings -r qodaa\" tap --no-esm -j 4 --no-cov test/*test.js",
 | 
			
		||||
    "update-bench-doc": "node benchmarks/utils/generate-benchmark-doc > docs/benchmarks.md"
 | 
			
		||||
  },
 | 
			
		||||
  "version": "5.17.0"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										144
									
								
								node_modules/pino/pino.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								node_modules/pino/pino.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,144 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const stdSerializers = require('pino-std-serializers')
 | 
			
		||||
const redaction = require('./lib/redaction')
 | 
			
		||||
const time = require('./lib/time')
 | 
			
		||||
const proto = require('./lib/proto')
 | 
			
		||||
const symbols = require('./lib/symbols')
 | 
			
		||||
const { assertDefaultLevelFound, mappings, genLsCache } = require('./lib/levels')
 | 
			
		||||
const {
 | 
			
		||||
  createArgsNormalizer,
 | 
			
		||||
  asChindings,
 | 
			
		||||
  final,
 | 
			
		||||
  stringify,
 | 
			
		||||
  buildSafeSonicBoom
 | 
			
		||||
} = require('./lib/tools')
 | 
			
		||||
const { version, LOG_VERSION } = require('./lib/meta')
 | 
			
		||||
const {
 | 
			
		||||
  chindingsSym,
 | 
			
		||||
  redactFmtSym,
 | 
			
		||||
  serializersSym,
 | 
			
		||||
  timeSym,
 | 
			
		||||
  timeSliceIndexSym,
 | 
			
		||||
  streamSym,
 | 
			
		||||
  stringifySym,
 | 
			
		||||
  stringifiersSym,
 | 
			
		||||
  setLevelSym,
 | 
			
		||||
  endSym,
 | 
			
		||||
  formatOptsSym,
 | 
			
		||||
  messageKeySym,
 | 
			
		||||
  nestedKeySym,
 | 
			
		||||
  useLevelLabelsSym,
 | 
			
		||||
  levelKeySym,
 | 
			
		||||
  mixinSym,
 | 
			
		||||
  useOnlyCustomLevelsSym
 | 
			
		||||
} = symbols
 | 
			
		||||
const { epochTime, nullTime } = time
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
const defaultErrorSerializer = stdSerializers.err
 | 
			
		||||
const defaultOptions = {
 | 
			
		||||
  level: 'info',
 | 
			
		||||
  useLevelLabels: false,
 | 
			
		||||
  messageKey: 'msg',
 | 
			
		||||
  nestedKey: null,
 | 
			
		||||
  enabled: true,
 | 
			
		||||
  prettyPrint: false,
 | 
			
		||||
  base: { pid, hostname },
 | 
			
		||||
  serializers: Object.assign(Object.create(null), {
 | 
			
		||||
    err: defaultErrorSerializer
 | 
			
		||||
  }),
 | 
			
		||||
  timestamp: epochTime,
 | 
			
		||||
  name: undefined,
 | 
			
		||||
  redact: null,
 | 
			
		||||
  customLevels: null,
 | 
			
		||||
  levelKey: 'level',
 | 
			
		||||
  useOnlyCustomLevels: false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const normalize = createArgsNormalizer(defaultOptions)
 | 
			
		||||
 | 
			
		||||
const serializers = Object.assign(Object.create(null), stdSerializers)
 | 
			
		||||
 | 
			
		||||
function pino (...args) {
 | 
			
		||||
  const instance = {}
 | 
			
		||||
  const { opts, stream } = normalize(instance, ...args)
 | 
			
		||||
  const {
 | 
			
		||||
    redact,
 | 
			
		||||
    crlf,
 | 
			
		||||
    serializers,
 | 
			
		||||
    timestamp,
 | 
			
		||||
    messageKey,
 | 
			
		||||
    nestedKey,
 | 
			
		||||
    base,
 | 
			
		||||
    name,
 | 
			
		||||
    level,
 | 
			
		||||
    customLevels,
 | 
			
		||||
    useLevelLabels,
 | 
			
		||||
    levelKey,
 | 
			
		||||
    mixin,
 | 
			
		||||
    useOnlyCustomLevels
 | 
			
		||||
  } = opts
 | 
			
		||||
 | 
			
		||||
  const stringifiers = redact ? redaction(redact, stringify) : {}
 | 
			
		||||
  const formatOpts = redact
 | 
			
		||||
    ? { stringify: stringifiers[redactFmtSym] }
 | 
			
		||||
    : { stringify }
 | 
			
		||||
  const end = ',"v":' + LOG_VERSION + '}' + (crlf ? '\r\n' : '\n')
 | 
			
		||||
  const coreChindings = asChindings.bind(null, {
 | 
			
		||||
    [chindingsSym]: '',
 | 
			
		||||
    [serializersSym]: serializers,
 | 
			
		||||
    [stringifiersSym]: stringifiers,
 | 
			
		||||
    [stringifySym]: stringify
 | 
			
		||||
  })
 | 
			
		||||
  const chindings = base === null ? '' : (name === undefined)
 | 
			
		||||
    ? coreChindings(base) : coreChindings(Object.assign({}, base, { name }))
 | 
			
		||||
  const time = (timestamp instanceof Function)
 | 
			
		||||
    ? timestamp : (timestamp ? epochTime : nullTime)
 | 
			
		||||
  const timeSliceIndex = time().indexOf(':') + 1
 | 
			
		||||
 | 
			
		||||
  if (useOnlyCustomLevels && !customLevels) throw Error('customLevels is required if useOnlyCustomLevels is set true')
 | 
			
		||||
  if (mixin && typeof mixin !== 'function') throw Error(`Unknown mixin type "${typeof mixin}" - expected "function"`)
 | 
			
		||||
 | 
			
		||||
  assertDefaultLevelFound(level, customLevels, useOnlyCustomLevels)
 | 
			
		||||
  const levels = mappings(customLevels, useOnlyCustomLevels)
 | 
			
		||||
 | 
			
		||||
  Object.assign(instance, {
 | 
			
		||||
    levels,
 | 
			
		||||
    [useLevelLabelsSym]: useLevelLabels,
 | 
			
		||||
    [levelKeySym]: levelKey,
 | 
			
		||||
    [useOnlyCustomLevelsSym]: useOnlyCustomLevels,
 | 
			
		||||
    [streamSym]: stream,
 | 
			
		||||
    [timeSym]: time,
 | 
			
		||||
    [timeSliceIndexSym]: timeSliceIndex,
 | 
			
		||||
    [stringifySym]: stringify,
 | 
			
		||||
    [stringifiersSym]: stringifiers,
 | 
			
		||||
    [endSym]: end,
 | 
			
		||||
    [formatOptsSym]: formatOpts,
 | 
			
		||||
    [messageKeySym]: messageKey,
 | 
			
		||||
    [nestedKeySym]: nestedKey,
 | 
			
		||||
    [serializersSym]: serializers,
 | 
			
		||||
    [mixinSym]: mixin,
 | 
			
		||||
    [chindingsSym]: chindings
 | 
			
		||||
  })
 | 
			
		||||
  Object.setPrototypeOf(instance, proto)
 | 
			
		||||
 | 
			
		||||
  if (customLevels || useLevelLabels || levelKey !== defaultOptions.levelKey) genLsCache(instance)
 | 
			
		||||
 | 
			
		||||
  instance[setLevelSym](level)
 | 
			
		||||
 | 
			
		||||
  return instance
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pino.extreme = (dest = process.stdout.fd) => buildSafeSonicBoom(dest, 4096, false)
 | 
			
		||||
pino.destination = (dest = process.stdout.fd) => buildSafeSonicBoom(dest, 0, true)
 | 
			
		||||
 | 
			
		||||
pino.final = final
 | 
			
		||||
pino.levels = mappings()
 | 
			
		||||
pino.stdSerializers = serializers
 | 
			
		||||
pino.stdTimeFunctions = Object.assign({}, time)
 | 
			
		||||
pino.symbols = symbols
 | 
			
		||||
pino.version = version
 | 
			
		||||
pino.LOG_VERSION = LOG_VERSION
 | 
			
		||||
 | 
			
		||||
module.exports = pino
 | 
			
		||||
							
								
								
									
										702
									
								
								node_modules/pino/test/basic.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										702
									
								
								node_modules/pino/test/basic.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,702 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const { readFileSync, existsSync, statSync } = require('fs')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, check, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
const { version } = require('../package.json')
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
const watchFileCreated = (filename) => new Promise((resolve, reject) => {
 | 
			
		||||
  const TIMEOUT = 800
 | 
			
		||||
  const INTERVAL = 100
 | 
			
		||||
  const threshold = TIMEOUT / INTERVAL
 | 
			
		||||
  let counter = 0
 | 
			
		||||
  const interval = setInterval(() => {
 | 
			
		||||
    // On some CI runs file is created but not filled
 | 
			
		||||
    if (existsSync(filename) && statSync(filename).size !== 0) {
 | 
			
		||||
      clearInterval(interval)
 | 
			
		||||
      resolve()
 | 
			
		||||
    } else if (counter <= threshold) {
 | 
			
		||||
      counter++
 | 
			
		||||
    } else {
 | 
			
		||||
      clearInterval(interval)
 | 
			
		||||
      reject(new Error(`${filename} was not created.`))
 | 
			
		||||
    }
 | 
			
		||||
  }, INTERVAL)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino version is exposed on export', async ({ is }) => {
 | 
			
		||||
  is(pino.version, version)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino version is exposed on instance', async ({ is }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  is(instance.version, version)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child instance exposes pino version', async ({ is }) => {
 | 
			
		||||
  const child = pino().child({ foo: 'bar' })
 | 
			
		||||
  is(child.version, version)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('bindings are exposed on every instance', async ({ same }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  same(instance.bindings(), {})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('bindings contain the name and the child bindings', async ({ same }) => {
 | 
			
		||||
  const instance = pino({ name: 'basicTest', level: 'info' }).child({ foo: 'bar' }).child({ a: 2 })
 | 
			
		||||
  same(instance.bindings(), { name: 'basicTest', foo: 'bar', a: 2 })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set bindings on instance', async ({ same }) => {
 | 
			
		||||
  const instance = pino({ name: 'basicTest', level: 'info' })
 | 
			
		||||
  instance.setBindings({ foo: 'bar' })
 | 
			
		||||
  same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('newly set bindings overwrite old bindings', async ({ same }) => {
 | 
			
		||||
  const instance = pino({ name: 'basicTest', level: 'info', base: { foo: 'bar' } })
 | 
			
		||||
  instance.setBindings({ foo: 'baz' })
 | 
			
		||||
  same(instance.bindings(), { name: 'basicTest', foo: 'baz' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set bindings on child instance', async ({ same }) => {
 | 
			
		||||
  const child = pino({ name: 'basicTest', level: 'info' }).child({})
 | 
			
		||||
  child.setBindings({ foo: 'bar' })
 | 
			
		||||
  same(child.bindings(), { name: 'basicTest', foo: 'bar' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child should have bindings set by parent', async ({ same }) => {
 | 
			
		||||
  const instance = pino({ name: 'basicTest', level: 'info' })
 | 
			
		||||
  instance.setBindings({ foo: 'bar' })
 | 
			
		||||
  const child = instance.child({})
 | 
			
		||||
  same(child.bindings(), { name: 'basicTest', foo: 'bar' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child should not share bindings of parent set after child creation', async ({ same }) => {
 | 
			
		||||
  const instance = pino({ name: 'basicTest', level: 'info' })
 | 
			
		||||
  const child = instance.child({})
 | 
			
		||||
  instance.setBindings({ foo: 'bar' })
 | 
			
		||||
  same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
 | 
			
		||||
  same(child.bindings(), { name: 'basicTest' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function levelTest (name, level) {
 | 
			
		||||
  test(`${name} logs as ${level}`, async ({ is }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    instance[name]('hello world')
 | 
			
		||||
    check(is, await once(stream, 'data'), level, 'hello world')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`passing objects at level ${name}`, async ({ is, same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    const obj = { hello: 'world' }
 | 
			
		||||
    instance[name](obj)
 | 
			
		||||
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
    is(result.pid, pid)
 | 
			
		||||
    is(result.hostname, hostname)
 | 
			
		||||
    is(result.level, level)
 | 
			
		||||
    is(result.hello, 'world')
 | 
			
		||||
    is(result.v, 1)
 | 
			
		||||
    same(Object.keys(obj), ['hello'])
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`passing an object and a string at level ${name}`, async ({ is, same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    const obj = { hello: 'world' }
 | 
			
		||||
    instance[name](obj, 'a string')
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: level,
 | 
			
		||||
      msg: 'a string',
 | 
			
		||||
      hello: 'world',
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
    same(Object.keys(obj), ['hello'])
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`overriding object key by string at level ${name}`, async ({ is, same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    instance[name]({ hello: 'world', msg: 'object' }, 'string')
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: level,
 | 
			
		||||
      msg: 'string',
 | 
			
		||||
      hello: 'world',
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`formatting logs as ${name}`, async ({ is }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    instance[name]('hello %d', 42)
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    check(is, result, level, 'hello 42')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`formatting a symbol at level ${name}`, async ({ is }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
 | 
			
		||||
    const sym = Symbol('foo')
 | 
			
		||||
    instance[name]('hello', sym)
 | 
			
		||||
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
 | 
			
		||||
    check(is, result, level, 'hello Symbol(foo)')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`passing error with a serializer at level ${name}`, async ({ is, same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const err = new Error('myerror')
 | 
			
		||||
    const instance = pino({
 | 
			
		||||
      serializers: {
 | 
			
		||||
        err: pino.stdSerializers.err
 | 
			
		||||
      }
 | 
			
		||||
    }, stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    instance[name]({ err })
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: level,
 | 
			
		||||
      err: {
 | 
			
		||||
        type: 'Error',
 | 
			
		||||
        message: err.message,
 | 
			
		||||
        stack: err.stack
 | 
			
		||||
      },
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test(`child logger for level ${name}`, async ({ is, same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino(stream)
 | 
			
		||||
    instance.level = name
 | 
			
		||||
    const child = instance.child({ hello: 'world' })
 | 
			
		||||
    child[name]('hello world')
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: level,
 | 
			
		||||
      msg: 'hello world',
 | 
			
		||||
      hello: 'world',
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
levelTest('fatal', 60)
 | 
			
		||||
levelTest('error', 50)
 | 
			
		||||
levelTest('warn', 40)
 | 
			
		||||
levelTest('info', 30)
 | 
			
		||||
levelTest('debug', 20)
 | 
			
		||||
levelTest('trace', 10)
 | 
			
		||||
 | 
			
		||||
test('serializers can return undefined to strip field', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      test () { return undefined }
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.info({ test: 'sensitive info' })
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is('test' in result, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('does not explode with a circular ref', async ({ doesNotThrow }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  const b = {}
 | 
			
		||||
  const a = {
 | 
			
		||||
    hello: b
 | 
			
		||||
  }
 | 
			
		||||
  b.a = a // circular ref
 | 
			
		||||
  doesNotThrow(() => instance.info(a))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the name', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    name: 'hello'
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 60,
 | 
			
		||||
    name: 'hello',
 | 
			
		||||
    msg: 'this is fatal',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the messageKey', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const message = 'hello world'
 | 
			
		||||
  const messageKey = 'fooMessage'
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    messageKey
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.info(message)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    fooMessage: message,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the nestedKey', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const object = { hello: 'world' }
 | 
			
		||||
  const nestedKey = 'stuff'
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    nestedKey
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.info(object)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    stuff: object,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set undefined properties', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info({ hello: 'world', property: undefined })
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    hello: 'world',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('prototype properties are not logged', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info(Object.create({ hello: 'world' }))
 | 
			
		||||
  const { hello } = await once(stream, 'data')
 | 
			
		||||
  is(hello, undefined)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the base', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    base: {
 | 
			
		||||
      a: 'b'
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    a: 'b',
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the base to null', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    base: null
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the base to null and use a serializer', async ({ is, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    base: null,
 | 
			
		||||
    serializers: {
 | 
			
		||||
      [Symbol.for('pino.*')]: (input) => {
 | 
			
		||||
        return Object.assign({}, input, { additionalMessage: 'using pino' })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal('this is fatal too')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal too',
 | 
			
		||||
    additionalMessage: 'using pino',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throw if creating child without bindings', async ({ throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  throws(() => instance.child())
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly escapes msg strings with stray double quote at end', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    name: 'hello'
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.fatal('this contains "')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 60,
 | 
			
		||||
    name: 'hello',
 | 
			
		||||
    msg: 'this contains "',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly escape msg strings with unclosed double quote', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    name: 'hello'
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal('" this contains')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 60,
 | 
			
		||||
    name: 'hello',
 | 
			
		||||
    msg: '" this contains',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// https://github.com/pinojs/pino/issues/139
 | 
			
		||||
test('object and format string', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info({}, 'foo %s', 'bar')
 | 
			
		||||
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'foo bar',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('object and format string property', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info({ answer: 42 }, 'foo %s', 'bar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'foo bar',
 | 
			
		||||
    answer: 42,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly strip undefined when returned from toJSON', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    test: 'this'
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal({ test: { toJSON () { return undefined } } })
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is('test' in result, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly supports stderr', async ({ same }) => {
 | 
			
		||||
  // stderr inherits from Stream, rather than Writable
 | 
			
		||||
  const dest = {
 | 
			
		||||
    writable: true,
 | 
			
		||||
    write (result) {
 | 
			
		||||
      result = JSON.parse(result)
 | 
			
		||||
      delete result.time
 | 
			
		||||
      same(result, {
 | 
			
		||||
        pid: pid,
 | 
			
		||||
        hostname: hostname,
 | 
			
		||||
        level: 60,
 | 
			
		||||
        msg: 'a message',
 | 
			
		||||
        v: 1
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  const instance = pino(dest)
 | 
			
		||||
  instance.fatal('a message')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('normalize number to string', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info(1)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: '1',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('normalize number to string with an object', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info({ answer: 42 }, 1)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: '1',
 | 
			
		||||
    answer: 42,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles objects with null prototype', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  const o = Object.create(null)
 | 
			
		||||
  o.test = 'test'
 | 
			
		||||
  instance.info(o)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    test: 'test',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino.destination', async ({ same }) => {
 | 
			
		||||
  const tmp = join(
 | 
			
		||||
    os.tmpdir(),
 | 
			
		||||
    '_' + Math.random().toString(36).substr(2, 9)
 | 
			
		||||
  )
 | 
			
		||||
  const instance = pino(pino.destination(tmp))
 | 
			
		||||
  instance.info('hello')
 | 
			
		||||
  await watchFileCreated(tmp)
 | 
			
		||||
  const result = JSON.parse(readFileSync(tmp).toString())
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'hello',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('auto pino.destination with a string', async ({ same }) => {
 | 
			
		||||
  const tmp = join(
 | 
			
		||||
    os.tmpdir(),
 | 
			
		||||
    '_' + Math.random().toString(36).substr(2, 9)
 | 
			
		||||
  )
 | 
			
		||||
  const instance = pino(tmp)
 | 
			
		||||
  instance.info('hello')
 | 
			
		||||
  await watchFileCreated(tmp)
 | 
			
		||||
  const result = JSON.parse(readFileSync(tmp).toString())
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'hello',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('auto pino.destination with a string as second argument', async ({ same }) => {
 | 
			
		||||
  const tmp = join(
 | 
			
		||||
    os.tmpdir(),
 | 
			
		||||
    '_' + Math.random().toString(36).substr(2, 9)
 | 
			
		||||
  )
 | 
			
		||||
  const instance = pino(null, tmp)
 | 
			
		||||
  instance.info('hello')
 | 
			
		||||
  await watchFileCreated(tmp)
 | 
			
		||||
  const result = JSON.parse(readFileSync(tmp).toString())
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'hello',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('does not override opts with a string as second argument', async ({ same }) => {
 | 
			
		||||
  const tmp = join(
 | 
			
		||||
    os.tmpdir(),
 | 
			
		||||
    '_' + Math.random().toString(36).substr(2, 9)
 | 
			
		||||
  )
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    timestamp: () => ',"time":"none"'
 | 
			
		||||
  }, tmp)
 | 
			
		||||
  instance.info('hello')
 | 
			
		||||
  await watchFileCreated(tmp)
 | 
			
		||||
  const result = JSON.parse(readFileSync(tmp).toString())
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 30,
 | 
			
		||||
    time: 'none',
 | 
			
		||||
    msg: 'hello',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// https://github.com/pinojs/pino/issues/222
 | 
			
		||||
test('children with same names render in correct order', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const root = pino(stream)
 | 
			
		||||
  root.child({ a: 1 }).child({ a: 2 }).info({ a: 3 })
 | 
			
		||||
  const { a } = await once(stream, 'data')
 | 
			
		||||
  is(a, 3, 'last logged object takes precedence')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// https://github.com/pinojs/pino/pull/251 - use this.stringify
 | 
			
		||||
test('use `fast-safe-stringify` to avoid circular dependencies', async ({ deepEqual }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const root = pino(stream)
 | 
			
		||||
  // circular depth
 | 
			
		||||
  const obj = {}
 | 
			
		||||
  obj.a = obj
 | 
			
		||||
  root.info(obj)
 | 
			
		||||
  const { a } = await once(stream, 'data')
 | 
			
		||||
  deepEqual(a, { a: '[Circular]' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('fast-safe-stringify must be used when interpolating', async (t) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  const o = { a: { b: {} } }
 | 
			
		||||
  o.a.b.c = o.a.b
 | 
			
		||||
  instance.info('test', o)
 | 
			
		||||
 | 
			
		||||
  const { msg } = await once(stream, 'data')
 | 
			
		||||
  t.is(msg, 'test {"a":{"b":{"c":"[Circular]"}}}')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when setting useOnlyCustomLevels without customLevels', async ({ is, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({
 | 
			
		||||
      useOnlyCustomLevels: true
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      useOnlyCustomLevels: true
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'customLevels is required if useOnlyCustomLevels is set true')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly log Infinity', async (t) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  const o = { num: Infinity }
 | 
			
		||||
  instance.info(o)
 | 
			
		||||
 | 
			
		||||
  const { num } = await once(stream, 'data')
 | 
			
		||||
  t.is(num, null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly log -Infinity', async (t) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  const o = { num: -Infinity }
 | 
			
		||||
  instance.info(o)
 | 
			
		||||
 | 
			
		||||
  const { num } = await once(stream, 'data')
 | 
			
		||||
  t.is(num, null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly log NaN', async (t) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  const o = { num: NaN }
 | 
			
		||||
  instance.info(o)
 | 
			
		||||
 | 
			
		||||
  const { num } = await once(stream, 'data')
 | 
			
		||||
  t.is(num, null)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										42
									
								
								node_modules/pino/test/broken-pipe.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								node_modules/pino/test/broken-pipe.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const t = require('tap')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const { fork } = require('child_process')
 | 
			
		||||
const { once } = require('./helper')
 | 
			
		||||
const pino = require('..')
 | 
			
		||||
 | 
			
		||||
function test (file) {
 | 
			
		||||
  file = join('fixtures', 'broken-pipe', file)
 | 
			
		||||
  t.test(file, { parallel: true }, async ({ is }) => {
 | 
			
		||||
    const child = fork(join(__dirname, file), { silent: true })
 | 
			
		||||
    child.stdout.destroy()
 | 
			
		||||
 | 
			
		||||
    child.stderr.pipe(process.stdout)
 | 
			
		||||
 | 
			
		||||
    const res = await once(child, 'close')
 | 
			
		||||
    is(res, 0) // process exits successfully
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
t.jobs = 42
 | 
			
		||||
 | 
			
		||||
test('basic.js')
 | 
			
		||||
test('destination.js')
 | 
			
		||||
test('extreme.js')
 | 
			
		||||
 | 
			
		||||
t.test('let error pass through', ({ is, plan }) => {
 | 
			
		||||
  plan(3)
 | 
			
		||||
  const stream = pino.destination()
 | 
			
		||||
 | 
			
		||||
  // side effect of the pino constructor is that it will set an
 | 
			
		||||
  // event handler for error
 | 
			
		||||
  pino(stream)
 | 
			
		||||
 | 
			
		||||
  process.nextTick(() => stream.emit('error', new Error('kaboom')))
 | 
			
		||||
  process.nextTick(() => stream.emit('error', new Error('kaboom')))
 | 
			
		||||
 | 
			
		||||
  stream.on('error', (err) => {
 | 
			
		||||
    is(err.message, 'kaboom')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										218
									
								
								node_modules/pino/test/browser-levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								node_modules/pino/test/browser-levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,218 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const test = require('tape')
 | 
			
		||||
const pino = require('../browser')
 | 
			
		||||
 | 
			
		||||
test('set the level by string', ({ end, same, is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 50,
 | 
			
		||||
      msg: 'this is an error'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 60,
 | 
			
		||||
      msg: 'this is fatal'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (actual) {
 | 
			
		||||
        checkLogObjects(is, same, actual, expected.shift())
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the level by string. init with silent', ({ end, same, is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 50,
 | 
			
		||||
      msg: 'this is an error'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 60,
 | 
			
		||||
      msg: 'this is fatal'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'silent',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (actual) {
 | 
			
		||||
        checkLogObjects(is, same, actual, expected.shift())
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the level by string. init with silent and transmit', ({ end, same, is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 50,
 | 
			
		||||
      msg: 'this is an error'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 60,
 | 
			
		||||
      msg: 'this is fatal'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'silent',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (actual) {
 | 
			
		||||
        checkLogObjects(is, same, actual, expected.shift())
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    transmit: {
 | 
			
		||||
      send () {}
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the level via constructor', ({ end, same, is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 50,
 | 
			
		||||
      msg: 'this is an error'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 60,
 | 
			
		||||
      msg: 'this is fatal'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'error',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (actual) {
 | 
			
		||||
        checkLogObjects(is, same, actual, expected.shift())
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('the wrong level throws', ({ end, throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    instance.level = 'kaboom'
 | 
			
		||||
  })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('the wrong level by number throws', ({ end, throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    instance.levelVal = 55
 | 
			
		||||
  })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes level string mappings', ({ end, is }) => {
 | 
			
		||||
  is(pino.levels.values.error, 50)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes level number mappings', ({ end, is }) => {
 | 
			
		||||
  is(pino.levels.labels[50], 'error')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns level integer', ({ end, is }) => {
 | 
			
		||||
  const instance = pino({ level: 'error' })
 | 
			
		||||
  is(instance.levelVal, 50)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('silent level via constructor', ({ end, fail }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'silent',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write () {
 | 
			
		||||
        fail('no data should be logged')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  Object.keys(pino.levels.values).forEach((level) => {
 | 
			
		||||
    instance[level]('hello world')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('silent level by string', ({ end, fail }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write () {
 | 
			
		||||
        fail('no data should be logged')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.level = 'silent'
 | 
			
		||||
 | 
			
		||||
  Object.keys(pino.levels.values).forEach((level) => {
 | 
			
		||||
    instance[level]('hello world')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposed levels', ({ end, same }) => {
 | 
			
		||||
  same(Object.keys(pino.levels.values), [
 | 
			
		||||
    'fatal',
 | 
			
		||||
    'error',
 | 
			
		||||
    'warn',
 | 
			
		||||
    'info',
 | 
			
		||||
    'debug',
 | 
			
		||||
    'trace'
 | 
			
		||||
  ])
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposed labels', ({ end, same }) => {
 | 
			
		||||
  same(Object.keys(pino.levels.labels), [
 | 
			
		||||
    '10',
 | 
			
		||||
    '20',
 | 
			
		||||
    '30',
 | 
			
		||||
    '40',
 | 
			
		||||
    '50',
 | 
			
		||||
    '60'
 | 
			
		||||
  ])
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function checkLogObjects (is, same, actual, expected) {
 | 
			
		||||
  is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
 | 
			
		||||
 | 
			
		||||
  const actualCopy = Object.assign({}, actual)
 | 
			
		||||
  const expectedCopy = Object.assign({}, expected)
 | 
			
		||||
  delete actualCopy.time
 | 
			
		||||
  delete expectedCopy.time
 | 
			
		||||
 | 
			
		||||
  same(actualCopy, expectedCopy)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										327
									
								
								node_modules/pino/test/browser-serializers.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								node_modules/pino/test/browser-serializers.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,327 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
// eslint-disable-next-line
 | 
			
		||||
if (typeof $1 !== 'undefined') $1 = arguments.callee.caller.arguments[0]
 | 
			
		||||
 | 
			
		||||
const test = require('tape')
 | 
			
		||||
const fresh = require('import-fresh')
 | 
			
		||||
const pino = require('../browser')
 | 
			
		||||
 | 
			
		||||
const parentSerializers = {
 | 
			
		||||
  test: () => 'parent'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const childSerializers = {
 | 
			
		||||
  test: () => 'child'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('serializers override values', ({ end, is }) => {
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: parentSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.test, 'parent')
 | 
			
		||||
        end()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  parent.fatal({ test: 'test' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('without the serialize option, serializers do not override values', ({ end, is }) => {
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: parentSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.test, 'test')
 | 
			
		||||
        end()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  parent.fatal({ test: 'test' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
if (process.title !== 'browser') {
 | 
			
		||||
  test('if serialize option is true, standard error serializer is auto enabled', ({ end, same }) => {
 | 
			
		||||
    const err = Error('test')
 | 
			
		||||
    err.code = 'test'
 | 
			
		||||
    err.type = 'Error' // get that cov
 | 
			
		||||
    const expect = pino.stdSerializers.err(err)
 | 
			
		||||
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (err) {
 | 
			
		||||
      same(err, expect)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser')({
 | 
			
		||||
      browser: { serialize: true }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.fatal(err)
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('if serialize option is array, standard error serializer is auto enabled', ({ end, same }) => {
 | 
			
		||||
    const err = Error('test')
 | 
			
		||||
    err.code = 'test'
 | 
			
		||||
    const expect = pino.stdSerializers.err(err)
 | 
			
		||||
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (err) {
 | 
			
		||||
      same(err, expect)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      browser: { serialize: [] }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.fatal(err)
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('if serialize option is array containing !stdSerializers.err, standard error serializer is disabled', ({ end, is }) => {
 | 
			
		||||
    const err = Error('test')
 | 
			
		||||
    err.code = 'test'
 | 
			
		||||
    const expect = err
 | 
			
		||||
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (err) {
 | 
			
		||||
      is(err, expect)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      browser: { serialize: ['!stdSerializers.err'] }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.fatal(err)
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('in browser, serializers apply to all objects', ({ end, is }) => {
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (test, test2, test3, test4, test5) {
 | 
			
		||||
      is(test.key, 'serialized')
 | 
			
		||||
      is(test2.key2, 'serialized2')
 | 
			
		||||
      is(test5.key3, 'serialized3')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      serializers: {
 | 
			
		||||
        key: () => 'serialized',
 | 
			
		||||
        key2: () => 'serialized2',
 | 
			
		||||
        key3: () => 'serialized3'
 | 
			
		||||
      },
 | 
			
		||||
      browser: { serialize: true }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('serialize can be an array of selected serializers', ({ end, is }) => {
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (test, test2, test3, test4, test5) {
 | 
			
		||||
      is(test.key, 'test')
 | 
			
		||||
      is(test2.key2, 'serialized2')
 | 
			
		||||
      is(test5.key3, 'test')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      serializers: {
 | 
			
		||||
        key: () => 'serialized',
 | 
			
		||||
        key2: () => 'serialized2',
 | 
			
		||||
        key3: () => 'serialized3'
 | 
			
		||||
      },
 | 
			
		||||
      browser: { serialize: ['key2'] }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('serialize filter applies to child loggers', ({ end, is }) => {
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (binding, test, test2, test3, test4, test5) {
 | 
			
		||||
      is(test.key, 'test')
 | 
			
		||||
      is(test2.key2, 'serialized2')
 | 
			
		||||
      is(test5.key3, 'test')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      browser: { serialize: ['key2'] }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.child({
 | 
			
		||||
      aBinding: 'test',
 | 
			
		||||
      serializers: {
 | 
			
		||||
        key: () => 'serialized',
 | 
			
		||||
        key2: () => 'serialized2',
 | 
			
		||||
        key3: () => 'serialized3'
 | 
			
		||||
      }
 | 
			
		||||
    }).fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('parent serializers apply to child bindings', ({ end, is }) => {
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (binding) {
 | 
			
		||||
      is(binding.key, 'serialized')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      serializers: {
 | 
			
		||||
        key: () => 'serialized'
 | 
			
		||||
      },
 | 
			
		||||
      browser: { serialize: true }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.child({ key: 'test' }).fatal({ test: 'test' })
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('child serializers apply to child bindings', ({ end, is }) => {
 | 
			
		||||
    const consoleError = console.error
 | 
			
		||||
    console.error = function (binding) {
 | 
			
		||||
      is(binding.key, 'serialized')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const logger = fresh('../browser', require)({
 | 
			
		||||
      browser: { serialize: true }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    console.error = consoleError
 | 
			
		||||
 | 
			
		||||
    logger.child({
 | 
			
		||||
      key: 'test',
 | 
			
		||||
      serializers: {
 | 
			
		||||
        key: () => 'serialized'
 | 
			
		||||
      }
 | 
			
		||||
    }).fatal({ test: 'test' })
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('child does not overwrite parent serializers', ({ end, is }) => {
 | 
			
		||||
  var c = 0
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: parentSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write (o) {
 | 
			
		||||
        c++
 | 
			
		||||
        if (c === 1) is(o.test, 'parent')
 | 
			
		||||
        if (c === 2) {
 | 
			
		||||
          is(o.test, 'child')
 | 
			
		||||
          end()
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const child = parent.child({ serializers: childSerializers })
 | 
			
		||||
 | 
			
		||||
  parent.fatal({ test: 'test' })
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children inherit parent serializers', ({ end, is }) => {
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: parentSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.test, 'parent')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ a: 'property' })
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children serializers get called', ({ end, is }) => {
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    test: 'this',
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.test, 'child')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ a: 'property', serializers: childSerializers })
 | 
			
		||||
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children serializers get called when inherited from parent', ({ end, is }) => {
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    test: 'this',
 | 
			
		||||
    serializers: parentSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write: (o) => {
 | 
			
		||||
        is(o.test, 'pass')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ serializers: { test: () => 'pass' } })
 | 
			
		||||
 | 
			
		||||
  child.fatal({ test: 'fail' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('non overriden serializers are available in the children', ({ end, is }) => {
 | 
			
		||||
  const pSerializers = {
 | 
			
		||||
    onlyParent: () => 'parent',
 | 
			
		||||
    shared: () => 'parent'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const cSerializers = {
 | 
			
		||||
    shared: () => 'child',
 | 
			
		||||
    onlyChild: () => 'child'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var c = 0
 | 
			
		||||
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: pSerializers,
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write (o) {
 | 
			
		||||
        c++
 | 
			
		||||
        if (c === 1) is(o.shared, 'child')
 | 
			
		||||
        if (c === 2) is(o.onlyParent, 'parent')
 | 
			
		||||
        if (c === 3) is(o.onlyChild, 'child')
 | 
			
		||||
        if (c === 4) is(o.onlyChild, 'test')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ serializers: cSerializers })
 | 
			
		||||
 | 
			
		||||
  child.fatal({ shared: 'test' })
 | 
			
		||||
  child.fatal({ onlyParent: 'test' })
 | 
			
		||||
  child.fatal({ onlyChild: 'test' })
 | 
			
		||||
  parent.fatal({ onlyChild: 'test' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										349
									
								
								node_modules/pino/test/browser-transmit.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								node_modules/pino/test/browser-transmit.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,349 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const test = require('tape')
 | 
			
		||||
const pino = require('../browser')
 | 
			
		||||
 | 
			
		||||
function noop () {}
 | 
			
		||||
 | 
			
		||||
test('throws if transmit object does not have send function', ({ end, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ browser: { transmit: {} } })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ browser: { transmit: { send: 'not a func' } } })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('calls send function after write', ({ end, is }) => {
 | 
			
		||||
  var c = 0
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: () => {
 | 
			
		||||
        c++
 | 
			
		||||
      },
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send () { is(c, 1) }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'test' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function the logged level', ({ end, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write () {},
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level) {
 | 
			
		||||
          is(level, 'fatal')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'test' })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function message strings in logEvent object when asObject is not set', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, { messages }) {
 | 
			
		||||
          is(messages[0], 'test')
 | 
			
		||||
          is(messages[1], 'another test')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal('test', 'another test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function message objects in logEvent object when asObject is not set', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, { messages }) {
 | 
			
		||||
          same(messages[0], { test: 'test' })
 | 
			
		||||
          is(messages[1], 'another test')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'test' }, 'another test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function message strings in logEvent object when asObject is set', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true,
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, { messages }) {
 | 
			
		||||
          is(messages[0], 'test')
 | 
			
		||||
          is(messages[1], 'another test')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal('test', 'another test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function message objects in logEvent object when asObject is set', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true,
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, { messages }) {
 | 
			
		||||
          same(messages[0], { test: 'test' })
 | 
			
		||||
          is(messages[1], 'another test')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'test' }, 'another test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supplies a timestamp (ts) in logEvent object which is exactly the same as the `time` property in asObject mode', ({ end, is }) => {
 | 
			
		||||
  var expected
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true, // implict because `write`, but just to be explicit
 | 
			
		||||
      write (o) {
 | 
			
		||||
        expected = o.time
 | 
			
		||||
      },
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          is(logEvent.ts, expected)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal('test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function child bindings via logEvent object', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          const messages = logEvent.messages
 | 
			
		||||
          const bindings = logEvent.bindings
 | 
			
		||||
          same(bindings[0], { first: 'binding' })
 | 
			
		||||
          same(bindings[1], { second: 'binding2' })
 | 
			
		||||
          same(messages[0], { test: 'test' })
 | 
			
		||||
          is(messages[1], 'another test')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger
 | 
			
		||||
    .child({ first: 'binding' })
 | 
			
		||||
    .child({ second: 'binding2' })
 | 
			
		||||
    .fatal({ test: 'test' }, 'another test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes send function level:{label, value} via logEvent object', ({ end, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          const label = logEvent.level.label
 | 
			
		||||
          const value = logEvent.level.value
 | 
			
		||||
 | 
			
		||||
          is(label, 'fatal')
 | 
			
		||||
          is(value, 60)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'test' }, 'another test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('calls send function according to transmit.level', ({ end, is }) => {
 | 
			
		||||
  var c = 0
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        level: 'error',
 | 
			
		||||
        send (level) {
 | 
			
		||||
          c++
 | 
			
		||||
          if (c === 1) is(level, 'error')
 | 
			
		||||
          if (c === 2) is(level, 'fatal')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  logger.warn('ignored')
 | 
			
		||||
  logger.error('test')
 | 
			
		||||
  logger.fatal('test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('transmit.level defaults to logger level', ({ end, is }) => {
 | 
			
		||||
  var c = 0
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    level: 'error',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level) {
 | 
			
		||||
          c++
 | 
			
		||||
          if (c === 1) is(level, 'error')
 | 
			
		||||
          if (c === 2) is(level, 'fatal')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  logger.warn('ignored')
 | 
			
		||||
  logger.error('test')
 | 
			
		||||
  logger.fatal('test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('transmit.level is effective even if lower than logger level', ({ end, is }) => {
 | 
			
		||||
  var c = 0
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    level: 'error',
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        level: 'info',
 | 
			
		||||
        send (level) {
 | 
			
		||||
          c++
 | 
			
		||||
          if (c === 1) is(level, 'warn')
 | 
			
		||||
          if (c === 2) is(level, 'error')
 | 
			
		||||
          if (c === 3) is(level, 'fatal')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  logger.warn('ignored')
 | 
			
		||||
  logger.error('test')
 | 
			
		||||
  logger.fatal('test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('applies all serializers to messages and bindings (serialize:false - default)', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      first: () => 'first',
 | 
			
		||||
      second: () => 'second',
 | 
			
		||||
      test: () => 'serialize it'
 | 
			
		||||
    },
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          const messages = logEvent.messages
 | 
			
		||||
          const bindings = logEvent.bindings
 | 
			
		||||
          same(bindings[0], { first: 'first' })
 | 
			
		||||
          same(bindings[1], { second: 'second' })
 | 
			
		||||
          same(messages[0], { test: 'serialize it' })
 | 
			
		||||
          is(messages[1].type, 'Error')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger
 | 
			
		||||
    .child({ first: 'binding' })
 | 
			
		||||
    .child({ second: 'binding2' })
 | 
			
		||||
    .fatal({ test: 'test' }, Error())
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('applies all serializers to messages and bindings (serialize:true)', ({ end, same, is }) => {
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      first: () => 'first',
 | 
			
		||||
      second: () => 'second',
 | 
			
		||||
      test: () => 'serialize it'
 | 
			
		||||
    },
 | 
			
		||||
    browser: {
 | 
			
		||||
      serialize: true,
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          const messages = logEvent.messages
 | 
			
		||||
          const bindings = logEvent.bindings
 | 
			
		||||
          same(bindings[0], { first: 'first' })
 | 
			
		||||
          same(bindings[1], { second: 'second' })
 | 
			
		||||
          same(messages[0], { test: 'serialize it' })
 | 
			
		||||
          is(messages[1].type, 'Error')
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger
 | 
			
		||||
    .child({ first: 'binding' })
 | 
			
		||||
    .child({ second: 'binding2' })
 | 
			
		||||
    .fatal({ test: 'test' }, Error())
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('extracts correct bindings and raw messages over multiple transmits', ({ end, same, is }) => {
 | 
			
		||||
  var messages = null
 | 
			
		||||
  var bindings = null
 | 
			
		||||
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: noop,
 | 
			
		||||
      transmit: {
 | 
			
		||||
        send (level, logEvent) {
 | 
			
		||||
          messages = logEvent.messages
 | 
			
		||||
          bindings = logEvent.bindings
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = logger.child({ child: true })
 | 
			
		||||
  const grandchild = child.child({ grandchild: true })
 | 
			
		||||
 | 
			
		||||
  logger.fatal({ test: 'parent:test1' })
 | 
			
		||||
  logger.fatal({ test: 'parent:test2' })
 | 
			
		||||
  same([], bindings)
 | 
			
		||||
  same([{ test: 'parent:test2' }], messages)
 | 
			
		||||
 | 
			
		||||
  child.fatal({ test: 'child:test1' })
 | 
			
		||||
  child.fatal({ test: 'child:test2' })
 | 
			
		||||
  same([{ child: true }], bindings)
 | 
			
		||||
  same([{ test: 'child:test2' }], messages)
 | 
			
		||||
 | 
			
		||||
  grandchild.fatal({ test: 'grandchild:test1' })
 | 
			
		||||
  grandchild.fatal({ test: 'grandchild:test2' })
 | 
			
		||||
  same([{ child: true }, { grandchild: true }], bindings)
 | 
			
		||||
  same([{ test: 'grandchild:test2' }], messages)
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										553
									
								
								node_modules/pino/test/browser.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										553
									
								
								node_modules/pino/test/browser.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,553 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const test = require('tape')
 | 
			
		||||
const fresh = require('import-fresh')
 | 
			
		||||
const pinoStdSerializers = require('pino-std-serializers')
 | 
			
		||||
const pino = require('../browser')
 | 
			
		||||
 | 
			
		||||
levelTest('fatal')
 | 
			
		||||
levelTest('error')
 | 
			
		||||
levelTest('warn')
 | 
			
		||||
levelTest('info')
 | 
			
		||||
levelTest('debug')
 | 
			
		||||
levelTest('trace')
 | 
			
		||||
 | 
			
		||||
test('silent level', ({ end, fail, pass }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'silent',
 | 
			
		||||
    browser: { write: fail }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
  const child = instance.child({ test: 'test' })
 | 
			
		||||
  child.info('msg-test')
 | 
			
		||||
  // use setTimeout because setImmediate isn't supported in most browsers
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    pass()
 | 
			
		||||
    end()
 | 
			
		||||
  }, 0)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('enabled false', ({ end, fail, pass }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    enabled: false,
 | 
			
		||||
    browser: { write: fail }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
  const child = instance.child({ test: 'test' })
 | 
			
		||||
  child.info('msg-test')
 | 
			
		||||
  // use setTimeout because setImmediate isn't supported in most browsers
 | 
			
		||||
  setTimeout(() => {
 | 
			
		||||
    pass()
 | 
			
		||||
    end()
 | 
			
		||||
  }, 0)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throw if creating child without bindings', ({ end, throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => instance.child())
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('stubs write, flush and ee methods on instance', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
 | 
			
		||||
  ok(isFunc(instance.setMaxListeners))
 | 
			
		||||
  ok(isFunc(instance.getMaxListeners))
 | 
			
		||||
  ok(isFunc(instance.emit))
 | 
			
		||||
  ok(isFunc(instance.addListener))
 | 
			
		||||
  ok(isFunc(instance.on))
 | 
			
		||||
  ok(isFunc(instance.prependListener))
 | 
			
		||||
  ok(isFunc(instance.once))
 | 
			
		||||
  ok(isFunc(instance.prependOnceListener))
 | 
			
		||||
  ok(isFunc(instance.removeListener))
 | 
			
		||||
  ok(isFunc(instance.removeAllListeners))
 | 
			
		||||
  ok(isFunc(instance.listeners))
 | 
			
		||||
  ok(isFunc(instance.listenerCount))
 | 
			
		||||
  ok(isFunc(instance.eventNames))
 | 
			
		||||
  ok(isFunc(instance.write))
 | 
			
		||||
  ok(isFunc(instance.flush))
 | 
			
		||||
 | 
			
		||||
  is(instance.on(), undefined)
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes levels object', ({ end, same }) => {
 | 
			
		||||
  same(pino.levels, {
 | 
			
		||||
    values: {
 | 
			
		||||
      fatal: 60,
 | 
			
		||||
      error: 50,
 | 
			
		||||
      warn: 40,
 | 
			
		||||
      info: 30,
 | 
			
		||||
      debug: 20,
 | 
			
		||||
      trace: 10
 | 
			
		||||
    },
 | 
			
		||||
    labels: {
 | 
			
		||||
      10: 'trace',
 | 
			
		||||
      20: 'debug',
 | 
			
		||||
      30: 'info',
 | 
			
		||||
      40: 'warn',
 | 
			
		||||
      50: 'error',
 | 
			
		||||
      60: 'fatal'
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes LOG_VERSION', ({ end, is }) => {
 | 
			
		||||
  is(pino.LOG_VERSION, 1)
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes faux stdSerializers', ({ end, ok, same }) => {
 | 
			
		||||
  ok(pino.stdSerializers)
 | 
			
		||||
  // make sure faux stdSerializers match pino-std-serializers
 | 
			
		||||
  for (const serializer in pinoStdSerializers) {
 | 
			
		||||
    ok(pino.stdSerializers[serializer], `pino.stdSerializers.${serializer}`)
 | 
			
		||||
  }
 | 
			
		||||
  // confirm faux methods return empty objects
 | 
			
		||||
  same(pino.stdSerializers.req(), {})
 | 
			
		||||
  same(pino.stdSerializers.mapHttpRequest(), {})
 | 
			
		||||
  same(pino.stdSerializers.mapHttpResponse(), {})
 | 
			
		||||
  same(pino.stdSerializers.res(), {})
 | 
			
		||||
  // confirm wrapping function is a passthrough
 | 
			
		||||
  const noChange = { foo: 'bar', fuz: 42 }
 | 
			
		||||
  same(pino.stdSerializers.wrapRequestSerializer(noChange), noChange)
 | 
			
		||||
  same(pino.stdSerializers.wrapResponseSerializer(noChange), noChange)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes err stdSerializer', ({ end, ok }) => {
 | 
			
		||||
  ok(pino.stdSerializers.err)
 | 
			
		||||
  ok(pino.stdSerializers.err(Error()))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
consoleMethodTest('error')
 | 
			
		||||
consoleMethodTest('fatal', 'error')
 | 
			
		||||
consoleMethodTest('warn')
 | 
			
		||||
consoleMethodTest('info')
 | 
			
		||||
consoleMethodTest('debug')
 | 
			
		||||
consoleMethodTest('trace')
 | 
			
		||||
absentConsoleMethodTest('error', 'log')
 | 
			
		||||
absentConsoleMethodTest('warn', 'error')
 | 
			
		||||
absentConsoleMethodTest('info', 'log')
 | 
			
		||||
absentConsoleMethodTest('debug', 'log')
 | 
			
		||||
absentConsoleMethodTest('trace', 'log')
 | 
			
		||||
 | 
			
		||||
// do not run this with airtap
 | 
			
		||||
if (process.title !== 'browser') {
 | 
			
		||||
  test('in absence of console, log methods become noops', ({ end, ok }) => {
 | 
			
		||||
    var console = global.console
 | 
			
		||||
    delete global.console
 | 
			
		||||
    const instance = fresh('../browser')()
 | 
			
		||||
    global.console = console
 | 
			
		||||
    ok(fnName(instance.log).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.fatal).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.error).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.warn).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.info).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.debug).match(/noop/))
 | 
			
		||||
    ok(fnName(instance.trace).match(/noop/))
 | 
			
		||||
    end()
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('opts.browser.asObject logs pino-like object to console', ({ end, ok, is }) => {
 | 
			
		||||
  var info = console.info
 | 
			
		||||
  console.info = function (o) {
 | 
			
		||||
    is(o.level, 30)
 | 
			
		||||
    is(o.msg, 'test')
 | 
			
		||||
    ok(o.time)
 | 
			
		||||
    console.info = info
 | 
			
		||||
  }
 | 
			
		||||
  const instance = require('../browser')({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func log single string', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string joining', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test test2 test3')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test', 'test2', 'test3')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string joining when asObject is true', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true,
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test test2 test3')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test', 'test2', 'test3')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string joining when asObject is true', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true,
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test test2 test3')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test', 'test2', 'test3')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string object joining', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test', { test: 'test2' }, { test: 'test3' })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string object joining when asObject is true', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      asObject: true,
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('test', { test: 'test2' }, { test: 'test3' })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func string interpolation', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 'test2 test ({"test":"test3"})')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info('%s test (%j)', 'test2', { test: 'test3' })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func number', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.msg, 1)
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info(1)
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write func log single object', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: function (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.test, 'test')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.info({ test: 'test' })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write obj writes to methods corresponding to level', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: {
 | 
			
		||||
        error: function (o) {
 | 
			
		||||
          is(o.level, 50)
 | 
			
		||||
          is(o.test, 'test')
 | 
			
		||||
          ok(o.time)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.error({ test: 'test' })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.asObject/write supports child loggers', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.test, 'test')
 | 
			
		||||
        is(o.msg, 'msg-test')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const child = instance.child({ test: 'test' })
 | 
			
		||||
  child.info('msg-test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.asObject/write supports child child loggers', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.test, 'test')
 | 
			
		||||
        is(o.foo, 'bar')
 | 
			
		||||
        is(o.msg, 'msg-test')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const child = instance.child({ test: 'test' }).child({ foo: 'bar' })
 | 
			
		||||
  child.info('msg-test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.asObject/write supports child child child loggers', ({ end, ok, is }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write (o) {
 | 
			
		||||
        is(o.level, 30)
 | 
			
		||||
        is(o.test, 'test')
 | 
			
		||||
        is(o.foo, 'bar')
 | 
			
		||||
        is(o.baz, 'bop')
 | 
			
		||||
        is(o.msg, 'msg-test')
 | 
			
		||||
        ok(o.time)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const child = instance.child({ test: 'test' }).child({ foo: 'bar' }).child({ baz: 'bop' })
 | 
			
		||||
  child.info('msg-test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.asObject defensively mitigates naughty numbers', ({ end, pass }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    browser: { asObject: true, write: () => {} }
 | 
			
		||||
  })
 | 
			
		||||
  const child = instance.child({ test: 'test' })
 | 
			
		||||
  child._childLevel = -10
 | 
			
		||||
  child.info('test')
 | 
			
		||||
  pass() // if we reached here, there was no infinite loop, so, .. pass.
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('opts.browser.write obj falls back to console where a method is not supplied', ({ end, ok, is }) => {
 | 
			
		||||
  var info = console.info
 | 
			
		||||
  console.info = (o) => {
 | 
			
		||||
    is(o.level, 30)
 | 
			
		||||
    is(o.msg, 'test')
 | 
			
		||||
    ok(o.time)
 | 
			
		||||
    console.info = info
 | 
			
		||||
  }
 | 
			
		||||
  const instance = require('../browser')({
 | 
			
		||||
    browser: {
 | 
			
		||||
      write: {
 | 
			
		||||
        error (o) {
 | 
			
		||||
          is(o.level, 50)
 | 
			
		||||
          is(o.test, 'test')
 | 
			
		||||
          ok(o.time)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  instance.error({ test: 'test' })
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function levelTest (name) {
 | 
			
		||||
  test(name + ' logs', ({ end, is }) => {
 | 
			
		||||
    var msg = 'hello world'
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], msg)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    pino({ level: name })[name](msg)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('passing objects at level ' + name, ({ end, is }) => {
 | 
			
		||||
    var msg = { hello: 'world' }
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], msg)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    pino({ level: name })[name](msg)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('passing an object and a string at level ' + name, ({ end, is }) => {
 | 
			
		||||
    var a = { hello: 'world' }
 | 
			
		||||
    var b = 'a string'
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], a)
 | 
			
		||||
      is(args[1], b)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    pino({ level: name })[name](a, b)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('formatting logs as ' + name, ({ end, is }) => {
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], 'hello %d')
 | 
			
		||||
      is(args[1], 42)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    pino({ level: name })[name]('hello %d', 42)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('passing error at level ' + name, ({ end, is }) => {
 | 
			
		||||
    var err = new Error('myerror')
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], err)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    pino({ level: name })[name](err)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('passing error with a serializer at level ' + name, ({ end, is }) => {
 | 
			
		||||
    // in browser - should have no effect (should not crash)
 | 
			
		||||
    var err = new Error('myerror')
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0].err, err)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    const instance = pino({
 | 
			
		||||
      level: name,
 | 
			
		||||
      serializers: {
 | 
			
		||||
        err: pino.stdSerializers.err
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    instance[name]({ err: err })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('child logger for level ' + name, ({ end, is }) => {
 | 
			
		||||
    var msg = 'hello world'
 | 
			
		||||
    var parent = { hello: 'world' }
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], parent)
 | 
			
		||||
      is(args[1], msg)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    const instance = pino({ level: name })
 | 
			
		||||
    const child = instance.child(parent)
 | 
			
		||||
    child[name](msg)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('child-child logger for level ' + name, ({ end, is }) => {
 | 
			
		||||
    var msg = 'hello world'
 | 
			
		||||
    var grandParent = { hello: 'world' }
 | 
			
		||||
    var parent = { hello: 'you' }
 | 
			
		||||
    sink(name, (args) => {
 | 
			
		||||
      is(args[0], grandParent)
 | 
			
		||||
      is(args[1], parent)
 | 
			
		||||
      is(args[2], msg)
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    const instance = pino({ level: name })
 | 
			
		||||
    const child = instance.child(grandParent).child(parent)
 | 
			
		||||
    child[name](msg)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function consoleMethodTest (level, method) {
 | 
			
		||||
  if (!method) method = level
 | 
			
		||||
  test('pino().' + level + ' uses console.' + method, ({ end, is }) => {
 | 
			
		||||
    sink(method, (args) => {
 | 
			
		||||
      is(args[0], 'test')
 | 
			
		||||
      end()
 | 
			
		||||
    })
 | 
			
		||||
    const instance = require('../browser')({ level: level })
 | 
			
		||||
    instance[level]('test')
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function absentConsoleMethodTest (method, fallback) {
 | 
			
		||||
  test('in absence of console.' + method + ', console.' + fallback + ' is used', ({ end, is }) => {
 | 
			
		||||
    var fn = console[method]
 | 
			
		||||
    console[method] = undefined
 | 
			
		||||
    sink(fallback, function (args) {
 | 
			
		||||
      is(args[0], 'test')
 | 
			
		||||
      end()
 | 
			
		||||
      console[method] = fn
 | 
			
		||||
    })
 | 
			
		||||
    const instance = require('../browser')({ level: method })
 | 
			
		||||
    instance[method]('test')
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function isFunc (fn) { return typeof fn === 'function' }
 | 
			
		||||
function fnName (fn) {
 | 
			
		||||
  var rx = /^\s*function\s*([^(]*)/i
 | 
			
		||||
  var match = rx.exec(fn)
 | 
			
		||||
  return match && match[1]
 | 
			
		||||
}
 | 
			
		||||
function sink (method, fn) {
 | 
			
		||||
  if (method === 'fatal') method = 'error'
 | 
			
		||||
  var orig = console[method]
 | 
			
		||||
  console[method] = function () {
 | 
			
		||||
    console[method] = orig
 | 
			
		||||
    fn(Array.prototype.slice.call(arguments))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								node_modules/pino/test/crlf.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								node_modules/pino/test/crlf.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
function capture () {
 | 
			
		||||
  const ws = writer((chunk, enc, cb) => {
 | 
			
		||||
    ws.data += chunk.toString()
 | 
			
		||||
    cb()
 | 
			
		||||
  })
 | 
			
		||||
  ws.data = ''
 | 
			
		||||
  return ws
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('pino uses LF by default', async ({ ok }) => {
 | 
			
		||||
  const stream = capture()
 | 
			
		||||
  const logger = pino(stream)
 | 
			
		||||
  logger.info('foo')
 | 
			
		||||
  logger.error('bar')
 | 
			
		||||
  ok(/foo[^\r\n]+\n[^\r\n]+bar[^\r\n]+\n/.test(stream.data))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino can log CRLF', async ({ ok }) => {
 | 
			
		||||
  const stream = capture()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    crlf: true
 | 
			
		||||
  }, stream)
 | 
			
		||||
  logger.info('foo')
 | 
			
		||||
  logger.error('bar')
 | 
			
		||||
  ok(/foo[^\n]+\r\n[^\n]+bar[^\n]+\r\n/.test(stream.data))
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										308
									
								
								node_modules/pino/test/custom-levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								node_modules/pino/test/custom-levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,308 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* eslint no-prototype-builtins: 0 */
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
test('adds additional levels', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35,
 | 
			
		||||
      bar: 45
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  logger.foo('test')
 | 
			
		||||
  const { level } = await once(stream, 'data')
 | 
			
		||||
  is(level, 35)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels does not override default levels', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  logger.info('test')
 | 
			
		||||
  const { level } = await once(stream, 'data')
 | 
			
		||||
  is(level, 30)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('default levels can be redefined using custom levels', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      info: 35,
 | 
			
		||||
      debug: 45
 | 
			
		||||
    },
 | 
			
		||||
    useOnlyCustomLevels: true
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  is(logger.hasOwnProperty('info'), true)
 | 
			
		||||
 | 
			
		||||
  logger.info('test')
 | 
			
		||||
  const { level } = await once(stream, 'data')
 | 
			
		||||
  is(level, 35)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels overrides default level label if use useOnlyCustomLevels', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    },
 | 
			
		||||
    useOnlyCustomLevels: true,
 | 
			
		||||
    level: 'foo'
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  is(logger.hasOwnProperty('info'), false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels overrides default level value if use useOnlyCustomLevels', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    },
 | 
			
		||||
    useOnlyCustomLevels: true,
 | 
			
		||||
    level: 35
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  is(logger.hasOwnProperty('info'), false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels are inherited by children', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  logger.child({ childMsg: 'ok' }).foo('test')
 | 
			
		||||
  const { msg, childMsg, level } = await once(stream, 'data')
 | 
			
		||||
  is(level, 35)
 | 
			
		||||
  is(childMsg, 'ok')
 | 
			
		||||
  is(msg, 'test')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels can be specified on child bindings', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino(stream).child({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    },
 | 
			
		||||
    childMsg: 'ok'
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.foo('test')
 | 
			
		||||
  const { msg, childMsg, level } = await once(stream, 'data')
 | 
			
		||||
  is(level, 35)
 | 
			
		||||
  is(childMsg, 'ok')
 | 
			
		||||
  is(msg, 'test')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('customLevels property child bindings does not get logged', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino(stream).child({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    },
 | 
			
		||||
    childMsg: 'ok'
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.foo('test')
 | 
			
		||||
  const { customLevels } = await once(stream, 'data')
 | 
			
		||||
  is(customLevels, undefined)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when specifying pre-existing parent labels via child bindings', async ({ is, throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  throws(() => pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }, stream).child({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 45
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  )
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 35
 | 
			
		||||
      }
 | 
			
		||||
    }, stream).child({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 45
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'levels cannot be overridden')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when specifying pre-existing parent values via child bindings', async ({ is, throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  throws(() => pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }, stream).child({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      bar: 35
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  )
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 35
 | 
			
		||||
      }
 | 
			
		||||
    }, stream).child({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        bar: 35
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'pre-existing level values cannot be used for new levels')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when specifying core values via child bindings', async ({ is, throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  throws(() => pino(stream).child({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 30
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  )
 | 
			
		||||
  try {
 | 
			
		||||
    pino(stream).child({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 30
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'pre-existing level values cannot be used for new levels')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when useOnlyCustomLevels is set true without customLevels', async ({ is, throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  throws(() => pino({
 | 
			
		||||
    useOnlyCustomLevels: true
 | 
			
		||||
  }, stream)
 | 
			
		||||
  )
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      useOnlyCustomLevels: true
 | 
			
		||||
    }, stream)
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'customLevels is required if useOnlyCustomLevels is set true')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom level on one instance does not affect other instances', async ({ is }) => {
 | 
			
		||||
  pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 37
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  is(typeof pino().foo, 'undefined')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting level below or at custom level will successfully log', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ customLevels: { foo: 35 } }, stream)
 | 
			
		||||
  instance.level = 'foo'
 | 
			
		||||
  instance.info('nope')
 | 
			
		||||
  instance.foo('bar')
 | 
			
		||||
  const { msg } = await once(stream, 'data')
 | 
			
		||||
  is(msg, 'bar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom level below level threshold will not log', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ customLevels: { foo: 15 } }, stream)
 | 
			
		||||
  instance.level = 'info'
 | 
			
		||||
  instance.info('bar')
 | 
			
		||||
  instance.foo('nope')
 | 
			
		||||
  const { msg } = await once(stream, 'data')
 | 
			
		||||
  is(msg, 'bar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('does not share custom level state across siblings', async ({ doesNotThrow }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino(stream)
 | 
			
		||||
  logger.child({
 | 
			
		||||
    customLevels: { foo: 35 }
 | 
			
		||||
  })
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    logger.child({
 | 
			
		||||
      customLevels: { foo: 35 }
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom level does not affect levelKey', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35,
 | 
			
		||||
      bar: 45
 | 
			
		||||
    },
 | 
			
		||||
    levelKey: 'priority'
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  logger.foo('test')
 | 
			
		||||
  const { priority } = await once(stream, 'data')
 | 
			
		||||
  is(priority, 35)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom levels accesible in prettifier function', async ({ plan, same }) => {
 | 
			
		||||
  plan(1)
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    prettyPrint: true,
 | 
			
		||||
    prettifier: function prettifierFactory () {
 | 
			
		||||
      const instance = this
 | 
			
		||||
      return function () {
 | 
			
		||||
        same(instance.levels, {
 | 
			
		||||
          labels: {
 | 
			
		||||
            10: 'trace',
 | 
			
		||||
            20: 'debug',
 | 
			
		||||
            30: 'info',
 | 
			
		||||
            35: 'foo',
 | 
			
		||||
            40: 'warn',
 | 
			
		||||
            45: 'bar',
 | 
			
		||||
            50: 'error',
 | 
			
		||||
            60: 'fatal'
 | 
			
		||||
          },
 | 
			
		||||
          values: {
 | 
			
		||||
            trace: 10,
 | 
			
		||||
            debug: 20,
 | 
			
		||||
            info: 30,
 | 
			
		||||
            warn: 40,
 | 
			
		||||
            error: 50,
 | 
			
		||||
            fatal: 60,
 | 
			
		||||
            foo: 35,
 | 
			
		||||
            bar: 45
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35,
 | 
			
		||||
      bar: 45
 | 
			
		||||
    },
 | 
			
		||||
    changeLevelName: 'priority'
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  logger.foo('test')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										179
									
								
								node_modules/pino/test/error.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								node_modules/pino/test/error.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,179 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* eslint no-prototype-builtins: 0 */
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
const level = 50
 | 
			
		||||
const name = 'error'
 | 
			
		||||
 | 
			
		||||
test('err is serialized with additional properties set on the Error object', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const err = Object.assign(new Error('myerror'), { foo: 'bar' })
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: level,
 | 
			
		||||
    type: 'Error',
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack,
 | 
			
		||||
    foo: err.foo,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('type should be retained, even if type is a property', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const err = Object.assign(new Error('myerror'), { type: 'bar' })
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: level,
 | 
			
		||||
    type: 'bar',
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('type, message and stack should be first level properties', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const err = Object.assign(new Error('foo'), { foo: 'bar' })
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: level,
 | 
			
		||||
    type: 'Error',
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack,
 | 
			
		||||
    foo: err.foo,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('err serializer', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const err = Object.assign(new Error('myerror'), { foo: 'bar' })
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      err: pino.stdSerializers.err
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name]({ err })
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: level,
 | 
			
		||||
    err: {
 | 
			
		||||
      type: 'Error',
 | 
			
		||||
      message: err.message,
 | 
			
		||||
      stack: err.stack,
 | 
			
		||||
      foo: err.foo
 | 
			
		||||
    },
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('an error with statusCode property is not confused for a http response', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const err = Object.assign(new Error('StatusCodeErr'), { statusCode: 500 })
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: level,
 | 
			
		||||
    type: 'Error',
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack,
 | 
			
		||||
    statusCode: err.statusCode,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('stack is omitted if it is not set on err', t => {
 | 
			
		||||
  t.plan(2)
 | 
			
		||||
  var err = new Error('myerror')
 | 
			
		||||
  delete err.stack
 | 
			
		||||
  var instance = pino(sink(function (chunk, enc, cb) {
 | 
			
		||||
    t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    t.equal(chunk.hasOwnProperty('stack'), false)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('stack is rendered as any other property if it\'s not a string', t => {
 | 
			
		||||
  t.plan(3)
 | 
			
		||||
  var err = new Error('myerror')
 | 
			
		||||
  err.stack = null
 | 
			
		||||
  var instance = pino(sink(function (chunk, enc, cb) {
 | 
			
		||||
    t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    t.equal(chunk.hasOwnProperty('stack'), true)
 | 
			
		||||
    t.equal(chunk.stack, null)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name](err)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly ignores toString on errors', async ({ same }) => {
 | 
			
		||||
  const err = new Error('myerror')
 | 
			
		||||
  err.toString = () => undefined
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    test: 'this'
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal(err)
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 60,
 | 
			
		||||
    type: 'Error',
 | 
			
		||||
    msg: err.message,
 | 
			
		||||
    stack: err.stack,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										93
									
								
								node_modules/pino/test/escaping.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								node_modules/pino/test/escaping.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
 | 
			
		||||
function testEscape (ch, key) {
 | 
			
		||||
  test('correctly escape ' + ch, async ({ same }) => {
 | 
			
		||||
    const stream = sink()
 | 
			
		||||
    const instance = pino({
 | 
			
		||||
      name: 'hello'
 | 
			
		||||
    }, stream)
 | 
			
		||||
    instance.fatal('this contains ' + key)
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 60,
 | 
			
		||||
      name: 'hello',
 | 
			
		||||
      msg: 'this contains ' + key,
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
testEscape('\\n', '\n')
 | 
			
		||||
testEscape('\\/', '/')
 | 
			
		||||
testEscape('\\\\', '\\')
 | 
			
		||||
testEscape('\\r', '\r')
 | 
			
		||||
testEscape('\\t', '\t')
 | 
			
		||||
testEscape('\\b', '\b')
 | 
			
		||||
 | 
			
		||||
const toEscape = [
 | 
			
		||||
  '\u0000', // NUL  Null character
 | 
			
		||||
  '\u0001', // SOH  Start of Heading
 | 
			
		||||
  '\u0002', // STX  Start of Text
 | 
			
		||||
  '\u0003', // ETX  End-of-text character
 | 
			
		||||
  '\u0004', // EOT  End-of-transmission character
 | 
			
		||||
  '\u0005', // ENQ  Enquiry character
 | 
			
		||||
  '\u0006', // ACK  Acknowledge character
 | 
			
		||||
  '\u0007', // BEL  Bell character
 | 
			
		||||
  '\u0008', // BS   Backspace
 | 
			
		||||
  '\u0009', // HT   Horizontal tab
 | 
			
		||||
  '\u000A', // LF   Line feed
 | 
			
		||||
  '\u000B', // VT   Vertical tab
 | 
			
		||||
  '\u000C', // FF   Form feed
 | 
			
		||||
  '\u000D', // CR   Carriage return
 | 
			
		||||
  '\u000E', // SO   Shift Out
 | 
			
		||||
  '\u000F', // SI   Shift In
 | 
			
		||||
  '\u0010', // DLE  Data Link Escape
 | 
			
		||||
  '\u0011', // DC1  Device Control 1
 | 
			
		||||
  '\u0012', // DC2  Device Control 2
 | 
			
		||||
  '\u0013', // DC3  Device Control 3
 | 
			
		||||
  '\u0014', // DC4  Device Control 4
 | 
			
		||||
  '\u0015', // NAK  Negative-acknowledge character
 | 
			
		||||
  '\u0016', // SYN  Synchronous Idle
 | 
			
		||||
  '\u0017', // ETB  End of Transmission Block
 | 
			
		||||
  '\u0018', // CAN  Cancel character
 | 
			
		||||
  '\u0019', // EM   End of Medium
 | 
			
		||||
  '\u001A', // SUB  Substitute character
 | 
			
		||||
  '\u001B', // ESC  Escape character
 | 
			
		||||
  '\u001C', // FS   File Separator
 | 
			
		||||
  '\u001D', // GS   Group Separator
 | 
			
		||||
  '\u001E', // RS   Record Separator
 | 
			
		||||
  '\u001F' // US   Unit Separator
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
toEscape.forEach((key) => {
 | 
			
		||||
  testEscape(JSON.stringify(key), key)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly escape `hello \\u001F world \\n \\u0022`', async ({ same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    name: 'hello'
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.fatal('hello \u001F world \n \u0022')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid: pid,
 | 
			
		||||
    hostname: hostname,
 | 
			
		||||
    level: 60,
 | 
			
		||||
    name: 'hello',
 | 
			
		||||
    msg: 'hello \u001F world \n \u0022',
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										53
									
								
								node_modules/pino/test/exit.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								node_modules/pino/test/exit.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const execa = require('execa')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
const { once } = require('./helper')
 | 
			
		||||
 | 
			
		||||
// https://github.com/pinojs/pino/issues/542
 | 
			
		||||
test('pino.destination log everything when calling process.exit(0)', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'destination-exit.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
 | 
			
		||||
  isNot(actual.match(/hello/), null)
 | 
			
		||||
  isNot(actual.match(/world/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino.extreme does not log everything when calling process.exit(0)', async ({ is }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'extreme-exit.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
 | 
			
		||||
  is(actual.match(/hello/), null)
 | 
			
		||||
  is(actual.match(/world/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino.extreme logs everything when calling flushSync', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'extreme-flush-exit.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
 | 
			
		||||
  isNot(actual.match(/hello/), null)
 | 
			
		||||
  isNot(actual.match(/world/), null)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										125
									
								
								node_modules/pino/test/extreme.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								node_modules/pino/test/extreme.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { createWriteStream } = require('fs')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { fork } = require('child_process')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
const { once, getPathToNull } = require('./helper')
 | 
			
		||||
 | 
			
		||||
test('extreme mode', async ({ is, teardown }) => {
 | 
			
		||||
  const now = Date.now
 | 
			
		||||
  const hostname = os.hostname
 | 
			
		||||
  const proc = process
 | 
			
		||||
  global.process = {
 | 
			
		||||
    __proto__: process,
 | 
			
		||||
    pid: 123456
 | 
			
		||||
  }
 | 
			
		||||
  Date.now = () => 1459875739796
 | 
			
		||||
  os.hostname = () => 'abcdefghijklmnopqr'
 | 
			
		||||
  delete require.cache[require.resolve('../')]
 | 
			
		||||
  const pino = require('../')
 | 
			
		||||
  var expected = ''
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const normal = pino(writer((s, enc, cb) => {
 | 
			
		||||
    expected += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const dest = createWriteStream(getPathToNull())
 | 
			
		||||
  dest.write = (s) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
  }
 | 
			
		||||
  const extreme = pino(dest)
 | 
			
		||||
 | 
			
		||||
  var i = 44
 | 
			
		||||
  while (i--) {
 | 
			
		||||
    normal.info('h')
 | 
			
		||||
    extreme.info('h')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var expected2 = expected.split('\n')[0]
 | 
			
		||||
  var actual2 = ''
 | 
			
		||||
 | 
			
		||||
  const child = fork(join(__dirname, '/fixtures/extreme.js'), { silent: true })
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual2 += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  is(actual, expected)
 | 
			
		||||
  is(actual2.trim(), expected2)
 | 
			
		||||
 | 
			
		||||
  teardown(() => {
 | 
			
		||||
    os.hostname = hostname
 | 
			
		||||
    Date.now = now
 | 
			
		||||
    global.process = proc
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('extreme mode with child', async ({ is, teardown }) => {
 | 
			
		||||
  const now = Date.now
 | 
			
		||||
  const hostname = os.hostname
 | 
			
		||||
  const proc = process
 | 
			
		||||
  global.process = {
 | 
			
		||||
    __proto__: process,
 | 
			
		||||
    pid: 123456
 | 
			
		||||
  }
 | 
			
		||||
  Date.now = function () {
 | 
			
		||||
    return 1459875739796
 | 
			
		||||
  }
 | 
			
		||||
  os.hostname = function () {
 | 
			
		||||
    return 'abcdefghijklmnopqr'
 | 
			
		||||
  }
 | 
			
		||||
  delete require.cache[require.resolve('../')]
 | 
			
		||||
  const pino = require('../')
 | 
			
		||||
  var expected = ''
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const normal = pino(writer((s, enc, cb) => {
 | 
			
		||||
    expected += s
 | 
			
		||||
    cb()
 | 
			
		||||
  })).child({ hello: 'world' })
 | 
			
		||||
 | 
			
		||||
  const dest = createWriteStream(getPathToNull())
 | 
			
		||||
  dest.write = function (s) { actual += s }
 | 
			
		||||
  const extreme = pino(dest).child({ hello: 'world' })
 | 
			
		||||
 | 
			
		||||
  var i = 500
 | 
			
		||||
  while (i--) {
 | 
			
		||||
    normal.info('h')
 | 
			
		||||
    extreme.info('h')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  extreme.flush()
 | 
			
		||||
 | 
			
		||||
  var expected2 = expected.split('\n')[0]
 | 
			
		||||
  var actual2 = ''
 | 
			
		||||
 | 
			
		||||
  const child = fork(join(__dirname, '/fixtures/extreme-child.js'), { silent: true })
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual2 += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  is(actual, expected)
 | 
			
		||||
  is(actual2.trim(), expected2)
 | 
			
		||||
 | 
			
		||||
  teardown(() => {
 | 
			
		||||
    os.hostname = hostname
 | 
			
		||||
    Date.now = now
 | 
			
		||||
    global.process = proc
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throw an error if extreme is passed', async ({ throws }) => {
 | 
			
		||||
  const pino = require('..')
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ extreme: true })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('flush does nothing without extreme mode', async () => {
 | 
			
		||||
  var instance = require('..')()
 | 
			
		||||
  instance.flush()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										182
									
								
								node_modules/pino/test/final.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								node_modules/pino/test/final.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,182 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const pino = require('..')
 | 
			
		||||
const fs = require('fs')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sleep, getPathToNull } = require('./helper')
 | 
			
		||||
 | 
			
		||||
test('replaces onTerminated option', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({
 | 
			
		||||
      onTerminated: () => {}
 | 
			
		||||
    })
 | 
			
		||||
  }, Error('The onTerminated option has been removed, use pino.final instead'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if not supplied a logger instance', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino.final()
 | 
			
		||||
  }, Error('expected a pino logger instance'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if the supplied handler is not a function', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino.final(pino(), 'dummy')
 | 
			
		||||
  }, Error('if supplied, the handler parameter should be a function'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if not supplied logger with pino.extreme instance', async ({ throws, doesNotThrow }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino.final(pino(fs.createWriteStream(getPathToNull())), () => {})
 | 
			
		||||
  }, Error('final requires a stream that has a flushSync method, such as pino.destination and pino.extreme'))
 | 
			
		||||
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    pino.final(pino(pino.extreme()), () => {})
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    pino.final(pino(pino.extreme()), () => {})
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns an exit listener function', async ({ is }) => {
 | 
			
		||||
  is(typeof pino.final(pino(pino.extreme()), () => {}), 'function')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('listener function immediately sync flushes when fired', async ({ pass, fail }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  var passed = false
 | 
			
		||||
  dest.flushSync = () => {
 | 
			
		||||
    passed = true
 | 
			
		||||
    pass('flushSync called')
 | 
			
		||||
  }
 | 
			
		||||
  pino.final(pino(dest), () => {})()
 | 
			
		||||
  await sleep(10)
 | 
			
		||||
  if (passed === false) fail('flushSync not called')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('listener function immediately sync flushes when fired (pino.destination)', async ({ pass, fail }) => {
 | 
			
		||||
  const dest = pino.destination(getPathToNull())
 | 
			
		||||
  var passed = false
 | 
			
		||||
  dest.flushSync = () => {
 | 
			
		||||
    passed = true
 | 
			
		||||
    pass('flushSync called')
 | 
			
		||||
  }
 | 
			
		||||
  pino.final(pino(dest), () => {})()
 | 
			
		||||
  await sleep(10)
 | 
			
		||||
  if (passed === false) fail('flushSync not called')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('swallows the non-ready error', async ({ doesNotThrow }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    pino.final(pino(dest), () => {})()
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('listener function triggers handler function parameter', async ({ pass, fail }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  var passed = false
 | 
			
		||||
  pino.final(pino(dest), () => {
 | 
			
		||||
    passed = true
 | 
			
		||||
    pass('handler function triggered')
 | 
			
		||||
  })()
 | 
			
		||||
  await sleep(10)
 | 
			
		||||
  if (passed === false) fail('handler function not triggered')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes any error to the handler', async ({ is }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  pino.final(pino(dest), (err) => {
 | 
			
		||||
    is(err.message, 'test')
 | 
			
		||||
  })(Error('test'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes a specialized final logger instance', async ({ is, isNot, error }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  const logger = pino(dest)
 | 
			
		||||
  pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
    error(err)
 | 
			
		||||
    is(typeof finalLogger.trace, 'function')
 | 
			
		||||
    is(typeof finalLogger.debug, 'function')
 | 
			
		||||
    is(typeof finalLogger.info, 'function')
 | 
			
		||||
    is(typeof finalLogger.warn, 'function')
 | 
			
		||||
    is(typeof finalLogger.error, 'function')
 | 
			
		||||
    is(typeof finalLogger.fatal, 'function')
 | 
			
		||||
 | 
			
		||||
    isNot(finalLogger.trace, logger.trace)
 | 
			
		||||
    isNot(finalLogger.debug, logger.debug)
 | 
			
		||||
    isNot(finalLogger.info, logger.info)
 | 
			
		||||
    isNot(finalLogger.warn, logger.warn)
 | 
			
		||||
    isNot(finalLogger.error, logger.error)
 | 
			
		||||
    isNot(finalLogger.fatal, logger.fatal)
 | 
			
		||||
 | 
			
		||||
    is(finalLogger.child, logger.child)
 | 
			
		||||
    is(finalLogger.levels, logger.levels)
 | 
			
		||||
  })()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns a specialized final logger instance if no handler is passed', async ({ is, isNot }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  const logger = pino(dest)
 | 
			
		||||
  const finalLogger = pino.final(logger)
 | 
			
		||||
  is(typeof finalLogger.trace, 'function')
 | 
			
		||||
  is(typeof finalLogger.debug, 'function')
 | 
			
		||||
  is(typeof finalLogger.info, 'function')
 | 
			
		||||
  is(typeof finalLogger.warn, 'function')
 | 
			
		||||
  is(typeof finalLogger.error, 'function')
 | 
			
		||||
  is(typeof finalLogger.fatal, 'function')
 | 
			
		||||
 | 
			
		||||
  isNot(finalLogger.trace, logger.trace)
 | 
			
		||||
  isNot(finalLogger.debug, logger.debug)
 | 
			
		||||
  isNot(finalLogger.info, logger.info)
 | 
			
		||||
  isNot(finalLogger.warn, logger.warn)
 | 
			
		||||
  isNot(finalLogger.error, logger.error)
 | 
			
		||||
  isNot(finalLogger.fatal, logger.fatal)
 | 
			
		||||
 | 
			
		||||
  is(finalLogger.child, logger.child)
 | 
			
		||||
  is(finalLogger.levels, logger.levels)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('final logger instances synchronously flush after a log method call', async ({ pass, fail, error }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  const logger = pino(dest)
 | 
			
		||||
  var passed = false
 | 
			
		||||
  var count = 0
 | 
			
		||||
  dest.flushSync = () => {
 | 
			
		||||
    count++
 | 
			
		||||
    if (count === 2) {
 | 
			
		||||
      passed = true
 | 
			
		||||
      pass('flushSync called')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
    error(err)
 | 
			
		||||
    finalLogger.info('hello')
 | 
			
		||||
  })()
 | 
			
		||||
  await sleep(10)
 | 
			
		||||
  if (passed === false) fail('flushSync not called')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('also instruments custom log methods', async ({ pass, fail, error }) => {
 | 
			
		||||
  const dest = pino.extreme(getPathToNull())
 | 
			
		||||
  const logger = pino({
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }, dest)
 | 
			
		||||
  var passed = false
 | 
			
		||||
  var count = 0
 | 
			
		||||
  dest.flushSync = () => {
 | 
			
		||||
    count++
 | 
			
		||||
    if (count === 2) {
 | 
			
		||||
      passed = true
 | 
			
		||||
      pass('flushSync called')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  pino.final(logger, (err, finalLogger) => {
 | 
			
		||||
    error(err)
 | 
			
		||||
    finalLogger.foo('hello')
 | 
			
		||||
  })()
 | 
			
		||||
  await sleep(10)
 | 
			
		||||
  if (passed === false) fail('flushSync not called')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/broken-pipe/basic.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/broken-pipe/basic.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
 | 
			
		||||
const pino = require('../../..')()
 | 
			
		||||
 | 
			
		||||
pino.info('hello world')
 | 
			
		||||
							
								
								
									
										10
									
								
								node_modules/pino/test/fixtures/broken-pipe/destination.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								node_modules/pino/test/fixtures/broken-pipe/destination.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
 | 
			
		||||
const pino = require('../../..')
 | 
			
		||||
const logger = pino(pino.destination())
 | 
			
		||||
 | 
			
		||||
logger.info('hello world')
 | 
			
		||||
							
								
								
									
										12
									
								
								node_modules/pino/test/fixtures/broken-pipe/extreme.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								node_modules/pino/test/fixtures/broken-pipe/extreme.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
 | 
			
		||||
const pino = require('../../..')
 | 
			
		||||
const logger = pino(pino.extreme())
 | 
			
		||||
 | 
			
		||||
for (let i = 0; i < 1000; i++) {
 | 
			
		||||
  logger.info('hello world')
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								node_modules/pino/test/fixtures/destination-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								node_modules/pino/test/fixtures/destination-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../'))
 | 
			
		||||
var logger = pino({}, pino.destination(1))
 | 
			
		||||
logger.info('hello')
 | 
			
		||||
logger.info('world')
 | 
			
		||||
process.exit(0)
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/extreme-child.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/extreme-child.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../'))
 | 
			
		||||
var extreme = pino(pino.extreme()).child({ hello: 'world' })
 | 
			
		||||
pino.final(extreme, (_, logger) => logger.info('h'))()
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/extreme-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/extreme-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../'))
 | 
			
		||||
var dest = pino.extreme(1)
 | 
			
		||||
var logger = pino({}, dest)
 | 
			
		||||
logger.info('hello')
 | 
			
		||||
logger.info('world')
 | 
			
		||||
process.exit(0)
 | 
			
		||||
							
								
								
									
										10
									
								
								node_modules/pino/test/fixtures/extreme-flush-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								node_modules/pino/test/fixtures/extreme-flush-exit.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../'))
 | 
			
		||||
var dest = pino.extreme(1)
 | 
			
		||||
var logger = pino({}, dest)
 | 
			
		||||
logger.info('hello')
 | 
			
		||||
logger.info('world')
 | 
			
		||||
dest.flushSync()
 | 
			
		||||
process.exit(0)
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/extreme.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/extreme.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../'))
 | 
			
		||||
var extreme = pino(pino.extreme())
 | 
			
		||||
pino.final(extreme, (_, logger) => logger.info('h'))()
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/basic.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/basic.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										8
									
								
								node_modules/pino/test/fixtures/pretty/child.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								node_modules/pino/test/fixtures/pretty/child.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true }).child({ a: 1 })
 | 
			
		||||
log.info('h')
 | 
			
		||||
log.child({ b: 2 }).info('h3')
 | 
			
		||||
setTimeout(() => log.info('h2'), 200)
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/custom-time-label.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/custom-time-label.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  timestamp: () => ',"custom-time-label":"test"',
 | 
			
		||||
  prettyPrint: true
 | 
			
		||||
})
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/custom-time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/custom-time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  timestamp: () => ',"time":"test"',
 | 
			
		||||
  prettyPrint: true
 | 
			
		||||
})
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										10
									
								
								node_modules/pino/test/fixtures/pretty/dateformat.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								node_modules/pino/test/fixtures/pretty/dateformat.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,10 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  prettyPrint: {
 | 
			
		||||
    translateTime: true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/error-props.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/error-props.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  prettyPrint: { errorProps: 'code,errno' }
 | 
			
		||||
})
 | 
			
		||||
var err = Object.assign(new Error('kaboom'), { code: 'ENOENT', errno: 1 })
 | 
			
		||||
log.error(err)
 | 
			
		||||
							
								
								
									
										7
									
								
								node_modules/pino/test/fixtures/pretty/error.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/pino/test/fixtures/pretty/error.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
log.error(new Error('kaboom'))
 | 
			
		||||
log.error(new Error('kaboom'), 'with', 'a', 'message')
 | 
			
		||||
							
								
								
									
										8
									
								
								node_modules/pino/test/fixtures/pretty/final-no-log-before.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								node_modules/pino/test/fixtures/pretty/final-no-log-before.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
process.once('beforeExit', pino.final(log, (_, logger) => {
 | 
			
		||||
  logger.info('beforeExit')
 | 
			
		||||
}))
 | 
			
		||||
							
								
								
									
										7
									
								
								node_modules/pino/test/fixtures/pretty/final-return.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/pino/test/fixtures/pretty/final-return.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
log.info('h')
 | 
			
		||||
pino.final(log).info('after')
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/final.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/final.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
log.info('h')
 | 
			
		||||
process.once('beforeExit', pino.final(log, (_, logger) => {
 | 
			
		||||
  logger.info('beforeExit')
 | 
			
		||||
}))
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/level-first.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/level-first.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: { levelFirst: true } })
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/no-time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/no-time.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  timestamp: false,
 | 
			
		||||
  prettyPrint: true
 | 
			
		||||
})
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/obj-msg-prop.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/obj-msg-prop.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: true })
 | 
			
		||||
log.info({ msg: 'hello' })
 | 
			
		||||
							
								
								
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/pretty-factory.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								node_modules/pino/test/fixtures/pretty/pretty-factory.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({ prettyPrint: { levelFirst: true }, prettifier: require('pino-pretty') })
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/redact.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/pino/test/fixtures/pretty/redact.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  prettyPrint: true,
 | 
			
		||||
  redact: ['foo.an']
 | 
			
		||||
})
 | 
			
		||||
log.info({ foo: { an: 'object' } }, 'h')
 | 
			
		||||
							
								
								
									
										17
									
								
								node_modules/pino/test/fixtures/pretty/serializers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								node_modules/pino/test/fixtures/pretty/serializers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  prettyPrint: true,
 | 
			
		||||
  serializers: {
 | 
			
		||||
    foo (obj) {
 | 
			
		||||
      if (obj.an !== 'object') {
 | 
			
		||||
        throw new Error('kaboom')
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return 'bar'
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
log.info({ foo: { an: 'object' } }, 'h')
 | 
			
		||||
							
								
								
									
										13
									
								
								node_modules/pino/test/fixtures/pretty/skipped-output.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								node_modules/pino/test/fixtures/pretty/skipped-output.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('./../../../'))
 | 
			
		||||
var log = pino({
 | 
			
		||||
  prettyPrint: true,
 | 
			
		||||
  prettifier: function () {
 | 
			
		||||
    return function () {
 | 
			
		||||
      return undefined
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
log.info('h')
 | 
			
		||||
							
								
								
									
										11
									
								
								node_modules/pino/test/fixtures/stdout-hack-protection.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								node_modules/pino/test/fixtures/stdout-hack-protection.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
global.process = { __proto__: process, pid: 123456 }
 | 
			
		||||
 | 
			
		||||
const write = process.stdout.write.bind(process.stdout)
 | 
			
		||||
process.stdout.write = function (chunk) {
 | 
			
		||||
  write('hack ' + chunk)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Date.now = function () { return 1459875739796 }
 | 
			
		||||
require('os').hostname = function () { return 'abcdefghijklmnopqr' }
 | 
			
		||||
var pino = require(require.resolve('../../'))()
 | 
			
		||||
pino.info('me')
 | 
			
		||||
							
								
								
									
										55
									
								
								node_modules/pino/test/helper.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								node_modules/pino/test/helper.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
const split = require('split2')
 | 
			
		||||
const pid = process.pid
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
const v = 1
 | 
			
		||||
 | 
			
		||||
const isWin = process.platform === 'win32'
 | 
			
		||||
 | 
			
		||||
function getPathToNull () {
 | 
			
		||||
  return isWin ? '\\\\.\\NUL' : '/dev/null'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function once (emitter, name) {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    if (name !== 'error') emitter.once('error', reject)
 | 
			
		||||
    emitter.once(name, (...args) => {
 | 
			
		||||
      emitter.removeListener('error', reject)
 | 
			
		||||
      resolve(...args)
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sink (func) {
 | 
			
		||||
  const result = split((data) => {
 | 
			
		||||
    try {
 | 
			
		||||
      return JSON.parse(data)
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.log(err)
 | 
			
		||||
      console.log(data)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  if (func) result.pipe(writer.obj(func))
 | 
			
		||||
  return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function check (is, chunk, level, msg) {
 | 
			
		||||
  is(new Date(chunk.time) <= new Date(), true, 'time is greater than Date.now()')
 | 
			
		||||
  delete chunk.time
 | 
			
		||||
  is(chunk.pid, pid)
 | 
			
		||||
  is(chunk.hostname, hostname)
 | 
			
		||||
  is(chunk.level, level)
 | 
			
		||||
  is(chunk.msg, msg)
 | 
			
		||||
  is(chunk.v, v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sleep (ms) {
 | 
			
		||||
  return new Promise((resolve) => {
 | 
			
		||||
    setTimeout(resolve, ms)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = { getPathToNull, sink, check, once, sleep }
 | 
			
		||||
							
								
								
									
										247
									
								
								node_modules/pino/test/http.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								node_modules/pino/test/http.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,247 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const http = require('http')
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const semver = require('semver')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
 | 
			
		||||
test('http request support', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  var originalReq
 | 
			
		||||
  const instance = pino(sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    same(chunk, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my request',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      req: {
 | 
			
		||||
        method: originalReq.method,
 | 
			
		||||
        url: originalReq.url,
 | 
			
		||||
        headers: originalReq.headers,
 | 
			
		||||
        remoteAddress: originalReq.connection.remoteAddress,
 | 
			
		||||
        remotePort: originalReq.connection.remotePort
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer((req, res) => {
 | 
			
		||||
    originalReq = req
 | 
			
		||||
    instance.info(req, 'my request')
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
  })
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
  error(err)
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('http request support via serializer', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  var originalReq
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      req: pino.stdSerializers.req
 | 
			
		||||
    }
 | 
			
		||||
  }, sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    same(chunk, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my request',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      req: {
 | 
			
		||||
        method: originalReq.method,
 | 
			
		||||
        url: originalReq.url,
 | 
			
		||||
        headers: originalReq.headers,
 | 
			
		||||
        remoteAddress: originalReq.connection.remoteAddress,
 | 
			
		||||
        remotePort: originalReq.connection.remotePort
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer(function (req, res) {
 | 
			
		||||
    originalReq = req
 | 
			
		||||
    instance.info({ req: req }, 'my request')
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
  })
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
  error(err)
 | 
			
		||||
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('http request support via serializer without request connection', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  var originalReq
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      req: pino.stdSerializers.req
 | 
			
		||||
    }
 | 
			
		||||
  }, sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    const expected = {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my request',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      req: {
 | 
			
		||||
        method: originalReq.method,
 | 
			
		||||
        url: originalReq.url,
 | 
			
		||||
        headers: originalReq.headers
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (semver.gte(process.version, '13.0.0')) {
 | 
			
		||||
      expected.req.remoteAddress = originalReq.connection.remoteAddress
 | 
			
		||||
      expected.req.remotePort = originalReq.connection.remotePort
 | 
			
		||||
    }
 | 
			
		||||
    same(chunk, expected)
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer(function (req, res) {
 | 
			
		||||
    originalReq = req
 | 
			
		||||
    delete req.connection
 | 
			
		||||
    instance.info({ req: req }, 'my request')
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
  })
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
  error(err)
 | 
			
		||||
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('http response support', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  var originalRes
 | 
			
		||||
  const instance = pino(sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    same(chunk, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my response',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      res: {
 | 
			
		||||
        statusCode: originalRes.statusCode,
 | 
			
		||||
        headers: originalRes._headers
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer(function (req, res) {
 | 
			
		||||
    originalRes = res
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
    instance.info(res, 'my response')
 | 
			
		||||
  })
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
 | 
			
		||||
  error(err)
 | 
			
		||||
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('http response support via a serializer', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      res: pino.stdSerializers.res
 | 
			
		||||
    }
 | 
			
		||||
  }, sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    same(chunk, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my response',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      res: {
 | 
			
		||||
        statusCode: 200,
 | 
			
		||||
        headers: {
 | 
			
		||||
          'x-single': 'y',
 | 
			
		||||
          'x-multi': [1, 2]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer(function (req, res) {
 | 
			
		||||
    res.setHeader('x-single', 'y')
 | 
			
		||||
    res.setHeader('x-multi', [1, 2])
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
    instance.info({ res: res }, 'my response')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
  error(err)
 | 
			
		||||
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('http request support via serializer in a child', async ({ ok, same, error, teardown }) => {
 | 
			
		||||
  var originalReq
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      req: pino.stdSerializers.req
 | 
			
		||||
    }
 | 
			
		||||
  }, sink((chunk, enc) => {
 | 
			
		||||
    ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete chunk.time
 | 
			
		||||
    same(chunk, {
 | 
			
		||||
      pid: pid,
 | 
			
		||||
      hostname: hostname,
 | 
			
		||||
      level: 30,
 | 
			
		||||
      msg: 'my request',
 | 
			
		||||
      v: 1,
 | 
			
		||||
      req: {
 | 
			
		||||
        method: originalReq.method,
 | 
			
		||||
        url: originalReq.url,
 | 
			
		||||
        headers: originalReq.headers,
 | 
			
		||||
        remoteAddress: originalReq.connection.remoteAddress,
 | 
			
		||||
        remotePort: originalReq.connection.remotePort
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const server = http.createServer(function (req, res) {
 | 
			
		||||
    originalReq = req
 | 
			
		||||
    const child = instance.child({ req: req })
 | 
			
		||||
    child.info('my request')
 | 
			
		||||
    res.end('hello')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  server.unref()
 | 
			
		||||
  server.listen()
 | 
			
		||||
  const err = await once(server, 'listening')
 | 
			
		||||
  error(err)
 | 
			
		||||
 | 
			
		||||
  const res = await once(http.get('http://localhost:' + server.address().port), 'response')
 | 
			
		||||
  res.resume()
 | 
			
		||||
  server.close()
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										43
									
								
								node_modules/pino/test/is-level-enabled.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								node_modules/pino/test/is-level-enabled.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
test('can check if current level enabled', async ({ is }) => {
 | 
			
		||||
  const log = pino({ level: 'debug' })
 | 
			
		||||
  is(true, log.isLevelEnabled('debug'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can check if level enabled after level set', async ({ is }) => {
 | 
			
		||||
  const log = pino()
 | 
			
		||||
  is(false, log.isLevelEnabled('debug'))
 | 
			
		||||
  log.level = 'debug'
 | 
			
		||||
  is(true, log.isLevelEnabled('debug'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can check if higher level enabled', async ({ is }) => {
 | 
			
		||||
  const log = pino({ level: 'debug' })
 | 
			
		||||
  is(true, log.isLevelEnabled('error'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can check if lower level is disabled', async ({ is }) => {
 | 
			
		||||
  const log = pino({ level: 'error' })
 | 
			
		||||
  is(false, log.isLevelEnabled('trace'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can check if child has current level enabled', async ({ is }) => {
 | 
			
		||||
  const log = pino().child({ level: 'debug' })
 | 
			
		||||
  is(true, log.isLevelEnabled('debug'))
 | 
			
		||||
  is(true, log.isLevelEnabled('error'))
 | 
			
		||||
  is(false, log.isLevelEnabled('trace'))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can check if custom level is enabled', async ({ is }) => {
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    customLevels: { foo: 35 },
 | 
			
		||||
    level: 'debug'
 | 
			
		||||
  })
 | 
			
		||||
  is(true, log.isLevelEnabled('foo'))
 | 
			
		||||
  is(true, log.isLevelEnabled('error'))
 | 
			
		||||
  is(false, log.isLevelEnabled('trace'))
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										441
									
								
								node_modules/pino/test/levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								node_modules/pino/test/levels.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,441 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once, check } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
test('set the level by string', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 50,
 | 
			
		||||
    msg: 'this is an error'
 | 
			
		||||
  }, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal'
 | 
			
		||||
  }]
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  const current = expected.shift()
 | 
			
		||||
  check(is, result, current.level, current.msg)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('the wrong level throws', async ({ throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    instance.level = 'kaboom'
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the level by number', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 50,
 | 
			
		||||
    msg: 'this is an error'
 | 
			
		||||
  }, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal'
 | 
			
		||||
  }]
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
 | 
			
		||||
  instance.level = 50
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  const current = expected.shift()
 | 
			
		||||
  check(is, result, current.level, current.msg)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes level string mappings', async ({ is }) => {
 | 
			
		||||
  is(pino.levels.values.error, 50)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposes level number mappings', async ({ is }) => {
 | 
			
		||||
  is(pino.levels.labels[50], 'error')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns level integer', async ({ is }) => {
 | 
			
		||||
  const instance = pino({ level: 'error' })
 | 
			
		||||
  is(instance.levelVal, 50)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child returns level integer', async ({ is }) => {
 | 
			
		||||
  const parent = pino({ level: 'error' })
 | 
			
		||||
  const child = parent.child({ foo: 'bar' })
 | 
			
		||||
  is(child.levelVal, 50)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set the level via exported pino function', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 50,
 | 
			
		||||
    msg: 'this is an error'
 | 
			
		||||
  }, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal'
 | 
			
		||||
  }]
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ level: 'error' }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  const current = expected.shift()
 | 
			
		||||
  check(is, result, current.level, current.msg)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('level-change event', async ({ is }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  function handle (lvl, val, prevLvl, prevVal) {
 | 
			
		||||
    is(lvl, 'trace')
 | 
			
		||||
    is(val, 10)
 | 
			
		||||
    is(prevLvl, 'info')
 | 
			
		||||
    is(prevVal, 30)
 | 
			
		||||
  }
 | 
			
		||||
  instance.on('level-change', handle)
 | 
			
		||||
  instance.level = 'trace'
 | 
			
		||||
  instance.removeListener('level-change', handle)
 | 
			
		||||
  instance.level = 'info'
 | 
			
		||||
 | 
			
		||||
  var count = 0
 | 
			
		||||
 | 
			
		||||
  const l1 = () => count++
 | 
			
		||||
  const l2 = () => count++
 | 
			
		||||
  const l3 = () => count++
 | 
			
		||||
  instance.on('level-change', l1)
 | 
			
		||||
  instance.on('level-change', l2)
 | 
			
		||||
  instance.on('level-change', l3)
 | 
			
		||||
 | 
			
		||||
  instance.level = 'trace'
 | 
			
		||||
  instance.removeListener('level-change', l3)
 | 
			
		||||
  instance.level = 'fatal'
 | 
			
		||||
  instance.removeListener('level-change', l1)
 | 
			
		||||
  instance.level = 'debug'
 | 
			
		||||
  instance.removeListener('level-change', l2)
 | 
			
		||||
  instance.level = 'info'
 | 
			
		||||
 | 
			
		||||
  is(count, 6)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('enable', async ({ fail }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'trace',
 | 
			
		||||
    enabled: false
 | 
			
		||||
  }, sink((result, enc) => {
 | 
			
		||||
    fail('no data should be logged')
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  Object.keys(pino.levels.values).forEach((level) => {
 | 
			
		||||
    instance[level]('hello world')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('silent level', async ({ fail }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: 'silent'
 | 
			
		||||
  }, sink((result, enc) => {
 | 
			
		||||
    fail('no data should be logged')
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  Object.keys(pino.levels.values).forEach((level) => {
 | 
			
		||||
    instance[level]('hello world')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('set silent via Infinity', async ({ fail }) => {
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    level: Infinity
 | 
			
		||||
  }, sink((result, enc) => {
 | 
			
		||||
    fail('no data should be logged')
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  Object.keys(pino.levels.values).forEach((level) => {
 | 
			
		||||
    instance[level]('hello world')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposed levels', async ({ same }) => {
 | 
			
		||||
  same(Object.keys(pino.levels.values), [
 | 
			
		||||
    'trace',
 | 
			
		||||
    'debug',
 | 
			
		||||
    'info',
 | 
			
		||||
    'warn',
 | 
			
		||||
    'error',
 | 
			
		||||
    'fatal'
 | 
			
		||||
  ])
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('exposed labels', async ({ same }) => {
 | 
			
		||||
  same(Object.keys(pino.levels.labels), [
 | 
			
		||||
    '10',
 | 
			
		||||
    '20',
 | 
			
		||||
    '30',
 | 
			
		||||
    '40',
 | 
			
		||||
    '50',
 | 
			
		||||
    '60'
 | 
			
		||||
  ])
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting level in child', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 50,
 | 
			
		||||
    msg: 'this is an error'
 | 
			
		||||
  }, {
 | 
			
		||||
    level: 60,
 | 
			
		||||
    msg: 'this is fatal'
 | 
			
		||||
  }]
 | 
			
		||||
  const instance = pino(sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    check(is, result, current.level, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  })).child({ level: 30 })
 | 
			
		||||
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.error('this is an error')
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting level by assigning a number to level', async ({ is }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  is(instance.levelVal, 30)
 | 
			
		||||
  is(instance.level, 'info')
 | 
			
		||||
  instance.level = 50
 | 
			
		||||
  is(instance.levelVal, 50)
 | 
			
		||||
  is(instance.level, 'error')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting level by number to unknown value results in a throw', async ({ throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => { instance.level = 973 })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting level by assigning a known label to level', async ({ is }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  is(instance.levelVal, 30)
 | 
			
		||||
  is(instance.level, 'info')
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  is(instance.levelVal, 50)
 | 
			
		||||
  is(instance.level, 'error')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('levelVal is read only', async ({ throws }) => {
 | 
			
		||||
  const instance = pino()
 | 
			
		||||
  throws(() => { instance.levelVal = 20 })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('produces labels when told to', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 'info',
 | 
			
		||||
    msg: 'hello world'
 | 
			
		||||
  }]
 | 
			
		||||
  const instance = pino({ useLevelLabels: true }, sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    check(is, result, current.level, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('resets levels from labels to numbers', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    level: 30,
 | 
			
		||||
    msg: 'hello world'
 | 
			
		||||
  }]
 | 
			
		||||
  pino({ useLevelLabels: true })
 | 
			
		||||
  const instance = pino({ useLevelLabels: false }, sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    check(is, result, current.level, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('aliases changeLevelName to levelKey', async ({ is }) => {
 | 
			
		||||
  const instance = pino({ changeLevelName: 'priority' }, sink((result, enc, cb) => {
 | 
			
		||||
    is(result.priority, 30)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('changes label naming when told to', async ({ is }) => {
 | 
			
		||||
  const expected = [{
 | 
			
		||||
    priority: 30,
 | 
			
		||||
    msg: 'hello world'
 | 
			
		||||
  }]
 | 
			
		||||
  const instance = pino({ levelKey: 'priority' }, sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    is(result.priority, current.priority)
 | 
			
		||||
    is(result.msg, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children produce labels when told to', async ({ is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 'info',
 | 
			
		||||
      msg: 'child 1'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 'info',
 | 
			
		||||
      msg: 'child 2'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const instance = pino({ useLevelLabels: true }, sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    check(is, result, current.level, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const child1 = instance.child({ name: 'child1' })
 | 
			
		||||
  const child2 = child1.child({ name: 'child2' })
 | 
			
		||||
 | 
			
		||||
  child1.info('child 1')
 | 
			
		||||
  child2.info('child 2')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('produces labels for custom levels', async ({ is }) => {
 | 
			
		||||
  const expected = [
 | 
			
		||||
    {
 | 
			
		||||
      level: 'info',
 | 
			
		||||
      msg: 'hello world'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      level: 'foo',
 | 
			
		||||
      msg: 'foobar'
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
  const opts = {
 | 
			
		||||
    useLevelLabels: true,
 | 
			
		||||
    customLevels: {
 | 
			
		||||
      foo: 35
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  const instance = pino(opts, sink((result, enc, cb) => {
 | 
			
		||||
    const current = expected.shift()
 | 
			
		||||
    check(is, result, current.level, current.msg)
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
  instance.foo('foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('setting levelKey does not affect labels when told to', async ({ is }) => {
 | 
			
		||||
  const instance = pino(
 | 
			
		||||
    {
 | 
			
		||||
      useLevelLabels: true,
 | 
			
		||||
      levelKey: 'priority'
 | 
			
		||||
    },
 | 
			
		||||
    sink((result, enc, cb) => {
 | 
			
		||||
      is(result.priority, 'info')
 | 
			
		||||
      cb()
 | 
			
		||||
    })
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  instance.info('hello world')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when creating a default label that does not exist in logger levels', async ({ is, throws }) => {
 | 
			
		||||
  const defaultLevel = 'foo'
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        bar: 5
 | 
			
		||||
      },
 | 
			
		||||
      level: defaultLevel
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      level: defaultLevel
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, `default level:${defaultLevel} must be included in custom levels`)
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when creating a default value that does not exist in logger levels', async ({ is, throws }) => {
 | 
			
		||||
  const defaultLevel = 15
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        bar: 5
 | 
			
		||||
      },
 | 
			
		||||
      level: defaultLevel
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      level: defaultLevel
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, `default level:${defaultLevel} must be included in custom levels`)
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when creating a default value that does not exist in logger levels', async ({ is, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 5
 | 
			
		||||
      },
 | 
			
		||||
      useOnlyCustomLevels: true
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
  try {
 | 
			
		||||
    pino({
 | 
			
		||||
      customLevels: {
 | 
			
		||||
        foo: 5
 | 
			
		||||
      },
 | 
			
		||||
      useOnlyCustomLevels: true
 | 
			
		||||
    })
 | 
			
		||||
  } catch ({ message }) {
 | 
			
		||||
    is(message, 'default level:info must be included in custom levels')
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('passes when creating a default value that exists in logger levels', async ({ is, throws }) => {
 | 
			
		||||
  pino({
 | 
			
		||||
    level: 30
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('fatal method sync-flushes the destination if sync flushing is available', async ({ pass, doesNotThrow, plan }) => {
 | 
			
		||||
  plan(2)
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  stream.flushSync = () => {
 | 
			
		||||
    pass('destination flushed')
 | 
			
		||||
  }
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.fatal('this is fatal')
 | 
			
		||||
  await once(stream, 'data')
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    stream.flushSync = undefined
 | 
			
		||||
    instance.fatal('this is fatal')
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('fatal method should call async when sync-flushing fails', ({ equal, fail, doesNotThrow, plan }) => {
 | 
			
		||||
  plan(2)
 | 
			
		||||
  const messages = [
 | 
			
		||||
    'this is fatal 1'
 | 
			
		||||
  ]
 | 
			
		||||
  const stream = sink((result) => equal(result.msg, messages.shift()))
 | 
			
		||||
  stream.flushSync = () => { throw new Error('Error') }
 | 
			
		||||
  stream.flush = () => fail('flush should be called')
 | 
			
		||||
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  doesNotThrow(() => instance.fatal(messages[0]))
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										110
									
								
								node_modules/pino/test/metadata.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								node_modules/pino/test/metadata.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
 | 
			
		||||
test('metadata works', async ({ ok, same, is }) => {
 | 
			
		||||
  const now = Date.now()
 | 
			
		||||
  const instance = pino({}, {
 | 
			
		||||
    [Symbol.for('pino.metadata')]: true,
 | 
			
		||||
    write (chunk) {
 | 
			
		||||
      is(instance, this.lastLogger)
 | 
			
		||||
      is(30, this.lastLevel)
 | 
			
		||||
      is('a msg', this.lastMsg)
 | 
			
		||||
      ok(Number(this.lastTime) >= now)
 | 
			
		||||
      same(this.lastObj, { hello: 'world', msg: 'a msg' })
 | 
			
		||||
      const result = JSON.parse(chunk)
 | 
			
		||||
      ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
      delete result.time
 | 
			
		||||
      same(result, {
 | 
			
		||||
        pid: pid,
 | 
			
		||||
        hostname: hostname,
 | 
			
		||||
        level: 30,
 | 
			
		||||
        hello: 'world',
 | 
			
		||||
        msg: 'a msg',
 | 
			
		||||
        v: 1
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.info({ hello: 'world' }, 'a msg')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child loggers works', async ({ ok, same, is }) => {
 | 
			
		||||
  const instance = pino({}, {
 | 
			
		||||
    [Symbol.for('pino.metadata')]: true,
 | 
			
		||||
    write (chunk) {
 | 
			
		||||
      is(child, this.lastLogger)
 | 
			
		||||
      is(30, this.lastLevel)
 | 
			
		||||
      is('a msg', this.lastMsg)
 | 
			
		||||
      same(this.lastObj, { from: 'child', msg: 'a msg' })
 | 
			
		||||
      const result = JSON.parse(chunk)
 | 
			
		||||
      ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
      delete result.time
 | 
			
		||||
      same(result, {
 | 
			
		||||
        pid: pid,
 | 
			
		||||
        hostname: hostname,
 | 
			
		||||
        level: 30,
 | 
			
		||||
        hello: 'world',
 | 
			
		||||
        from: 'child',
 | 
			
		||||
        msg: 'a msg',
 | 
			
		||||
        v: 1
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const child = instance.child({ hello: 'world' })
 | 
			
		||||
  child.info({ from: 'child' }, 'a msg')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('without object', async ({ ok, same, is }) => {
 | 
			
		||||
  const instance = pino({}, {
 | 
			
		||||
    [Symbol.for('pino.metadata')]: true,
 | 
			
		||||
    write (chunk) {
 | 
			
		||||
      is(instance, this.lastLogger)
 | 
			
		||||
      is(30, this.lastLevel)
 | 
			
		||||
      is('a msg', this.lastMsg)
 | 
			
		||||
      same({ msg: 'a msg' }, this.lastObj)
 | 
			
		||||
      const result = JSON.parse(chunk)
 | 
			
		||||
      ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
      delete result.time
 | 
			
		||||
      same(result, {
 | 
			
		||||
        pid: pid,
 | 
			
		||||
        hostname: hostname,
 | 
			
		||||
        level: 30,
 | 
			
		||||
        msg: 'a msg',
 | 
			
		||||
        v: 1
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.info('a msg')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('without msg', async ({ ok, same, is }) => {
 | 
			
		||||
  const instance = pino({}, {
 | 
			
		||||
    [Symbol.for('pino.metadata')]: true,
 | 
			
		||||
    write (chunk) {
 | 
			
		||||
      is(instance, this.lastLogger)
 | 
			
		||||
      is(30, this.lastLevel)
 | 
			
		||||
      is(undefined, this.lastMsg)
 | 
			
		||||
      same({ hello: 'world' }, this.lastObj)
 | 
			
		||||
      const result = JSON.parse(chunk)
 | 
			
		||||
      ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
      delete result.time
 | 
			
		||||
      same(result, {
 | 
			
		||||
        pid: pid,
 | 
			
		||||
        hostname: hostname,
 | 
			
		||||
        level: 30,
 | 
			
		||||
        hello: 'world',
 | 
			
		||||
        v: 1
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  instance.info({ hello: 'world' })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										106
									
								
								node_modules/pino/test/mixin.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								node_modules/pino/test/mixin.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const os = require('os')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const { pid } = process
 | 
			
		||||
const hostname = os.hostname()
 | 
			
		||||
const level = 50
 | 
			
		||||
const name = 'error'
 | 
			
		||||
 | 
			
		||||
test('mixin object is included', async ({ ok, same }) => {
 | 
			
		||||
  let n = 0
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    mixin () {
 | 
			
		||||
      return { hello: ++n }
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name]('test')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid,
 | 
			
		||||
    hostname,
 | 
			
		||||
    level,
 | 
			
		||||
    msg: 'test',
 | 
			
		||||
    hello: 1,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('mixin object is new every time', async ({ plan, ok, same }) => {
 | 
			
		||||
  plan(6)
 | 
			
		||||
 | 
			
		||||
  let n = 0
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    mixin () {
 | 
			
		||||
      return { hello: n }
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
 | 
			
		||||
  while (++n < 4) {
 | 
			
		||||
    const msg = `test #${n}`
 | 
			
		||||
    stream.pause()
 | 
			
		||||
    instance[name](msg)
 | 
			
		||||
    stream.resume()
 | 
			
		||||
    const result = await once(stream, 'data')
 | 
			
		||||
    ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
    delete result.time
 | 
			
		||||
    same(result, {
 | 
			
		||||
      pid,
 | 
			
		||||
      hostname,
 | 
			
		||||
      level,
 | 
			
		||||
      msg,
 | 
			
		||||
      hello: n,
 | 
			
		||||
      v: 1
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('mixin object is not called if below log level', async ({ ok }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    mixin () {
 | 
			
		||||
      ok(false, 'should not call mixin function')
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.level = 'error'
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('mixin object + logged object', async ({ ok, same }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    mixin () {
 | 
			
		||||
      return { foo: 1, bar: 2 }
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.level = name
 | 
			
		||||
  instance[name]({ bar: 3, baz: 4 })
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
 | 
			
		||||
  delete result.time
 | 
			
		||||
  same(result, {
 | 
			
		||||
    pid,
 | 
			
		||||
    hostname,
 | 
			
		||||
    level,
 | 
			
		||||
    foo: 1,
 | 
			
		||||
    bar: 3,
 | 
			
		||||
    baz: 4,
 | 
			
		||||
    v: 1
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('mixin not a function', async ({ throws }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  throws(function () {
 | 
			
		||||
    pino({ mixin: 'not a function' }, stream)
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										312
									
								
								node_modules/pino/test/pretty.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								node_modules/pino/test/pretty.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,312 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { Writable } = require('stream')
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const execa = require('execa')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
const { once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
const tap = require('tap')
 | 
			
		||||
 | 
			
		||||
const isWin = process.platform === 'win32'
 | 
			
		||||
if (isWin) {
 | 
			
		||||
  tap.comment('Skipping pretty printing tests on Windows as colour codes are different and tests fail')
 | 
			
		||||
  process.exit(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('can be enabled via exported pino function', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'basic.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can be enabled via exported pino function with pretty configuration', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'level-first.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/^INFO.*h/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can be enabled via exported pino function with prettifier', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'pretty-factory.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/^INFO.*h/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('does not throw error when enabled with stream specified', async ({ doesNotThrow }) => {
 | 
			
		||||
  doesNotThrow(() => pino({ prettyPrint: true }, process.stdout))
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when prettyPrint is true but pino-pretty module is not installed', async ({ throws, is }) => {
 | 
			
		||||
  // pino pretty *is* installed, and probably also cached, so rather than
 | 
			
		||||
  // messing with the filesystem the simplest way to generate a not found
 | 
			
		||||
  // error is to simulate it:
 | 
			
		||||
  const prettyFactory = require('pino-pretty')
 | 
			
		||||
  require.cache[require.resolve('pino-pretty')].exports = () => {
 | 
			
		||||
    throw Error('Cannot find module \'pino-pretty\'')
 | 
			
		||||
  }
 | 
			
		||||
  throws(() => pino({ prettyPrint: true }))
 | 
			
		||||
  try { pino({ prettyPrint: true }) } catch ({ message }) {
 | 
			
		||||
    is(message, 'Missing `pino-pretty` module: `pino-pretty` must be installed separately')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  require.cache[require.resolve('pino-pretty')].exports = prettyFactory
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('can send pretty print to custom stream', async ({ is }) => {
 | 
			
		||||
  const dest = new Writable({
 | 
			
		||||
    objectMode: true,
 | 
			
		||||
    write (formatted, enc) {
 | 
			
		||||
      is(/^INFO.*foo\n$/.test(formatted), true)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    prettifier: require('pino-pretty'),
 | 
			
		||||
    prettyPrint: {
 | 
			
		||||
      levelFirst: true,
 | 
			
		||||
      colorize: false
 | 
			
		||||
    }
 | 
			
		||||
  }, dest)
 | 
			
		||||
  log.info('foo')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ignores `undefined` from prettifier', async ({ is }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'skipped-output.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  is(actual, '')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parses and outputs chindings', async ({ is, isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'child.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h2/), null)
 | 
			
		||||
  isNot(actual.match(/a: 1/), null)
 | 
			
		||||
  isNot(actual.match(/b: 2/), null)
 | 
			
		||||
  is(actual.match(/a: 1/g).length, 3)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('applies serializers', async ({ is, isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'serializers.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
 | 
			
		||||
  isNot(actual.match(/foo: "bar"/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('applies redaction rules', async ({ is, isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'redact.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
 | 
			
		||||
  isNot(actual.match(/\[Redacted\]/), null)
 | 
			
		||||
  is(actual.match(/object/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('dateformat', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'dateformat.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): h/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('without timestamp', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'no-time.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.slice(2), '[]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('with custom timestamp', async ({ is }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  is(actual.slice(0, 8), '["test"]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('with custom timestamp label', async ({ is }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time-label.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  is(actual.slice(0, 8), '["test"]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('errors', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null)
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): with a message/), null)
 | 
			
		||||
  isNot(actual.match(/.*error\.js.*/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('errors with props', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error-props.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null)
 | 
			
		||||
  isNot(actual.match(/code: ENOENT/), null)
 | 
			
		||||
  isNot(actual.match(/errno: 1/), null)
 | 
			
		||||
  isNot(actual.match(/.*error-props\.js.*/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('final works with pretty', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null)
 | 
			
		||||
  isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): beforeExit/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('final works when returning a logger', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-return.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null)
 | 
			
		||||
  isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): after/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('final works without prior logging', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-no-log-before.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/WARN\s+: pino.final with prettyPrint does not support flushing/), null)
 | 
			
		||||
  isNot(actual.match(/INFO\s+\(123456 on abcdefghijklmnopqr\): beforeExit/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('works as expected with an object with the msg prop', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'obj-msg-prop.js')])
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/\(123456 on abcdefghijklmnopqr\): hello/), null)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('should not lose stream metadata for streams with `needsMetadataGsym` flag', async ({ isNot }) => {
 | 
			
		||||
  const dest = new Writable({
 | 
			
		||||
    objectMode: true,
 | 
			
		||||
    write () {
 | 
			
		||||
      isNot(typeof this.lastLevel === 'undefined', true)
 | 
			
		||||
      isNot(typeof this.lastMsg === 'undefined', true)
 | 
			
		||||
      isNot(typeof this.lastObj === 'undefined', true)
 | 
			
		||||
      isNot(typeof this.lastTime === 'undefined', true)
 | 
			
		||||
      isNot(typeof this.lastLogger === 'undefined', true)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  dest[pino.symbols.needsMetadataGsym] = true
 | 
			
		||||
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    prettyPrint: true
 | 
			
		||||
  }, dest)
 | 
			
		||||
  log.info('foo')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('should not add stream metadata for streams without `needsMetadataGsym` flag', async ({ is }) => {
 | 
			
		||||
  const dest = new Writable({
 | 
			
		||||
    objectMode: true,
 | 
			
		||||
    write () {
 | 
			
		||||
      is(typeof this.lastLevel === 'undefined', true)
 | 
			
		||||
      is(typeof this.lastMsg === 'undefined', true)
 | 
			
		||||
      is(typeof this.lastObj === 'undefined', true)
 | 
			
		||||
      is(typeof this.lastTime === 'undefined', true)
 | 
			
		||||
      is(typeof this.lastLogger === 'undefined', true)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const log = pino({
 | 
			
		||||
    prettyPrint: true
 | 
			
		||||
  }, dest)
 | 
			
		||||
  log.info('foo')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										713
									
								
								node_modules/pino/test/redact.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										713
									
								
								node_modules/pino/test/redact.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,713 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
test('redact option – throws if not array', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: 'req.headers.cookie' })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – throws if array does not only contain strings', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: ['req.headers.cookie', {}] })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – throws if array contains an invalid path', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: ['req,headers.cookie'] })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – throws if not array', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: { paths: 'req.headers.cookie' } })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – throws if array does not only contain strings', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: { paths: ['req.headers.cookie', {}] } })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – throws if array contains an invalid path', async ({ throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    pino({ redact: { paths: ['req,headers.cookie'] } })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – top level key', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['key'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: { redact: 'me' }
 | 
			
		||||
  })
 | 
			
		||||
  const { key } = await once(stream, 'data')
 | 
			
		||||
  is(key, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – top level key next level key', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['key', 'key.foo'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: { redact: 'me' }
 | 
			
		||||
  })
 | 
			
		||||
  const { key } = await once(stream, 'data')
 | 
			
		||||
  is(key, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – next level key then top level key', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['key.foo', 'key'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: { redact: 'me' }
 | 
			
		||||
  })
 | 
			
		||||
  const { key } = await once(stream, 'data')
 | 
			
		||||
  is(key, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.headers.cookie'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – child object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.headers.cookie'] }, stream)
 | 
			
		||||
  instance.child({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }).info('message completed')
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact option – interpolated object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.headers.cookie'] }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.info('test', {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { msg } = await once(stream, 'data')
 | 
			
		||||
  is(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – child object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
 | 
			
		||||
  instance.child({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }).info('message completed')
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths option – interpolated object', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
 | 
			
		||||
 | 
			
		||||
  instance.info('test', {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { msg } = await once(stream, 'data')
 | 
			
		||||
  is(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.censor option – sets the redact value', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, 'test')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove option – removes both key and value', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is('cookie' in req.headers, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove – top level key - object value', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: { redact: 'me' }
 | 
			
		||||
  })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is('key' in o, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove – top level key - number value', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: 1
 | 
			
		||||
  })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is('key' in o, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove – top level key - boolean value', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    key: false
 | 
			
		||||
  })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is('key' in o, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove – top level key in child logger', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const opts = { redact: { paths: ['key'], remove: true } }
 | 
			
		||||
  const instance = pino(opts, stream).child({ key: { redact: 'me' } })
 | 
			
		||||
  instance.info('test')
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is('key' in o, false)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths preserves original object values after the log write', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.headers.cookie'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.req.headers.cookie, '[Redacted]')
 | 
			
		||||
  is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.paths preserves original object values after the log write', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.req.headers.cookie, '[Redacted]')
 | 
			
		||||
  is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.censor preserves original object values after the log write', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.req.headers.cookie, 'test')
 | 
			
		||||
  is(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.remove preserves original object values after the log write', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is('cookie' in o.req.headers, false)
 | 
			
		||||
  is('cookie' in obj.req.headers, true)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports last position wildcard paths', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.headers.*'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
  is(req.headers.host, '[Redacted]')
 | 
			
		||||
  is(req.headers.connection, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports first position wildcard paths', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['*.headers'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports first position wildcards before other paths', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['*.headers.cookie', 'req.id'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
  is(req.id, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports first position wildcards after other paths', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.id', '*.headers.cookie'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
  is(req.id, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports first position wildcards after top level keys', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['key', '*.headers.cookie'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports top level wildcard', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['*'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports top level wildcard with a censor function', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({
 | 
			
		||||
    redact: {
 | 
			
		||||
      paths: ['*'],
 | 
			
		||||
      censor: () => '[Redacted]'
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports top level wildcard and leading wildcard', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['*', '*.req'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact – supports intermediate wildcard paths', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['req.*.cookie'] }, stream)
 | 
			
		||||
  instance.info({
 | 
			
		||||
    req: {
 | 
			
		||||
      id: 7915,
 | 
			
		||||
      method: 'GET',
 | 
			
		||||
      url: '/',
 | 
			
		||||
      headers: {
 | 
			
		||||
        host: 'localhost:3000',
 | 
			
		||||
        connection: 'keep-alive',
 | 
			
		||||
        cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
 | 
			
		||||
      },
 | 
			
		||||
      remoteAddress: '::ffff:127.0.0.1',
 | 
			
		||||
      remotePort: 58022
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  const { req } = await once(stream, 'data')
 | 
			
		||||
  is(req.headers.cookie, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts numbers at the top level', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['id'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    id: 7915
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.id, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts booleans at the top level', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['maybe'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    maybe: true
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.maybe, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts strings at the top level', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['s'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    s: 's'
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.s, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('does not redact primitives if not objects', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['a.b'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    a: 42
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.a, 42)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts null at the top level', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['n'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    n: null
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.n, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports bracket notation', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['a["b.b"]'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    a: { 'b.b': 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.a['b.b'], '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports bracket notation with further nesting', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['a["b.b"].c'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    a: { 'b.b': { c: 'd' } }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.a['b.b'].c, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports bracket notation with empty string as path segment', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['a[""].c'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    a: { '': { c: 'd' } }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.a[''].c, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation (single quote)', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['[\'a.a\'].b'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    'a.a': { b: 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o['a.a'].b, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation (double quote)', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['["a.a"].b'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    'a.a': { b: 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o['a.a'].b, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation (backtick quote)', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['[`a.a`].b'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    'a.a': { b: 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o['a.a'].b, '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation (single-segment path)', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['[`a.a`]'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    'a.a': { b: 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o['a.a'], '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation (single-segment path, wilcard)', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ redact: ['[*]'] }, stream)
 | 
			
		||||
  const obj = {
 | 
			
		||||
    'a.a': { b: 'c' }
 | 
			
		||||
  }
 | 
			
		||||
  instance.info(obj)
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o['a.a'], '[Redacted]')
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										245
									
								
								node_modules/pino/test/serializers.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								node_modules/pino/test/serializers.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,245 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
const parentSerializers = {
 | 
			
		||||
  test: () => 'parent'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const childSerializers = {
 | 
			
		||||
  test: () => 'child'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test('default err namespace error serializer', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino(stream)
 | 
			
		||||
 | 
			
		||||
  parent.info({ err: ReferenceError('test') })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(typeof o.err, 'object')
 | 
			
		||||
  is(o.err.type, 'ReferenceError')
 | 
			
		||||
  is(o.err.message, 'test')
 | 
			
		||||
  is(typeof o.err.stack, 'string')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('custom serializer overrides default err namespace error serializer', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      err: (e) => ({
 | 
			
		||||
        t: e.constructor.name,
 | 
			
		||||
        m: e.message,
 | 
			
		||||
        s: e.stack
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  parent.info({ err: ReferenceError('test') })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(typeof o.err, 'object')
 | 
			
		||||
  is(o.err.t, 'ReferenceError')
 | 
			
		||||
  is(o.err.m, 'test')
 | 
			
		||||
  is(typeof o.err.s, 'string')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('null overrides default err namespace error serializer', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: { err: null } }, stream)
 | 
			
		||||
 | 
			
		||||
  parent.info({ err: ReferenceError('test') })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(typeof o.err, 'object')
 | 
			
		||||
  is(typeof o.err.type, 'undefined')
 | 
			
		||||
  is(typeof o.err.message, 'undefined')
 | 
			
		||||
  is(typeof o.err.stack, 'undefined')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('undefined overrides default err namespace error serializer', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: { err: undefined } }, stream)
 | 
			
		||||
 | 
			
		||||
  parent.info({ err: ReferenceError('test') })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(typeof o.err, 'object')
 | 
			
		||||
  is(typeof o.err.type, 'undefined')
 | 
			
		||||
  is(typeof o.err.message, 'undefined')
 | 
			
		||||
  is(typeof o.err.stack, 'undefined')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('serializers override values', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: parentSerializers }, stream)
 | 
			
		||||
  parent.child({ serializers: childSerializers })
 | 
			
		||||
 | 
			
		||||
  parent.fatal({ test: 'test' })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.test, 'parent')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child does not overwrite parent serializers', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: parentSerializers }, stream)
 | 
			
		||||
  const child = parent.child({ serializers: childSerializers })
 | 
			
		||||
 | 
			
		||||
  parent.fatal({ test: 'test' })
 | 
			
		||||
 | 
			
		||||
  const o = once(stream, 'data')
 | 
			
		||||
  is((await o).test, 'parent')
 | 
			
		||||
  const o2 = once(stream, 'data')
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
  is((await o2).test, 'child')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('Symbol.for(\'pino.serializers\')', async ({ is, isNot }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: parentSerializers }, stream)
 | 
			
		||||
  const child = parent.child({ a: 'property' })
 | 
			
		||||
 | 
			
		||||
  is(parent[Symbol.for('pino.serializers')], parentSerializers)
 | 
			
		||||
  is(child[Symbol.for('pino.serializers')], parentSerializers)
 | 
			
		||||
 | 
			
		||||
  const child2 = parent.child({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      a
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  function a () {
 | 
			
		||||
    return 'hello'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isNot(child2[Symbol.for('pino.serializers')], parentSerializers)
 | 
			
		||||
  is(child2[Symbol.for('pino.serializers')].a, a)
 | 
			
		||||
  is(child2[Symbol.for('pino.serializers')].test, parentSerializers.test)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children inherit parent serializers', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({ serializers: parentSerializers }, stream)
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ a: 'property' })
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.test, 'parent')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children inherit parent Symbol serializers', async ({ is, isNot }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const symbolSerializers = {
 | 
			
		||||
    [Symbol.for('pino.*')]: parentSerializers.test
 | 
			
		||||
  }
 | 
			
		||||
  const parent = pino({ serializers: symbolSerializers }, stream)
 | 
			
		||||
 | 
			
		||||
  is(parent[Symbol.for('pino.serializers')], symbolSerializers)
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({
 | 
			
		||||
    serializers: {
 | 
			
		||||
      [Symbol.for('a')]: a,
 | 
			
		||||
      a
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  function a () {
 | 
			
		||||
    return 'hello'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isNot(child[Symbol.for('pino.serializers')], symbolSerializers)
 | 
			
		||||
  is(child[Symbol.for('pino.serializers')].a, a)
 | 
			
		||||
  is(child[Symbol.for('pino.serializers')][Symbol.for('a')], a)
 | 
			
		||||
  is(child[Symbol.for('pino.serializers')][Symbol.for('pino.*')], parentSerializers.test)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children serializers get called', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    test: 'this'
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ a: 'property', serializers: childSerializers })
 | 
			
		||||
 | 
			
		||||
  child.fatal({ test: 'test' })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.test, 'child')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('children serializers get called when inherited from parent', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const parent = pino({
 | 
			
		||||
    test: 'this',
 | 
			
		||||
    serializers: parentSerializers
 | 
			
		||||
  }, stream)
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ serializers: { test: function () { return 'pass' } } })
 | 
			
		||||
 | 
			
		||||
  child.fatal({ test: 'fail' })
 | 
			
		||||
  const o = await once(stream, 'data')
 | 
			
		||||
  is(o.test, 'pass')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('non-overridden serializers are available in the children', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const pSerializers = {
 | 
			
		||||
    onlyParent: function () { return 'parent' },
 | 
			
		||||
    shared: function () { return 'parent' }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const cSerializers = {
 | 
			
		||||
    shared: function () { return 'child' },
 | 
			
		||||
    onlyChild: function () { return 'child' }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const parent = pino({ serializers: pSerializers }, stream)
 | 
			
		||||
 | 
			
		||||
  const child = parent.child({ serializers: cSerializers })
 | 
			
		||||
 | 
			
		||||
  const o = once(stream, 'data')
 | 
			
		||||
  child.fatal({ shared: 'test' })
 | 
			
		||||
  is((await o).shared, 'child')
 | 
			
		||||
  const o2 = once(stream, 'data')
 | 
			
		||||
  child.fatal({ onlyParent: 'test' })
 | 
			
		||||
  is((await o2).onlyParent, 'parent')
 | 
			
		||||
  const o3 = once(stream, 'data')
 | 
			
		||||
  child.fatal({ onlyChild: 'test' })
 | 
			
		||||
  is((await o3).onlyChild, 'child')
 | 
			
		||||
  const o4 = once(stream, 'data')
 | 
			
		||||
  parent.fatal({ onlyChild: 'test' })
 | 
			
		||||
  is((await o4).onlyChild, 'test')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('Symbol.for(\'pino.*\') serializer', async ({ notSame, is, isNot }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const globalSerializer = {
 | 
			
		||||
    [Symbol.for('pino.*')]: function (obj) {
 | 
			
		||||
      if (obj.lionel === 'richie') {
 | 
			
		||||
        return { hello: 'is', it: 'me', you: 'are', looking: 'for' }
 | 
			
		||||
      }
 | 
			
		||||
      return { lionel: 'richie' }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const logger = pino({ serializers: globalSerializer }, stream)
 | 
			
		||||
 | 
			
		||||
  const o = once(stream, 'data')
 | 
			
		||||
  logger.info({ hello: 'is', it: 'me', you: 'are', looking: 'for' })
 | 
			
		||||
  is((await o).lionel, 'richie')
 | 
			
		||||
  isNot((await o).hello, 'is')
 | 
			
		||||
  isNot((await o).it, 'me')
 | 
			
		||||
  isNot((await o).you, 'are')
 | 
			
		||||
  isNot((await o).looking, 'for')
 | 
			
		||||
 | 
			
		||||
  const o2 = once(stream, 'data')
 | 
			
		||||
  logger.info({ lionel: 'richie' })
 | 
			
		||||
  is((await o2).lionel, 'richie')
 | 
			
		||||
  is((await o2).hello, 'is')
 | 
			
		||||
  is((await o2).it, 'me')
 | 
			
		||||
  is((await o2).you, 'are')
 | 
			
		||||
  is((await o2).looking, 'for')
 | 
			
		||||
 | 
			
		||||
  const o3 = once(stream, 'data')
 | 
			
		||||
  logger.info('message')
 | 
			
		||||
  is((await o3).lionel, 'richie')
 | 
			
		||||
  is('pid' in (await o3), false)
 | 
			
		||||
  is('hostname' in (await o3), false)
 | 
			
		||||
  notSame(await o3, ['pid', 'hostname'])
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										19
									
								
								node_modules/pino/test/stdout-protection.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								node_modules/pino/test/stdout-protection.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { join } = require('path')
 | 
			
		||||
const { fork } = require('child_process')
 | 
			
		||||
const { once } = require('./helper')
 | 
			
		||||
const writer = require('flush-write-stream')
 | 
			
		||||
 | 
			
		||||
test('do not use SonicBoom is someone tampered with process.stdout.write', async ({ isNot }) => {
 | 
			
		||||
  var actual = ''
 | 
			
		||||
  const child = fork(join(__dirname, 'fixtures', 'stdout-hack-protection.js'), { silent: true })
 | 
			
		||||
 | 
			
		||||
  child.stdout.pipe(writer((s, enc, cb) => {
 | 
			
		||||
    actual += s
 | 
			
		||||
    cb()
 | 
			
		||||
  }))
 | 
			
		||||
  await once(child, 'close')
 | 
			
		||||
  isNot(actual.match(/^hack/), null)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										121
									
								
								node_modules/pino/test/timestamp.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								node_modules/pino/test/timestamp.test.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
/* eslint no-prototype-builtins: 0 */
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const { sink, once } = require('./helper')
 | 
			
		||||
const pino = require('../')
 | 
			
		||||
 | 
			
		||||
test('pino exposes standard time functions', async ({ ok }) => {
 | 
			
		||||
  ok(pino.stdTimeFunctions)
 | 
			
		||||
  ok(pino.stdTimeFunctions.epochTime)
 | 
			
		||||
  ok(pino.stdTimeFunctions.unixTime)
 | 
			
		||||
  ok(pino.stdTimeFunctions.nullTime)
 | 
			
		||||
  ok(pino.stdTimeFunctions.isoTime)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino accepts external time functions', async ({ is }) => {
 | 
			
		||||
  const opts = {
 | 
			
		||||
    timestamp: () => ',"time":"none"'
 | 
			
		||||
  }
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(opts, stream)
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  is(result.time, 'none')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino accepts external time functions with custom label', async ({ is }) => {
 | 
			
		||||
  const opts = {
 | 
			
		||||
    timestamp: () => ',"custom-time-label":"none"'
 | 
			
		||||
  }
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(opts, stream)
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('custom-time-label'), true)
 | 
			
		||||
  is(result['custom-time-label'], 'none')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('inserts timestamp by default', async ({ ok, is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(stream)
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
 | 
			
		||||
  is(result.msg, 'foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('omits timestamp when timestamp option is false', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ timestamp: false }, stream)
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), false)
 | 
			
		||||
  is(result.msg, 'foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('inserts timestamp when timestamp option is true', async ({ ok, is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino({ timestamp: true }, stream)
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
 | 
			
		||||
  is(result.msg, 'foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child inserts timestamp by default', async ({ ok, is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino(stream)
 | 
			
		||||
  const instance = logger.child({ component: 'child' })
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
 | 
			
		||||
  is(result.msg, 'foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('child omits timestamp with option', async ({ is }) => {
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const logger = pino({ timestamp: false }, stream)
 | 
			
		||||
  const instance = logger.child({ component: 'child' })
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), false)
 | 
			
		||||
  is(result.msg, 'foobar')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino.stdTimeFunctions.unixTime returns seconds based timestamps', async ({ is }) => {
 | 
			
		||||
  const opts = {
 | 
			
		||||
    timestamp: pino.stdTimeFunctions.unixTime
 | 
			
		||||
  }
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(opts, stream)
 | 
			
		||||
  const now = Date.now
 | 
			
		||||
  Date.now = () => 1531069919686
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  is(result.time, 1531069920)
 | 
			
		||||
  Date.now = now
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('pino.stdTimeFunctions.isoTime returns ISO 8601 timestamps', async ({ is }) => {
 | 
			
		||||
  const opts = {
 | 
			
		||||
    timestamp: pino.stdTimeFunctions.isoTime
 | 
			
		||||
  }
 | 
			
		||||
  const stream = sink()
 | 
			
		||||
  const instance = pino(opts, stream)
 | 
			
		||||
  const ms = 1531069919686
 | 
			
		||||
  const now = Date.now
 | 
			
		||||
  Date.now = () => ms
 | 
			
		||||
  const iso = new Date(ms).toISOString()
 | 
			
		||||
  instance.info('foobar')
 | 
			
		||||
  const result = await once(stream, 'data')
 | 
			
		||||
  is(result.hasOwnProperty('time'), true)
 | 
			
		||||
  is(result.time, iso)
 | 
			
		||||
  Date.now = now
 | 
			
		||||
})
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue