Skip to content

Commit 4597c08

Browse files
committed
fix: allow for zero backups and zero daysToKeep
1 parent c0945c0 commit 4597c08

File tree

7 files changed

+69
-12
lines changed

7 files changed

+69
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ When filename size >= maxSize then:
5555
* `compress` \<boolean\> - defaults to `false` - compress the backup files using gzip (files will have `.gz` extension).
5656
* `keepFileExt` \<boolean\> - defaults to `false` - keep the file original extension. e.g.: `abc.log -> abc.2013-08-30.log`.
5757
* `alwaysIncludePattern` \<boolean\> - defaults to `false` - extend the initial file with the pattern
58-
* `daysToKeep` \<integer\> - defaults to `MAX_SAFE_INTEGER` - the number of old files that matches the pattern to keep (excluding the hot file)
58+
* `daysToKeep` \<integer\> - defaults to `1` - the number of old files that matches the pattern to keep (excluding the hot file)
5959

6060

6161
This returns a `WritableStream`. When the current time, formatted as `pattern`, changes then the current file will be renamed to `filename.formattedDate` where `formattedDate` is the result of processing the date through the pattern, and a new file will begin to be written. Streamroller uses [date-format](http://github.com/nomiddlename/date-format) to format dates, and the `pattern` should use the date-format format. e.g. with a `pattern` of `".yyyy-MM-dd"`, and assuming today is August 29, 2013 then writing to the stream today will just write to `filename`. At midnight (or more precisely, at the next file write after midnight), `filename` will be renamed to `filename.2013-08-29` and a new `filename` will be created. If `options.alwaysIncludePattern` is true, then the initial file will be `filename.2013-08-29` and no renaming will occur at midnight, but a new file will be written to with the name `filename.2013-08-30`.

lib/DateRollingFileStream.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ class DateRollingFileStream extends RollingFileWriteStream {
1313
if (!pattern) {
1414
pattern = 'yyyy-MM-dd';
1515
}
16-
if (options.daysToKeep) {
17-
options.numToKeep = options.daysToKeep;
16+
if (!options.daysToKeep && options.daysToKeep !== 0) {
17+
options.daysToKeep = 1;
18+
} else if (options.daysToKeep < 0) {
19+
throw new Error(`options.daysToKeep (${options.daysToKeep}) should be >= 0`);
20+
} else if (options.daysToKeep >= Number.MAX_SAFE_INTEGER) {
21+
// to cater for numToKeep (include the hot file) at Number.MAX_SAFE_INTEGER
22+
throw new Error(`options.daysToKeep (${options.daysToKeep}) should be < Number.MAX_SAFE_INTEGER`);
1823
}
24+
options.numToKeep = options.daysToKeep + 1;
1925
if (pattern.startsWith('.')) {
2026
pattern = pattern.substring(1);
2127
}

lib/RollingFileStream.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ class RollingFileStream extends RollingFileWriteStream {
99
if (size) {
1010
options.maxSize = size;
1111
}
12-
if (!backups) {
12+
if (!backups && backups !== 0) {
1313
backups = 1;
14+
} else if (backups < 0) {
15+
throw new Error(`backups (${backups}) should be >= 0`);
16+
} else if (backups >= Number.MAX_SAFE_INTEGER) {
17+
// to cater for numToKeep (include the hot file) at Number.MAX_SAFE_INTEGER
18+
throw new Error(`backups (${backups}) should be < Number.MAX_SAFE_INTEGER`);
1419
}
15-
options.numToKeep = backups;
20+
options.numToKeep = backups + 1;
1621
super(filename, options);
17-
this.backups = this.options.numToKeep;
22+
this.backups = backups;
1823
this.size = this.options.maxSize;
1924
}
2025

lib/RollingFileWriteStream.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ class RollingFileWriteStream extends Writable {
250250
debug("_clean: existing files are: ", existingFileDetails);
251251
if (this._tooManyFiles(existingFileDetails.length)) {
252252
const fileNamesToRemove = existingFileDetails
253-
.slice(0, existingFileDetails.length - this.options.numToKeep - 1)
253+
.slice(0, existingFileDetails.length - this.options.numToKeep)
254254
.map(f => path.format({ dir: this.fileObject.dir, base: f.filename }));
255255
await deleteFiles(fileNamesToRemove);
256256
}

test/DateRollingFileStream-test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,28 @@ describe("DateRollingFileStream", function() {
460460
});
461461
});
462462

463+
describe("with invalid number of daysToKeep", () => {
464+
it("should complain about negative daysToKeep", () => {
465+
const daysToKeep = -1;
466+
(() => {
467+
new DateRollingFileStream(
468+
path.join(__dirname, "daysToKeep.log"),
469+
{ daysToKeep: daysToKeep }
470+
);
471+
}).should.throw(`options.daysToKeep (${daysToKeep}) should be >= 0`);
472+
});
473+
474+
it("should complain about daysToKeep >= Number.MAX_SAFE_INTEGER", () => {
475+
const daysToKeep = Number.MAX_SAFE_INTEGER;
476+
(() => {
477+
new DateRollingFileStream(
478+
path.join(__dirname, "daysToKeep.log"),
479+
{ daysToKeep: daysToKeep }
480+
);
481+
}).should.throw(`options.daysToKeep (${daysToKeep}) should be < Number.MAX_SAFE_INTEGER`);
482+
});
483+
});
484+
463485
describe("with daysToKeep option", function() {
464486
let stream;
465487
var daysToKeep = 4;
@@ -539,7 +561,7 @@ describe("DateRollingFileStream", function() {
539561
stream.write("New file message\n", "utf8", done);
540562
});
541563

542-
it("should be 4 files left from original 3", async function() {
564+
it("should be 5 files left from original 11", async function() {
543565
const files = await fs.readdir(__dirname);
544566
var logFiles = files.filter(
545567
file => file.indexOf("compressedDaysToKeep.log") > -1

test/RollingFileStream-test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,30 @@ describe("RollingFileStream", function() {
119119
});
120120
});
121121

122+
describe("with invalid number of backups", () => {
123+
it("should complain about negative backups", () => {
124+
const backups = -1;
125+
(() => {
126+
new RollingFileStream(
127+
path.join(__dirname, "test-rolling-file-stream"),
128+
1024,
129+
backups
130+
);
131+
}).should.throw(`backups (${backups}) should be >= 0`);
132+
});
133+
134+
it("should complain about backups >= Number.MAX_SAFE_INTEGER", () => {
135+
const backups = Number.MAX_SAFE_INTEGER;
136+
(() => {
137+
new RollingFileStream(
138+
path.join(__dirname, "test-rolling-file-stream"),
139+
1024,
140+
backups
141+
);
142+
}).should.throw(`backups (${backups}) should be < Number.MAX_SAFE_INTEGER`);
143+
});
144+
});
145+
122146
describe("writing less than the file size", function() {
123147
before(async function() {
124148
await remove("test-rolling-file-stream-write-less");

test/RollingFileWriteStream-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -472,15 +472,15 @@ describe("RollingFileWriteStream", () => {
472472
});
473473
});
474474

475-
describe("with 5 maxSize and 3 files limit", () => {
475+
describe("with 5 maxSize and 3 backups limit", () => {
476476
const fileObj = generateTestFile();
477477
let s;
478478

479479
before(async () => {
480480
fakeNow = new Date(2012, 8, 12, 10, 37, 11);
481481
s = new RollingFileWriteStream(fileObj.path, {
482482
maxSize: 5,
483-
numToKeep: 3
483+
numToKeep: 4
484484
});
485485
const flows = Array.from(Array(38).keys()).map(i => () => {
486486
fakeNow = new Date(2012, 8, 12 + parseInt(i / 5), 10, 37, 11);
@@ -543,7 +543,7 @@ describe("RollingFileWriteStream", () => {
543543
});
544544
});
545545

546-
describe("with 5 maxSize and 3 files limit, rotating daily", () => {
546+
describe("with 5 maxSize and 3 backups limit, rotating daily", () => {
547547
const fileObj = generateTestFile();
548548
let s;
549549

@@ -552,7 +552,7 @@ describe("RollingFileWriteStream", () => {
552552
s = new RollingFileWriteStream(fileObj.path, {
553553
maxSize: 5,
554554
pattern: "yyyy-MM-dd",
555-
numToKeep: 3
555+
numToKeep: 4
556556
});
557557
const flows = Array.from(Array(38).keys()).map(i => () => {
558558
fakeNow = new Date(2012, 8, 12 + parseInt(i / 10), 10, 37, 11);

0 commit comments

Comments
 (0)