Skip to content

Commit 83a7754

Browse files
authoredJan 22, 2022
Exposing the watch_log from file-stream-rotator to allow the logfile 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
1 parent 3262308 commit 83a7754

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed
 

‎daily-rotate-file.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ var DailyRotateFile = function (options) {
9090
utc: options.utc ? options.utc : false,
9191
extension: options.extension ? options.extension : '',
9292
create_symlink: options.createSymlink ? options.createSymlink : false,
93-
symlink_name: options.symlinkName ? options.symlinkName : 'current.log'
93+
symlink_name: options.symlinkName ? options.symlinkName : 'current.log',
94+
watch_log: options.watchLog ? options.watchLog : false
9495
});
9596

9697
this.logStream.on('new', function (newFile) {
@@ -141,6 +142,12 @@ var DailyRotateFile = function (options) {
141142
});
142143
});
143144
}
145+
146+
if (options.watchLog) {
147+
this.logStream.on('addWatcher', (newFile) => {
148+
self.emit('addWatcher', newFile);
149+
})
150+
}
144151
}
145152
};
146153

‎index.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ declare namespace DailyRotateFile {
9494
*/
9595
symlinkName?: string;
9696

97+
/**
98+
* Watch the current file being written to and recreate it in case of accidental deletion. (default: FALSE)
99+
*/
100+
watchLog?: boolean;
101+
97102
handleRejections?: boolean;
98103
}
99104
}

‎test/transport-tests.js

+37-6
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,19 @@ describe('winston/transports/daily-rotate-file', function () {
9393
});
9494

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

100100
var logEntry = JSON.parse(logEntries[0]);
101101
expect(logEntry.level).to.equal('info');
102102
expect(logEntry.message).to.equal('this message should write to the file');
103103
done();
104-
});
104+
105+
this.transport.removeListener('finish', finishListener)
106+
}
107+
108+
this.transport.on('finish', finishListener);
105109

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

156160
this.transport = new DailyRotateFile(opts);
157161

158-
this.transport.on('finish', function () {
162+
const finishListener = () => {
159163
fs.readdir(logDir, function (err, files) {
160164
expect(files.filter(function (file) {
161165
return path.extname(file) === '.gz';
162166
}).length).to.equal(1);
163167
done();
164168
});
165-
});
169+
170+
this.transport.removeListener('finish', finishListener)
171+
}
172+
173+
this.transport.on('finish', finishListener);
166174
sendLogItem(this.transport, 'info', randomString(1056));
167175
sendLogItem(this.transport, 'info', randomString(1056));
168176
this.transport.close();
169177
});
170178
});
171179

180+
describe('when setting watchLog', function () {
181+
it('should addWatcher to recreate log if deleted', function (done) {
182+
var opts = Object.assign({}, options);
183+
opts.watchLog = true;
184+
this.transport = new DailyRotateFile(opts);
185+
186+
this.transport.on('addWatcher', (newFile) => {
187+
expect(newFile).to.equal(filename);
188+
done()
189+
});
190+
191+
this.transport.on('new', (newFile) => {
192+
expect(newFile).to.equal(filename);
193+
});
194+
195+
sendLogItem(this.transport, 'info', 'First message to file');
196+
this.transport.close();
197+
});
198+
});
199+
172200
describe('query', function () {
173201
it('should call callback when no files are present', function () {
174202
this.transport.query(function (err, results) {
@@ -200,13 +228,16 @@ describe('winston/transports/daily-rotate-file', function () {
200228
sendLogItem(this.transport, 'info', randomString(1056));
201229

202230
var self = this;
203-
this.transport.on('finish', function () {
231+
const finishListener = () => {
204232
self.transport.query(function (err, results) {
205233
expect(results).to.not.be.null;
206234
expect(results.length).to.equal(4);
207235
done();
208236
});
209-
});
237+
this.transport.removeListener('finish', finishListener)
238+
}
239+
240+
this.transport.on('finish', finishListener);
210241

211242
this.transport.close();
212243
});

0 commit comments

Comments
 (0)
Please sign in to comment.