rotating-file: auto rotate file on startup if needed

Fixes #239
master
Paul Milham 2015-12-28 14:01:11 -07:00 committed by Trent Mick
parent bb1ab77c3e
commit 46d2be4642
1 changed files with 50 additions and 17 deletions

View File

@ -1168,8 +1168,7 @@ if (mv) {
RotatingFileStream = function RotatingFileStream(options) {
this.path = options.path;
this.stream = fs.createWriteStream(this.path,
{flags: 'a', encoding: 'utf8'});
this.count = (options.count == null ? 10 : options.count);
assert.equal(typeof (this.count), 'number',
format('rotating-file stream "count" is not a number: %j (%s) in %j',
@ -1206,6 +1205,22 @@ RotatingFileStream = function RotatingFileStream(options) {
this.periodScope = 'd';
}
var lastModified = null;
try {
var fileInfo = fs.statSync(this.path);
lastModified = fileInfo.mtime.getTime();
}
catch (err) {
// file doesn't exist
}
var rotateAfterOpen = false;
if (lastModified) {
var lastRotTime = this._calcRotTime(0);
if (lastModified < lastRotTime) {
rotateAfterOpen = true;
}
}
// TODO: template support for backup files
// template: <path to which to rotate>
// default is %P.%n
@ -1222,15 +1237,21 @@ RotatingFileStream = function RotatingFileStream(options) {
// prior art? Want to avoid ':' in
// filenames (illegal on Windows for one).
this.stream = fs.createWriteStream(this.path,
{flags: 'a', encoding: 'utf8'});
this.rotQueue = [];
this.rotating = false;
if (rotateAfterOpen) {
this.rotate();
}
this._setupNextRot();
}
util.inherits(RotatingFileStream, EventEmitter);
RotatingFileStream.prototype._setupNextRot = function () {
this.rotAt = this._nextRotTime();
this.rotAt = this._calcRotTime(1);
this._setRotationTimer();
}
@ -1251,10 +1272,11 @@ RotatingFileStream.prototype._setRotationTimer = function () {
}
}
RotatingFileStream.prototype._nextRotTime = function _nextRotTime(first) {
RotatingFileStream.prototype._calcRotTime =
function _calcRotTime(periodOffset) {
var _DEBUG = false;
if (_DEBUG)
console.log('-- _nextRotTime: %s%s', this.periodNum, this.periodScope);
console.log('-- _calcRotTime: %s%s', this.periodNum, this.periodScope);
var d = new Date();
if (_DEBUG) console.log(' now local: %s', d);
@ -1264,54 +1286,65 @@ RotatingFileStream.prototype._nextRotTime = function _nextRotTime(first) {
case 'ms':
// Hidden millisecond period for debugging.
if (this.rotAt) {
rotAt = this.rotAt + this.periodNum;
rotAt = this.rotAt + this.periodNum * periodOffset;
} else {
rotAt = Date.now() + this.periodNum;
rotAt = Date.now() + this.periodNum * periodOffset;
}
break;
case 'h':
if (this.rotAt) {
rotAt = this.rotAt + this.periodNum * 60 * 60 * 1000;
rotAt = this.rotAt + this.periodNum * 60 * 60 * 1000 * periodOffset;
} else {
// First time: top of the next hour.
rotAt = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(),
d.getUTCDate(), d.getUTCHours() + 1);
d.getUTCDate(), d.getUTCHours() + periodOffset);
}
break;
case 'd':
if (this.rotAt) {
rotAt = this.rotAt + this.periodNum * 24 * 60 * 60 * 1000;
rotAt = this.rotAt + this.periodNum * 24 * 60 * 60 * 1000
* periodOffset;
} else {
// First time: start of tomorrow (i.e. at the coming midnight) UTC.
rotAt = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(),
d.getUTCDate() + 1);
d.getUTCDate() + periodOffset);
}
break;
case 'w':
// Currently, always on Sunday morning at 00:00:00 (UTC).
if (this.rotAt) {
rotAt = this.rotAt + this.periodNum * 7 * 24 * 60 * 60 * 1000;
rotAt = this.rotAt + this.periodNum * 7 * 24 * 60 * 60 * 1000
* periodOffset;
} else {
// First time: this coming Sunday.
var dayOffset = (7 - d.getUTCDay());
if (periodOffset < 1) {
dayOffset = -d.getUTCDay();
}
if (periodOffset > 1 || periodOffset < -1) {
dayOffset += 7 * periodOffset;
}
rotAt = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(),
d.getUTCDate() + (7 - d.getUTCDay()));
d.getUTCDate() + dayOffset);
}
break;
case 'm':
if (this.rotAt) {
rotAt = Date.UTC(d.getUTCFullYear(),
d.getUTCMonth() + this.periodNum, 1);
d.getUTCMonth() + this.periodNum * periodOffset, 1);
} else {
// First time: the start of the next month.
rotAt = Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);
rotAt = Date.UTC(d.getUTCFullYear(),
d.getUTCMonth() + periodOffset, 1);
}
break;
case 'y':
if (this.rotAt) {
rotAt = Date.UTC(d.getUTCFullYear() + this.periodNum, 0, 1);
rotAt = Date.UTC(d.getUTCFullYear() + this.periodNum * periodOffset,
0, 1);
} else {
// First time: the start of the next year.
rotAt = Date.UTC(d.getUTCFullYear() + 1, 0, 1);
rotAt = Date.UTC(d.getUTCFullYear() + periodOffset, 0, 1);
}
break;
default: