UNPKG

pino

Version:

super fast, all natural json logger

139 lines (117 loc) 3.14 kB
'use strict' const metadata = Symbol.for('pino.metadata') const { levels } = require('./levels') const defaultLevels = Object.create(levels) defaultLevels.silent = Infinity function multistream (streamsArray, opts) { let counter = 0 streamsArray = streamsArray || [] opts = opts || { dedupe: false } let levels = defaultLevels if (opts.levels && typeof opts.levels === 'object') { levels = opts.levels } const res = { write, add, flushSync, end, minLevel: 0, streams: [], clone, [metadata]: true } if (Array.isArray(streamsArray)) { streamsArray.forEach(add, res) } else { add.call(res, streamsArray) } // clean this object up // or it will stay allocated forever // as it is closed on the following closures streamsArray = null return res // we can exit early because the streams are ordered by level function write (data) { let dest const level = this.lastLevel const { streams } = this let stream for (let i = 0; i < streams.length; i++) { dest = streams[i] if (dest.level <= level) { stream = dest.stream if (stream[metadata]) { const { lastTime, lastMsg, lastObj, lastLogger } = this stream.lastLevel = level stream.lastTime = lastTime stream.lastMsg = lastMsg stream.lastObj = lastObj stream.lastLogger = lastLogger } if (!opts.dedupe || dest.level === level) { stream.write(data) } } else { break } } } function flushSync () { for (const { stream } of this.streams) { if (typeof stream.flushSync === 'function') { stream.flushSync() } } } function add (dest) { const { streams } = this if (typeof dest.write === 'function') { return add.call(this, { stream: dest }) } else if (typeof dest.levelVal === 'number') { return add.call(this, Object.assign({}, dest, { level: dest.levelVal, levelVal: undefined })) } else if (typeof dest.level === 'string') { return add.call(this, Object.assign({}, dest, { level: levels[dest.level] })) } else if (typeof dest.level !== 'number') { // we default level to 'info' dest = Object.assign({}, dest, { level: 30 }) } else { dest = Object.assign({}, dest) } dest.id = counter++ streams.unshift(dest) streams.sort(compareByLevel) this.minLevel = streams[0].level return res } function end () { for (const { stream } of this.streams) { if (typeof stream.flushSync === 'function') { stream.flushSync() } stream.end() } } function clone (level) { const streams = new Array(this.streams.length) for (let i = 0; i < streams.length; i++) { streams[i] = { level: level, stream: this.streams[i].stream } } return { write, add, minLevel: level, streams, clone, flushSync, [metadata]: true } } } function compareByLevel (a, b) { return a.level - b.level } module.exports = multistream