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.
		
		
		
		
		
			
		
			
				
					194 lines
				
				4.9 KiB
			
		
		
			
		
	
	
					194 lines
				
				4.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								/* eslint no-prototype-builtins: 0 */
							 | 
						||
| 
								 | 
							
								const flatstr = require('flatstr')
							 | 
						||
| 
								 | 
							
								const {
							 | 
						||
| 
								 | 
							
								  lsCacheSym,
							 | 
						||
| 
								 | 
							
								  levelValSym,
							 | 
						||
| 
								 | 
							
								  useOnlyCustomLevelsSym,
							 | 
						||
| 
								 | 
							
								  streamSym,
							 | 
						||
| 
								 | 
							
								  formattersSym,
							 | 
						||
| 
								 | 
							
								  hooksSym
							 | 
						||
| 
								 | 
							
								} = require('./symbols')
							 | 
						||
| 
								 | 
							
								const { noop, genLog } = require('./tools')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const levels = {
							 | 
						||
| 
								 | 
							
								  trace: 10,
							 | 
						||
| 
								 | 
							
								  debug: 20,
							 | 
						||
| 
								 | 
							
								  info: 30,
							 | 
						||
| 
								 | 
							
								  warn: 40,
							 | 
						||
| 
								 | 
							
								  error: 50,
							 | 
						||
| 
								 | 
							
								  fatal: 60
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								const levelMethods = {
							 | 
						||
| 
								 | 
							
								  fatal: (hook) => {
							 | 
						||
| 
								 | 
							
								    const logFatal = genLog(levels.fatal, hook)
							 | 
						||
| 
								 | 
							
								    return function (...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: (hook) => genLog(levels.error, hook),
							 | 
						||
| 
								 | 
							
								  warn: (hook) => genLog(levels.warn, hook),
							 | 
						||
| 
								 | 
							
								  info: (hook) => genLog(levels.info, hook),
							 | 
						||
| 
								 | 
							
								  debug: (hook) => genLog(levels.debug, hook),
							 | 
						||
| 
								 | 
							
								  trace: (hook) => genLog(levels.trace, hook)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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 formatter = instance[formattersSym].level
							 | 
						||
| 
								 | 
							
								  const { labels } = instance.levels
							 | 
						||
| 
								 | 
							
								  const cache = {}
							 | 
						||
| 
								 | 
							
								  for (const label in labels) {
							 | 
						||
| 
								 | 
							
								    const level = formatter(labels[label], Number(label))
							 | 
						||
| 
								 | 
							
								    cache[label] = JSON.stringify(level).slice(0, -1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  instance[lsCacheSym] = cache
							 | 
						||
| 
								 | 
							
								  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]
							 | 
						||
| 
								 | 
							
								  const hook = this[hooksSym].logMethod
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (const key in values) {
							 | 
						||
| 
								 | 
							
								    if (levelVal > values[key]) {
							 | 
						||
| 
								 | 
							
								      this[key] = noop
							 | 
						||
| 
								 | 
							
								      continue
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this[key] = isStandardLevel(key, useOnlyCustomLevelsVal) ? levelMethods[key](hook) : genLog(values[key], hook)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.emit(
							 | 
						||
| 
								 | 
							
								    'level-change',
							 | 
						||
| 
								 | 
							
								    level,
							 | 
						||
| 
								 | 
							
								    levelVal,
							 | 
						||
| 
								 | 
							
								    labels[preLevelVal],
							 | 
						||
| 
								 | 
							
								    preLevelVal
							 | 
						||
| 
								 | 
							
								  )
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getLevel (level) {
							 | 
						||
| 
								 | 
							
								  const { levels, levelVal } = this
							 | 
						||
| 
								 | 
							
								  // protection against potential loss of Pino scope from serializers (edge case with circular refs - https://github.com/pinojs/pino/issues/833)
							 | 
						||
| 
								 | 
							
								  return (levels && levels.labels) ? 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
							 | 
						||
| 
								 | 
							
								    /* eslint-disable */
							 | 
						||
| 
								 | 
							
								    ? Object.keys(customLevels).reduce((o, k) => {
							 | 
						||
| 
								 | 
							
								        o[customLevels[k]] = k
							 | 
						||
| 
								 | 
							
								        return o
							 | 
						||
| 
								 | 
							
								      }, {})
							 | 
						||
| 
								 | 
							
								    : null
							 | 
						||
| 
								 | 
							
								    /* eslint-enable */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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
							 | 
						||
| 
								 | 
							
								}
							 |