diff --git a/lib/winston/transports/file.js b/lib/winston/transports/file.js index 88e7ee76e..ffaa47eb6 100644 --- a/lib/winston/transports/file.js +++ b/lib/winston/transports/file.js @@ -66,6 +66,7 @@ module.exports = class File extends TransportStream { console.warn('options.stream will be removed in winston@4. Use winston.transports.Stream'); throwIf('stream', 'filename', 'maxsize'); this._dest = this._stream.pipe(this._setupStream(options.stream)); + this.dirname = path.dirname(this._dest.path); // We need to listen for drain events when write() returns false. This // can make node mad at times. } else { @@ -88,6 +89,7 @@ module.exports = class File extends TransportStream { this._opening = false; this._ending = false; + if (this.dirname) this._createLogDirIfNotExist(this.dirname); this.open(); } @@ -685,4 +687,12 @@ module.exports = class File extends TransportStream { ); }); } + + _createLogDirIfNotExist(dirPath) { + /* eslint-disable no-sync */ + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + } + /* eslint-enable no-sync */ + } }; diff --git a/test/transports/file-create-dir-test.js b/test/transports/file-create-dir-test.js new file mode 100644 index 000000000..82407ce33 --- /dev/null +++ b/test/transports/file-create-dir-test.js @@ -0,0 +1,43 @@ +'use strict'; + +const fs = require('fs'); +const assert = require('assert'); +const path = require('path'); +const winston = require('../../lib/winston'); + +/* eslint-disable no-sync */ + +describe('winston/transports/file/createLogDir', function () { + const logDir = path.resolve(__dirname, '../fixtures/temp_logs'); + + beforeEach(function () { + fs.rmdirSync(logDir); + }); + + it('should create directory if it does not exist', function () { + winston.createLogger({ + transports: [ + new winston.transports.File({ + filename: path.join(logDir, 'file.log') + }) + ] + }); + + assert(fs.existsSync(logDir)); + }); + + it('should create directory if it does not exist when write to the stream', function () { + const streamfile = path.join(logDir, 'simple-stream.log'); + const stream = fs.createWriteStream(streamfile); + + winston.createLogger({ + transports: [ + new winston.transports.File({ + stream: stream + }) + ] + }); + + assert(fs.existsSync(logDir)); + }); +});