Skip to content

Commit

Permalink
Exposing the watch_log from file-stream-rotator to allow the logfile …
Browse files Browse the repository at this point in the history
…to be recreated in case of accidental deletion (#323)

* Exposing the watch_log option from file-stream-rotator to allow log file to be recreated in case of accidental deletion

* Adding unit test to check for addWatcher event

* Fix other unit tests to remove listener after event
  • Loading branch information
chneil authored Jan 22, 2022
1 parent 3262308 commit 83a7754
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
9 changes: 8 additions & 1 deletion daily-rotate-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ var DailyRotateFile = function (options) {
utc: options.utc ? options.utc : false,
extension: options.extension ? options.extension : '',
create_symlink: options.createSymlink ? options.createSymlink : false,
symlink_name: options.symlinkName ? options.symlinkName : 'current.log'
symlink_name: options.symlinkName ? options.symlinkName : 'current.log',
watch_log: options.watchLog ? options.watchLog : false
});

this.logStream.on('new', function (newFile) {
Expand Down Expand Up @@ -141,6 +142,12 @@ var DailyRotateFile = function (options) {
});
});
}

if (options.watchLog) {
this.logStream.on('addWatcher', (newFile) => {
self.emit('addWatcher', newFile);
})
}
}
};

Expand Down
5 changes: 5 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ declare namespace DailyRotateFile {
*/
symlinkName?: string;

/**
* Watch the current file being written to and recreate it in case of accidental deletion. (default: FALSE)
*/
watchLog?: boolean;

handleRejections?: boolean;
}
}
Expand Down
43 changes: 37 additions & 6 deletions test/transport-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,19 @@ describe('winston/transports/daily-rotate-file', function () {
});

it('should write to the file', function (done) {
this.transport.on('finish', function () {
const finishListener = () => {
var logEntries = fs.readFileSync(filename).toString().split('\n').slice(0, -1);
expect(logEntries.length).to.equal(1);

var logEntry = JSON.parse(logEntries[0]);
expect(logEntry.level).to.equal('info');
expect(logEntry.message).to.equal('this message should write to the file');
done();
});

this.transport.removeListener('finish', finishListener)
}

this.transport.on('finish', finishListener);

sendLogItem(this.transport, 'info', 'this message should write to the file', {}, function (err, logged) {
expect(err).to.be.null;
Expand Down Expand Up @@ -155,20 +159,44 @@ describe('winston/transports/daily-rotate-file', function () {

this.transport = new DailyRotateFile(opts);

this.transport.on('finish', function () {
const finishListener = () => {
fs.readdir(logDir, function (err, files) {
expect(files.filter(function (file) {
return path.extname(file) === '.gz';
}).length).to.equal(1);
done();
});
});

this.transport.removeListener('finish', finishListener)
}

this.transport.on('finish', finishListener);
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
this.transport.close();
});
});

describe('when setting watchLog', function () {
it('should addWatcher to recreate log if deleted', function (done) {
var opts = Object.assign({}, options);
opts.watchLog = true;
this.transport = new DailyRotateFile(opts);

this.transport.on('addWatcher', (newFile) => {
expect(newFile).to.equal(filename);
done()
});

this.transport.on('new', (newFile) => {
expect(newFile).to.equal(filename);
});

sendLogItem(this.transport, 'info', 'First message to file');
this.transport.close();
});
});

describe('query', function () {
it('should call callback when no files are present', function () {
this.transport.query(function (err, results) {
Expand Down Expand Up @@ -200,13 +228,16 @@ describe('winston/transports/daily-rotate-file', function () {
sendLogItem(this.transport, 'info', randomString(1056));

var self = this;
this.transport.on('finish', function () {
const finishListener = () => {
self.transport.query(function (err, results) {
expect(results).to.not.be.null;
expect(results.length).to.equal(4);
done();
});
});
this.transport.removeListener('finish', finishListener)
}

this.transport.on('finish', finishListener);

this.transport.close();
});
Expand Down

0 comments on commit 83a7754

Please sign in to comment.