Skip to content

Commit

Permalink
Fixing rotateExisting feature
Browse files Browse the repository at this point in the history
Adding tests so that it doesn't rot again.
  • Loading branch information
Rcomian committed Jan 8, 2017
1 parent f85bf84 commit ad5dee9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ Bunyan Rotating File Stream is a stream component for the logging system "node b

# Recent changes

## 1.6.1 Fixed support for the "rotateExisting" flag

Tests have been added to ensure that this feature keeps working in the future.
Note that this feature may not work as expected with linux on EXT4.

## 1.6 Support for non-JSON logs

Minor release but now that logs which are written in a non-json format are supported.
Expand All @@ -40,6 +45,7 @@ Implemented tests and strategies to support specific node versions:
* 0.12.*latest*
* 4.*latest*
* 6.*latest*
* 7.*latest*

*0.10 and earlier*

Expand Down Expand Up @@ -172,7 +178,10 @@ the scope: top of the hour (h), midnight (d), start of Sunday (w), start of the
<td>If period is also set, will rotate an existing log file when the process
starts up if that file needs rotating due to its age. This means that
if you want a new file every day, and the process isn't running over midnight,
this option will give you that new file when you next startup.</td>
this option will give you that new file when you next startup.

See note on EXT4.
</td>
</tr>
<tr>
<td>threshold</td>
Expand Down Expand Up @@ -233,6 +242,20 @@ force the stream to create a new file instead.</p>
</tr>
</table>

## rotateExisting and Linux filesystems (EXT4) support

Some filesystems on Linux (in particular EXT4) do not record the file creation date.

Since the rotateExisting requires us to look at this date to see if the file would have been rotated had the
system been running for all that time, this feature cannot work as required.

You can check if this feature will work on your filesystem by executing `stat [mylogfile]`. If the "Birth" field
has a value in it, rfs will be able to see the creation time correctly.

Otherwise behaviour of this flag will be based on what birthtime is filled with. If it returns 0, then the file
will always be rotated. If it returns ctime, it will only be rotated if the rotation period has expired since the
last write.

# Templating

## Behaviour without templating
Expand Down
10 changes: 5 additions & 5 deletions lib/initialperiodtrigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ function InitialPeriodRotateTrigger(options) {
function shutdown() {
}

function checkIfRotationNeeded(ctime, now) {
var nextRot = ctime;
var lastRot = nextRot;
function checkIfRotationNeeded(birthtime, now) {
var nextRot = birthtime;
var lastRot = birthtime;
while (nextRot < now) {
lastRot = nextRot;
nextRot = nextRotTime(lastRot, periodScope, periodNum);
}

return { needsRotation: lastRot != ctime, rotateTo: lastRot };
return { needsRotation: lastRot != birthtime, rotateTo: lastRot };
}

function newFile(data) {
if (rotatingoldfiles) {
// First setup, see if the file is old and needs rotating
rotatingoldfiles = false;
var rotation = checkIfRotationNeeded(data.path, Date.now());
var rotation = checkIfRotationNeeded(data.stats.birthtime.getTime(), new Date().getTime());
if (rotation.needsRotation) {
// The current file is old enough to need a rotation.
base.emit('rotate', {date: rotation.rotateTo});
Expand Down
47 changes: 46 additions & 1 deletion test/functionality.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ function runTest(name, options, next) {
});

var i = 1;
var offset = (options.batch.startAt || 1) - 1;
var batch = _.extend({}, { size: 10 }, options.batch);

// Prior to node v4, high load scenarios (like these tests) can starve timer events
var logdelay = batch.delay || (semver.lt(process.version, '4.0.0') ? 20 : 0);

var ia = setInterval(function () {
for (var j = 0; j < batch.size; j += 1) {
log.info({node: 'a', i: i});
log.info({node: 'a', i: i + offset});
i += 1;

if (typeof (batch.iterations) !== 'undefined' && i >= batch.iterations) {
Expand Down Expand Up @@ -393,6 +394,45 @@ function totalfiles(template) {
}
}

function rotateExisting(template) {
return function (next) {
var name = 'testlogs/' + 'rotateExisting-' + template;

async.series([
function (next) { rmdir(name, ignoreMissing(next)); },
function (next) { mkdirp(name, next); },
function createBaseFile(next) { runTest (name, {
stream: { path: name + '/' + template + '.log', period: '1000ms', rotateExisting: true },
batch: { startAt: 1, iterations: 100 }
}, next); },
function waitLongTime(next) {
setTimeout(next, 2000);
},
function writeToNewFile(next) { runTest (name, {
stream: { path: name + '/' + template + '.log', period: '1000ms', rotateExisting: true },
batch: { startAt: 100, iterations: 101 }
}, next); },
function waitShortTime(next) {
setTimeout(next, 100);
},
function writeToExistingFile(next) { runTest (name, {
stream: { path: name + '/' + template + '.log', period: '1000ms', rotateExisting: true },
batch: { startAt: 200, iterations: 101 }
}, next); },
function (next) {
checkFileConsistency(name, {first: 1, last: 300}, next);
},
function (next) {
var files = fs.readdirSync(name);
assert.equal(2, files.length);
console.log(name.replace('%d', '%%d'), 'passed');
next();
},
function (next) { rmdir(name, ignoreMissing(next)); }
], next);
}
}

function shorthandperiod(template) {
return function (next) {
var name = 'testlogs/' + 'shorthandperiod-' + template;
Expand Down Expand Up @@ -623,6 +663,11 @@ mkdirp('testlogs', function () {
toosmallthresholdstillgetswrites('test-%Y-%m-%d'),
toosmallthresholdstillgetswrites('test-%Y-%m-%d-%H-%M-%S'),
toosmallthresholdstillgetswrites('test-%N-%Y-%m-%d'),
rotateExisting('test'),
rotateExisting('test-%N'),
rotateExisting('test-%Y-%m-%d'),
rotateExisting('test-%Y-%m-%d-%H-%M-%S'),
rotateExisting('test-%N-%Y-%m-%d'),

checkrotationofoldfile,
checkrotationofnewfile,
Expand Down

0 comments on commit ad5dee9

Please sign in to comment.