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
						
					
					
				'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
 | 
						|
}
 |