From b40232f304baa6ca411b69162b9cdd99f8d362cf Mon Sep 17 00:00:00 2001 From: ADoyle Date: Thu, 19 Nov 2020 17:05:49 +0800 Subject: [PATCH] fix: File Transport not flush when logger.end() invoked --- lib/winston/transports/file.js | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/winston/transports/file.js b/lib/winston/transports/file.js index d0314be9f..04ec3c07e 100644 --- a/lib/winston/transports/file.js +++ b/lib/winston/transports/file.js @@ -87,6 +87,7 @@ module.exports = class File extends TransportStream { this._created = 0; this._drain = false; this._opening = false; + this._destOpened = false; this._ending = false; if (this.dirname) this._createLogDirIfNotExist(this.dirname); @@ -522,8 +523,8 @@ module.exports = class File extends TransportStream { */ _endStream(callback = () => {}) { if (this._dest) { - this._stream.unpipe(this._dest); this._dest.end(() => { + this._stream.unpipe(this._dest); this._cleanupStream(this._dest); callback(); }); @@ -532,6 +533,32 @@ module.exports = class File extends TransportStream { } } + /** + * To fix issue https://github.com/winstonjs/winston/issues/228 + * @private + * @param {function} cb Delaying the 'finish' event until callback is called + * @returns {undefined} + */ + _waitStreamsCreatedButNotPiped(cb) { + if (this._destOpened) { + return cb(); + } + + this.once('startPipe', () => { + this._dest.once('finish', () => { + cb(); + }); + + this.close(() => { + this._endStream(); + }); + }); + } + + _final(cb) { + this._waitStreamsCreatedButNotPiped(cb); + } + /** * Returns the WritableStream for the active file on this instance. If we * should gzip the file then a zlib stream is returned. @@ -549,8 +576,10 @@ module.exports = class File extends TransportStream { .on('close', () => debug('close', dest.path, dest.bytesWritten)) .on('open', () => { debug('file open ok', fullpath); + this._destOpened = true; this.emit('open', fullpath); source.pipe(dest); + this.emit('startPipe'); // If rotation occured during the open operation then we immediately // start writing to a new PassThrough, begin opening the next file