UNPKG

detox

Version:

E2E tests and automation for mobile

106 lines (87 loc) 2.76 kB
const { PassThrough } = require('stream'); const { promisify } = require('util'); const bunyan = require('bunyan'); const bds = require('bunyan-debug-stream'); const _ = require('lodash'); const { DetoxInternalError } = require('../../errors'); class BunyanLogger { constructor() { this._bunyan = bunyan.createLogger({ name: 'detox', streams: [] }); /** @type {bunyan.Stream} */ this._debugStream = null; /** @type {bunyan.Stream} */ this._fileStream = null; } /** * @returns {bunyan} */ get logger() { return this._bunyan; } /** * @param {Detox.DetoxLoggerConfig} config * @returns {this} */ installDebugStream(config) { if (this._debugStream) { _.remove(this._bunyan['streams'], this._debugStream); // @ts-ignore this._debugStream.stream.end(); this._debugStream = null; } const streamOptions = { out: null, ...config.options }; /* istanbul ignore next */ if (!streamOptions.out) { // This is a default if-else branch, used everywhere except for the unit tests. streamOptions.out = new PassThrough().pipe(process.stderr); } this._bunyan.addStream({ type: 'raw', level: config.level, stream: bds.default(streamOptions), }); this._debugStream = _.last(this._bunyan['streams']); return this; } /** * @param {string} file * @returns {this} */ installFileStream(file) { /* istanbul ignore next */ if (this._fileStream) { // This is an impossible condition, but we keep it here for the sake of completeness. throw new DetoxInternalError('Trying to install a second file stream inside already initialized Bunyan logger'); } this._fileStream = { level: 'trace', path: file, }; this._bunyan.addStream(this._fileStream); return this; } async closeFileStreams() { const internalBunyanStreams = this._bunyan['streams']; const openFileStreams = _.filter(internalBunyanStreams, this._isOpenFileStream); _.remove(internalBunyanStreams, openFileStreams); await Promise.all(openFileStreams.map(bunyanStream => { const stream = bunyanStream.stream; return promisify(stream.end.bind(stream))(); })); } /** @private */ _isOpenFileStream = (bunyanStream) => { switch (bunyanStream.type) { case 'file': return bunyanStream.path && !bunyanStream.stream.destroyed; case 'raw': /* istanbul ignore next */ const stream = bunyanStream.stream === this._debugStream.stream ? bunyanStream.stream._out : bunyanStream.stream; /* istanbul ignore next */ return stream.fd > 2 && !stream.closed; } }; } module.exports = BunyanLogger;