184 lines
4.5 KiB
JavaScript
184 lines
4.5 KiB
JavaScript
|
'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
|
||
|
}
|