You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					438 lines
				
				12 KiB
			
		
		
			
		
	
	
					438 lines
				
				12 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'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,
							 | 
						||
| 
								 | 
							
								  redactFmtSym,
							 | 
						||
| 
								 | 
							
								  streamSym,
							 | 
						||
| 
								 | 
							
								  nestedKeySym,
							 | 
						||
| 
								 | 
							
								  formattersSym,
							 | 
						||
| 
								 | 
							
								  messageKeySym
							 | 
						||
| 
								 | 
							
								} = require('./symbols')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function noop () {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function genLog (level, hook) {
							 | 
						||
| 
								 | 
							
								  if (!hook) return LOG
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return function hookWrappedLog (...args) {
							 | 
						||
| 
								 | 
							
								    hook.call(this, args, LOG, level)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function LOG (o, ...n) {
							 | 
						||
| 
								 | 
							
								    if (typeof o === 'object') {
							 | 
						||
| 
								 | 
							
								      let msg = o
							 | 
						||
| 
								 | 
							
								      if (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 }
							 | 
						||
| 
								 | 
							
								      let formatParams
							 | 
						||
| 
								 | 
							
								      if (msg === null && n.length === 0) {
							 | 
						||
| 
								 | 
							
								        formatParams = [null]
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        msg = n.shift()
							 | 
						||
| 
								 | 
							
								        formatParams = n
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this[writeSym](o, format(msg, formatParams, this[formatOptsSym]), level)
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this[writeSym](null, format(o, n, this[formatOptsSym]), level)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 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) {
							 | 
						||
| 
								 | 
							
								  let result = ''
							 | 
						||
| 
								 | 
							
								  let last = 0
							 | 
						||
| 
								 | 
							
								  let found = false
							 | 
						||
| 
								 | 
							
								  let 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, msg, num, time) {
							 | 
						||
| 
								 | 
							
								  const stringify = this[stringifySym]
							 | 
						||
| 
								 | 
							
								  const stringifiers = this[stringifiersSym]
							 | 
						||
| 
								 | 
							
								  const end = this[endSym]
							 | 
						||
| 
								 | 
							
								  const chindings = this[chindingsSym]
							 | 
						||
| 
								 | 
							
								  const serializers = this[serializersSym]
							 | 
						||
| 
								 | 
							
								  const formatters = this[formattersSym]
							 | 
						||
| 
								 | 
							
								  const messageKey = this[messageKeySym]
							 | 
						||
| 
								 | 
							
								  let 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let value
							 | 
						||
| 
								 | 
							
								  const notHasOwnProperty = obj.hasOwnProperty === undefined
							 | 
						||
| 
								 | 
							
								  if (formatters.log) {
							 | 
						||
| 
								 | 
							
								    obj = formatters.log(obj)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (msg !== undefined) {
							 | 
						||
| 
								 | 
							
								    obj[messageKey] = msg
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const wildcardStringifier = stringifiers[wildcardFirstSym]
							 | 
						||
| 
								 | 
							
								  for (const 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 explicitly 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) {
							 | 
						||
| 
								 | 
							
								  let value
							 | 
						||
| 
								 | 
							
								  let data = instance[chindingsSym]
							 | 
						||
| 
								 | 
							
								  const stringify = instance[stringifySym]
							 | 
						||
| 
								 | 
							
								  const stringifiers = instance[stringifiersSym]
							 | 
						||
| 
								 | 
							
								  const wildcardStringifier = stringifiers[wildcardFirstSym]
							 | 
						||
| 
								 | 
							
								  const serializers = instance[serializersSym]
							 | 
						||
| 
								 | 
							
								  const formatter = instance[formattersSym].bindings
							 | 
						||
| 
								 | 
							
								  bindings = formatter(bindings)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (const key in bindings) {
							 | 
						||
| 
								 | 
							
								    value = bindings[key]
							 | 
						||
| 
								 | 
							
								    const valid = key !== 'level' &&
							 | 
						||
| 
								 | 
							
								      key !== 'serializers' &&
							 | 
						||
| 
								 | 
							
								      key !== 'formatters' &&
							 | 
						||
| 
								 | 
							
								      key !== 'customLevels' &&
							 | 
						||
| 
								 | 
							
								      bindings.hasOwnProperty(key) &&
							 | 
						||
| 
								 | 
							
								      value !== undefined
							 | 
						||
| 
								 | 
							
								    if (valid === true) {
							 | 
						||
| 
								 | 
							
								      value = serializers[key] ? serializers[key](value) : value
							 | 
						||
| 
								 | 
							
								      value = (stringifiers[key] || wildcardStringifier || 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, opts)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    const prettyFactory = require('pino-pretty').prettyFactory || require('pino-pretty')
							 | 
						||
| 
								 | 
							
								    prettyFactory.asMetaWrapper = prettifierMetaWrapper
							 | 
						||
| 
								 | 
							
								    return prettifierMetaWrapper(prettyFactory(opts), dest, opts)
							 | 
						||
| 
								 | 
							
								  } catch (e) {
							 | 
						||
| 
								 | 
							
								    if (e.message.startsWith("Cannot find module 'pino-pretty'")) {
							 | 
						||
| 
								 | 
							
								      throw Error('Missing `pino-pretty` module: `pino-pretty` must be installed separately')
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    throw e
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function prettifierMetaWrapper (pretty, dest, opts) {
							 | 
						||
| 
								 | 
							
								  opts = Object.assign({ suppressFlushSyncWarning: false }, opts)
							 | 
						||
| 
								 | 
							
								  let warned = false
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    [needsMetadataGsym]: true,
							 | 
						||
| 
								 | 
							
								    lastLevel: 0,
							 | 
						||
| 
								 | 
							
								    lastMsg: null,
							 | 
						||
| 
								 | 
							
								    lastObj: null,
							 | 
						||
| 
								 | 
							
								    lastLogger: null,
							 | 
						||
| 
								 | 
							
								    flushSync () {
							 | 
						||
| 
								 | 
							
								      if (opts.suppressFlushSyncWarning || 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
							 | 
						||
| 
								 | 
							
								      let 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('{' + lastLogger[chindingsSym].substr(1) + '}')
							 | 
						||
| 
								 | 
							
								        lastLogger[parsedChindingsSym] = chindings
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return chindings
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    write (chunk) {
							 | 
						||
| 
								 | 
							
								      const lastLogger = this.lastLogger
							 | 
						||
| 
								 | 
							
								      const chindings = this.chindings()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      let time = this.lastTime
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (time.match(/^\d+/)) {
							 | 
						||
| 
								 | 
							
								        time = parseInt(time)
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        time = time.slice(1, -1)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const lastObj = this.lastObj
							 | 
						||
| 
								 | 
							
								      const lastMsg = this.lastMsg
							 | 
						||
| 
								 | 
							
								      const errorProps = null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const formatters = lastLogger[formattersSym]
							 | 
						||
| 
								 | 
							
								      const formattedObj = formatters.log ? formatters.log(lastObj) : lastObj
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const messageKey = lastLogger[messageKeySym]
							 | 
						||
| 
								 | 
							
								      if (lastMsg && formattedObj && !formattedObj.hasOwnProperty(messageKey)) {
							 | 
						||
| 
								 | 
							
								        formattedObj[messageKey] = lastMsg
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const obj = Object.assign({
							 | 
						||
| 
								 | 
							
								        level: this.lastLevel,
							 | 
						||
| 
								 | 
							
								        time
							 | 
						||
| 
								 | 
							
								      }, formattedObj, errorProps)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const serializers = lastLogger[serializersSym]
							 | 
						||
| 
								 | 
							
								      const keys = Object.keys(serializers)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      for (var i = 0; i < keys.length; i++) {
							 | 
						||
| 
								 | 
							
								        const key = keys[i]
							 | 
						||
| 
								 | 
							
								        if (obj[key] !== undefined) {
							 | 
						||
| 
								 | 
							
								          obj[key] = serializers[key](obj[key])
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      for (const key in chindings) {
							 | 
						||
| 
								 | 
							
								        if (!obj.hasOwnProperty(key)) {
							 | 
						||
| 
								 | 
							
								          obj[key] = chindings[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 (opts) {
							 | 
						||
| 
								 | 
							
								  const stream = new SonicBoom(opts)
							 | 
						||
| 
								 | 
							
								  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({ dest: opts, sync: true })
							 | 
						||
| 
								 | 
							
								      opts = {}
							 | 
						||
| 
								 | 
							
								    } else if (typeof stream === 'string') {
							 | 
						||
| 
								 | 
							
								      stream = buildSafeSonicBoom({ dest: stream, sync: true })
							 | 
						||
| 
								 | 
							
								    } 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.destination({ sync: false }) 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({ fd: stream.fd, sync: true })
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    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')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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 buildFormatters (level, bindings, log) {
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    level,
							 | 
						||
| 
								 | 
							
								    bindings,
							 | 
						||
| 
								 | 
							
								    log
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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,
							 | 
						||
| 
								 | 
							
								  buildFormatters
							 | 
						||
| 
								 | 
							
								}
							 |