Skip to content

Commit

Permalink
Merge 1641200 into 8077987
Browse files Browse the repository at this point in the history
  • Loading branch information
David Mark Clements committed Jul 13, 2018
2 parents 8077987 + 1641200 commit a64337c
Show file tree
Hide file tree
Showing 11 changed files with 479 additions and 272 deletions.
7 changes: 3 additions & 4 deletions benchmarks/child-creation.bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ const pino = require('../')
const bunyan = require('bunyan')
const bole = require('bole')('bench')
const fs = require('fs')
const dest = fs.createWriteStream('/dev/null')
const plog = pino(dest)
const plog = pino(pino.destination(('/dev/null')))
delete require.cache[require.resolve('../')]
const plogExtreme = require('../')(pino.extreme('/dev/null'))

Expand All @@ -15,13 +14,13 @@ const blog = bunyan.createLogger({
name: 'myapp',
streams: [{
level: 'trace',
stream: dest
stream: fs.createWriteStream('/dev/null')
}]
})

require('bole').output({
level: 'info',
stream: dest
stream: fs.createWriteStream('/dev/null')
}).setFastTime(true)

const run = bench([
Expand Down
51 changes: 51 additions & 0 deletions benchmarks/internal/custom-levels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict'

const bench = require('fastbench')
const pino = require('../../')

const base = pino(pino.destination('/dev/null'))
const baseCl = pino({
customLevels: {foo: 31}
}, pino.destination('/dev/null'))
const child = base.child({})
const childCl = base.child({
customLevels: {foo: 31}
})
const childOfBaseCl = baseCl.child({})

const max = 100

const run = bench([
function benchPinoNoCustomLevel (cb) {
for (var i = 0; i < max; i++) {
base.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoCustomLevel (cb) {
for (var i = 0; i < max; i++) {
baseCl.foo({ hello: 'world' })
}
setImmediate(cb)
},
function benchChildNoCustomLevel (cb) {
for (var i = 0; i < max; i++) {
child.info({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoChildCustomLevel (cb) {
for (var i = 0; i < max; i++) {
childCl.foo({ hello: 'world' })
}
setImmediate(cb)
},
function benchPinoChildInheritedCustomLevel (cb) {
for (var i = 0; i < max; i++) {
childOfBaseCl.foo({ hello: 'world' })
}
setImmediate(cb)
}
], 10000)

run(run)
4 changes: 2 additions & 2 deletions benchmarks/internal/parent-vs-child.bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const childChild = child.child({})
const childChildChild = childChild.child({})
const childChildChildChild = childChildChild.child({})
const child2 = base.child({})
const baseSerializers = pino({serializers: {err: () => {}}}, pino.destination('/dev/null'))
const baseSerializers = pino(pino.destination('/dev/null'))
const baseSerializersChild = baseSerializers.child({})
const baseSerializersChildSerializers = baseSerializers.child({serializers: {err: () => {}}})
const baseSerializersChildSerializers = baseSerializers.child({})

const max = 100

Expand Down
131 changes: 61 additions & 70 deletions lib/levels.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use strict'
const flatstr = require('flatstr')
const { setLevelSym, lsCacheSym, levelValSym } = require('./symbols')
const { lsCacheSym, levelValSym } = require('./symbols')
const { noop, genLog } = require('./tools')

const levels = {
fatal: 60,
error: 50,
warn: 40,
info: 30,
trace: 10,
debug: 20,
trace: 10
info: 30,
warn: 40,
error: 50,
fatal: 60
}

const levelMethods = {
Expand All @@ -26,14 +26,20 @@ const nums = Object.keys(levels).reduce((o, k) => {
return o
}, {})

// level string cache
const lsCache = Object.keys(nums).reduce((o, k) => {
o[k] = flatstr('{"level":' + Number(k))
const initialLsCache = Object.keys(nums).reduce((o, k) => {
if (!(k in o)) o[k] = flatstr('{"level":' + Number(k))
return o
}, {})

function genLsCache (instance) {
instance[lsCacheSym] = Object.keys(instance.levels.labels).reduce((o, k) => {
if (!(k in o)) o[k] = flatstr('{"level":' + Number(k))
return o
}, instance[lsCacheSym])
return instance
}

function isStandardLevel (level) {
if (level === Infinity) return true
switch (level) {
case 'fatal':
case 'error':
Expand All @@ -47,57 +53,31 @@ function isStandardLevel (level) {
}
}

function isStandardLevelVal (val) {
switch (val) {
case Infinity:
case 60:
case 50:
case 40:
case 30:
case 20:
case 10:
return true
default:
return false
}
}

function getLevelVal () {
return this[levelValSym]
}

function setLevelVal (num) {
if (typeof num !== 'number') throw Error('levelVal must be a number')

function setLevel (level) {
const { labels, values } = this.levels

this.emit(
'level-change',
labels[num],
num,
labels[this[levelValSym]],
this[levelValSym]
)

this[levelValSym] = num
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]

for (var key in values) {
if (num > values[key]) {
if (levelVal > values[key]) {
this[key] = noop
continue
}
this[key] = isStandardLevel(key) ? levelMethods[key] : genLog(values[key])
}
}

function setLevel (level) {
const { values } = this.levels
if (typeof level === 'number') {
this.levelVal = level
return
}
if (values[level] === undefined) throw Error('unknown level ' + level)
this.levelVal = values[level]
this.emit(
'level-change',
level,
levelVal,
labels[preLevelVal],
preLevelVal
)
}

function getLevel (level) {
Expand All @@ -107,13 +87,16 @@ function getLevel (level) {

function addLevel (name, lvl) {
const { values, labels } = this.levels
if (values.hasOwnProperty(name) === true) return false
if (labels.hasOwnProperty(lvl) === true) return false
if (name in values) {
throw Error('levels cannot be overridden')
}
if (lvl in labels) {
throw Error('pre-existing level values cannot be used for new levels')
}
values[name] = lvl
labels[lvl] = name
this[lsCacheSym][lvl] = flatstr('{"level":' + Number(lvl))
this[name] = lvl < this[levelValSym] ? noop : genLog(lvl)
return true
}

function isLevelEnabled (logLevel) {
Expand All @@ -122,33 +105,41 @@ function isLevelEnabled (logLevel) {
return logLevelVal !== undefined && (logLevelVal >= this[levelValSym])
}

function mappings () {
function mappings (customLevels = null) {
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'}}),
nums
nums,
customNums
)
const values = Object.assign(
Object.create(Object.prototype, {silent: {value: Infinity}}),
levels
levels,
customLevels
)
return { labels, values }
}

function setLevelState (instance, level, levelVal) {
const levelIsStandard = isStandardLevel(level)
const valIsStandard = isStandardLevelVal(levelVal)
if (valIsStandard === true) throw Error('level value is already used: ' + levelVal)
if (levelIsStandard === false && valIsStandard === false) instance.addLevel(level, levelVal)
instance[setLevelSym](level)
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 = {
setLevelState,
isStandardLevelVal,
lsCache,
assertNoLevelCollisions,
initialLsCache,
genLsCache,
levelMethods,
getLevelVal,
setLevelVal,
getLevel,
setLevel,
addLevel,
Expand Down
32 changes: 17 additions & 15 deletions lib/proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ const SonicBoom = require('sonic-boom')
const flatstr = require('flatstr')
const {
lsCacheSym,
getLevelValSym,
setLevelValSym,
levelValSym,
setLevelSym,
getLevelSym,
chindingsSym,
Expand All @@ -17,15 +16,14 @@ const {
needsMetadataGsym
} = require('./symbols')
const {
lsCache,
setLevelVal,
getLevelVal,
getLevel,
setLevel,
addLevel,
setLevelState,
isLevelEnabled,
isStandardLevelVal
mappings,
initialLsCache,
genLsCache,
assertNoLevelCollisions
} = require('./levels')
const {
noop,
Expand All @@ -47,15 +45,13 @@ const prototype = {
isLevelEnabled,
version,
silent: noop,
get levelVal () { return this[getLevelValSym]() },
set levelVal (num) { return this[setLevelValSym](num) },
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,
[lsCacheSym]: Object.assign({}, lsCache),
[getLevelValSym]: getLevelVal,
[setLevelValSym]: setLevelVal,
[getLevelSym]: getLevel,
[setLevelSym]: setLevel,
LOG_VERSION
Expand All @@ -66,7 +62,7 @@ Object.setPrototypeOf(prototype, EventEmitter.prototype)
module.exports = prototype

function child (bindings) {
const { level, levelVal } = this
const { level } = this
const serializers = this[serializersSym]
const chindings = asChindings(this, bindings)
const instance = Object.create(this)
Expand All @@ -79,10 +75,16 @@ function child (bindings) {
instance[serializersSym][bk] = bindings.serializers[bk]
}
} else instance[serializersSym] = serializers
if (bindings.hasOwnProperty('customLevels') === true) {
assertNoLevelCollisions(this.levels, bindings.customLevels)
const levels = mappings(bindings.customLevels)
instance.levels = levels
genLsCache(instance)
}
instance[chindingsSym] = chindings
const childLevel = bindings.level || level
if (isStandardLevelVal(levelVal) === true) instance[setLevelSym](childLevel)
else setLevelState(instance, childLevel, levelVal)
instance[setLevelSym](childLevel)

return instance
}

Expand Down
4 changes: 0 additions & 4 deletions lib/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

const setLevelSym = Symbol('pino.setLevel')
const getLevelSym = Symbol('pino.getLevel')
const setLevelValSym = Symbol('pino.setLevelVal')
const getLevelValSym = Symbol('pino.getLevelVal')
const levelValSym = Symbol('pino.levelVal')

const lsCacheSym = Symbol('pino.lsCache')
Expand All @@ -30,8 +28,6 @@ const needsMetadataGsym = Symbol.for('pino.metadata')
module.exports = {
setLevelSym,
getLevelSym,
setLevelValSym,
getLevelValSym,
levelValSym,
lsCacheSym,
chindingsSym,
Expand Down
1 change: 1 addition & 0 deletions lib/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ function asChindings (instance, bindings) {
value = bindings[key]
const valid = key !== 'level' &&
key !== 'serializers' &&
key !== 'customLevels' &&
bindings.hasOwnProperty(key) &&
value !== undefined
if (valid === true) {
Expand Down

0 comments on commit a64337c

Please sign in to comment.