extracted streams, date-format into separate modules
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
var streams = require('../streams')
|
var streams = require('streamroller')
|
||||||
, layouts = require('../layouts')
|
, layouts = require('../layouts')
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
, os = require('os')
|
, os = require('os')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
var layouts = require('../layouts')
|
var layouts = require('../layouts')
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
, fs = require('fs')
|
, fs = require('fs')
|
||||||
, streams = require('../streams')
|
, streams = require('streamroller')
|
||||||
, os = require('os')
|
, os = require('os')
|
||||||
, eol = os.EOL || '\n'
|
, eol = os.EOL || '\n'
|
||||||
, openFiles = [];
|
, openFiles = [];
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.ISO8601_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS";
|
|
||||||
exports.ISO8601_WITH_TZ_OFFSET_FORMAT = "yyyy-MM-ddThh:mm:ssO";
|
|
||||||
exports.DATETIME_FORMAT = "dd MM yyyy hh:mm:ss.SSS";
|
|
||||||
exports.ABSOLUTETIME_FORMAT = "hh:mm:ss.SSS";
|
|
||||||
|
|
||||||
function padWithZeros(vNumber, width) {
|
|
||||||
var numAsString = vNumber + "";
|
|
||||||
while (numAsString.length < width) {
|
|
||||||
numAsString = "0" + numAsString;
|
|
||||||
}
|
|
||||||
return numAsString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addZero(vNumber) {
|
|
||||||
return padWithZeros(vNumber, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the TimeOffest
|
|
||||||
* Thanks to http://www.svendtofte.com/code/date_format/
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function offset(date) {
|
|
||||||
// Difference to Greenwich time (GMT) in hours
|
|
||||||
var os = Math.abs(date.getTimezoneOffset());
|
|
||||||
var h = String(Math.floor(os/60));
|
|
||||||
var m = String(os%60);
|
|
||||||
if (h.length == 1) {
|
|
||||||
h = "0" + h;
|
|
||||||
}
|
|
||||||
if (m.length == 1) {
|
|
||||||
m = "0" + m;
|
|
||||||
}
|
|
||||||
return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.asString = function(/*format,*/ date) {
|
|
||||||
var format = exports.ISO8601_FORMAT;
|
|
||||||
if (typeof(date) === "string") {
|
|
||||||
format = arguments[0];
|
|
||||||
date = arguments[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
var vDay = addZero(date.getDate());
|
|
||||||
var vMonth = addZero(date.getMonth()+1);
|
|
||||||
var vYearLong = addZero(date.getFullYear());
|
|
||||||
var vYearShort = addZero(date.getFullYear().toString().substring(2,4));
|
|
||||||
var vYear = (format.indexOf("yyyy") > -1 ? vYearLong : vYearShort);
|
|
||||||
var vHour = addZero(date.getHours());
|
|
||||||
var vMinute = addZero(date.getMinutes());
|
|
||||||
var vSecond = addZero(date.getSeconds());
|
|
||||||
var vMillisecond = padWithZeros(date.getMilliseconds(), 3);
|
|
||||||
var vTimeZone = offset(date);
|
|
||||||
var formatted = format
|
|
||||||
.replace(/dd/g, vDay)
|
|
||||||
.replace(/MM/g, vMonth)
|
|
||||||
.replace(/y{1,4}/g, vYear)
|
|
||||||
.replace(/hh/g, vHour)
|
|
||||||
.replace(/mm/g, vMinute)
|
|
||||||
.replace(/ss/g, vSecond)
|
|
||||||
.replace(/SSS/g, vMillisecond)
|
|
||||||
.replace(/O/g, vTimeZone);
|
|
||||||
return formatted;
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
var dateFormat = require('./date_format')
|
var dateFormat = require('date-format')
|
||||||
, os = require('os')
|
, os = require('os')
|
||||||
, eol = os.EOL || '\n'
|
, eol = os.EOL || '\n'
|
||||||
, util = require('util')
|
, util = require('util')
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var fs = require('fs')
|
|
||||||
, stream
|
|
||||||
, debug = require('debug')('log4js:BaseRollingFileStream')
|
|
||||||
, util = require('util')
|
|
||||||
, semver = require('semver');
|
|
||||||
|
|
||||||
if (semver.satisfies(process.version, '>=0.10.0')) {
|
|
||||||
stream = require('stream');
|
|
||||||
} else {
|
|
||||||
stream = require('readable-stream');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = BaseRollingFileStream;
|
|
||||||
|
|
||||||
function BaseRollingFileStream(filename, options) {
|
|
||||||
debug("In BaseRollingFileStream");
|
|
||||||
this.filename = filename;
|
|
||||||
this.options = options || { encoding: 'utf8', mode: parseInt('0644', 8), flags: 'a' };
|
|
||||||
this.currentSize = 0;
|
|
||||||
|
|
||||||
function currentFileSize(file) {
|
|
||||||
var fileSize = 0;
|
|
||||||
try {
|
|
||||||
fileSize = fs.statSync(file).size;
|
|
||||||
} catch (e) {
|
|
||||||
// file does not exist
|
|
||||||
}
|
|
||||||
return fileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
function throwErrorIfArgumentsAreNotValid() {
|
|
||||||
if (!filename) {
|
|
||||||
throw new Error("You must specify a filename");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throwErrorIfArgumentsAreNotValid();
|
|
||||||
debug("Calling BaseRollingFileStream.super");
|
|
||||||
BaseRollingFileStream.super_.call(this);
|
|
||||||
this.openTheStream();
|
|
||||||
this.currentSize = currentFileSize(this.filename);
|
|
||||||
}
|
|
||||||
util.inherits(BaseRollingFileStream, stream.Writable);
|
|
||||||
|
|
||||||
BaseRollingFileStream.prototype._write = function(chunk, encoding, callback) {
|
|
||||||
var that = this;
|
|
||||||
function writeTheChunk() {
|
|
||||||
debug("writing the chunk to the underlying stream");
|
|
||||||
that.currentSize += chunk.length;
|
|
||||||
that.theStream.write(chunk, encoding, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("in _write");
|
|
||||||
|
|
||||||
if (this.shouldRoll()) {
|
|
||||||
this.currentSize = 0;
|
|
||||||
this.roll(this.filename, writeTheChunk);
|
|
||||||
} else {
|
|
||||||
writeTheChunk();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BaseRollingFileStream.prototype.openTheStream = function(cb) {
|
|
||||||
debug("opening the underlying stream");
|
|
||||||
this.theStream = fs.createWriteStream(this.filename, this.options);
|
|
||||||
if (cb) {
|
|
||||||
this.theStream.on("open", cb);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
BaseRollingFileStream.prototype.closeTheStream = function(cb) {
|
|
||||||
debug("closing the underlying stream");
|
|
||||||
this.theStream.end(cb);
|
|
||||||
};
|
|
||||||
|
|
||||||
BaseRollingFileStream.prototype.shouldRoll = function() {
|
|
||||||
return false; // default behaviour is never to roll
|
|
||||||
};
|
|
||||||
|
|
||||||
BaseRollingFileStream.prototype.roll = function(filename, callback) {
|
|
||||||
callback(); // default behaviour is not to do anything
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var BaseRollingFileStream = require('./BaseRollingFileStream')
|
|
||||||
, debug = require('debug')('log4js:DateRollingFileStream')
|
|
||||||
, format = require('../date_format')
|
|
||||||
, async = require('async')
|
|
||||||
, fs = require('fs')
|
|
||||||
, util = require('util');
|
|
||||||
|
|
||||||
module.exports = DateRollingFileStream;
|
|
||||||
|
|
||||||
function DateRollingFileStream(filename, pattern, options, now) {
|
|
||||||
debug("Now is ", now);
|
|
||||||
if (pattern && typeof(pattern) === 'object') {
|
|
||||||
now = options;
|
|
||||||
options = pattern;
|
|
||||||
pattern = null;
|
|
||||||
}
|
|
||||||
this.pattern = pattern || '.yyyy-MM-dd';
|
|
||||||
this.now = now || Date.now;
|
|
||||||
this.lastTimeWeWroteSomething = format.asString(this.pattern, new Date(this.now()));
|
|
||||||
this.baseFilename = filename;
|
|
||||||
this.alwaysIncludePattern = false;
|
|
||||||
|
|
||||||
if (options) {
|
|
||||||
if (options.alwaysIncludePattern) {
|
|
||||||
this.alwaysIncludePattern = true;
|
|
||||||
filename = this.baseFilename + this.lastTimeWeWroteSomething;
|
|
||||||
}
|
|
||||||
delete options.alwaysIncludePattern;
|
|
||||||
if (Object.keys(options).length === 0) {
|
|
||||||
options = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug("this.now is ", this.now, ", now is ", now);
|
|
||||||
|
|
||||||
DateRollingFileStream.super_.call(this, filename, options);
|
|
||||||
}
|
|
||||||
util.inherits(DateRollingFileStream, BaseRollingFileStream);
|
|
||||||
|
|
||||||
DateRollingFileStream.prototype.shouldRoll = function() {
|
|
||||||
var lastTime = this.lastTimeWeWroteSomething,
|
|
||||||
thisTime = format.asString(this.pattern, new Date(this.now()));
|
|
||||||
|
|
||||||
debug("DateRollingFileStream.shouldRoll with now = ",
|
|
||||||
this.now(), ", thisTime = ", thisTime, ", lastTime = ", lastTime);
|
|
||||||
|
|
||||||
this.lastTimeWeWroteSomething = thisTime;
|
|
||||||
this.previousTime = lastTime;
|
|
||||||
|
|
||||||
return thisTime !== lastTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
DateRollingFileStream.prototype.roll = function(filename, callback) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
debug("Starting roll");
|
|
||||||
|
|
||||||
if (this.alwaysIncludePattern) {
|
|
||||||
this.filename = this.baseFilename + this.lastTimeWeWroteSomething;
|
|
||||||
async.series([
|
|
||||||
this.closeTheStream.bind(this),
|
|
||||||
this.openTheStream.bind(this)
|
|
||||||
], callback);
|
|
||||||
} else {
|
|
||||||
var newFilename = this.baseFilename + this.previousTime;
|
|
||||||
async.series([
|
|
||||||
this.closeTheStream.bind(this),
|
|
||||||
deleteAnyExistingFile,
|
|
||||||
renameTheCurrentFile,
|
|
||||||
this.openTheStream.bind(this)
|
|
||||||
], callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteAnyExistingFile(cb) {
|
|
||||||
//on windows, you can get a EEXIST error if you rename a file to an existing file
|
|
||||||
//so, we'll try to delete the file we're renaming to first
|
|
||||||
fs.unlink(newFilename, function (err) {
|
|
||||||
//ignore err: if we could not delete, it's most likely that it doesn't exist
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameTheCurrentFile(cb) {
|
|
||||||
debug("Renaming the ", filename, " -> ", newFilename);
|
|
||||||
fs.rename(filename, newFilename, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var BaseRollingFileStream = require('./BaseRollingFileStream')
|
|
||||||
, debug = require('debug')('log4js:RollingFileStream')
|
|
||||||
, util = require('util')
|
|
||||||
, path = require('path')
|
|
||||||
, fs = require('fs')
|
|
||||||
, async = require('async');
|
|
||||||
|
|
||||||
module.exports = RollingFileStream;
|
|
||||||
|
|
||||||
function RollingFileStream (filename, size, backups, options) {
|
|
||||||
this.size = size;
|
|
||||||
this.backups = backups || 1;
|
|
||||||
|
|
||||||
function throwErrorIfArgumentsAreNotValid() {
|
|
||||||
if (!filename || !size || size <= 0) {
|
|
||||||
throw new Error("You must specify a filename and file size");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throwErrorIfArgumentsAreNotValid();
|
|
||||||
|
|
||||||
RollingFileStream.super_.call(this, filename, options);
|
|
||||||
}
|
|
||||||
util.inherits(RollingFileStream, BaseRollingFileStream);
|
|
||||||
|
|
||||||
RollingFileStream.prototype.shouldRoll = function() {
|
|
||||||
debug("should roll with current size %d, and max size %d", this.currentSize, this.size);
|
|
||||||
return this.currentSize >= this.size;
|
|
||||||
};
|
|
||||||
|
|
||||||
RollingFileStream.prototype.roll = function(filename, callback) {
|
|
||||||
var that = this,
|
|
||||||
nameMatcher = new RegExp('^' + path.basename(filename));
|
|
||||||
|
|
||||||
function justTheseFiles (item) {
|
|
||||||
return nameMatcher.test(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
function index(filename_) {
|
|
||||||
return parseInt(filename_.substring((path.basename(filename) + '.').length), 10) || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function byIndex(a, b) {
|
|
||||||
if (index(a) > index(b)) {
|
|
||||||
return 1;
|
|
||||||
} else if (index(a) < index(b) ) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function increaseFileIndex (fileToRename, cb) {
|
|
||||||
var idx = index(fileToRename);
|
|
||||||
debug('Index of ', fileToRename, ' is ', idx);
|
|
||||||
if (idx < that.backups) {
|
|
||||||
//on windows, you can get a EEXIST error if you rename a file to an existing file
|
|
||||||
//so, we'll try to delete the file we're renaming to first
|
|
||||||
fs.unlink(filename + '.' + (idx+1), function (err) {
|
|
||||||
//ignore err: if we could not delete, it's most likely that it doesn't exist
|
|
||||||
debug('Renaming ', fileToRename, ' -> ', filename, '.', (idx+1));
|
|
||||||
fs.rename(path.join(path.dirname(filename), fileToRename), filename + '.' + (idx + 1), cb);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renameTheFiles(cb) {
|
|
||||||
//roll the backups (rename file.n to file.n+1, where n <= numBackups)
|
|
||||||
debug("Renaming the old files");
|
|
||||||
fs.readdir(path.dirname(filename), function (err, files) {
|
|
||||||
async.forEachSeries(
|
|
||||||
files.filter(justTheseFiles).sort(byIndex).reverse(),
|
|
||||||
increaseFileIndex,
|
|
||||||
cb
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
debug("Rolling, rolling, rolling");
|
|
||||||
async.series([
|
|
||||||
this.closeTheStream.bind(this),
|
|
||||||
renameTheFiles,
|
|
||||||
this.openTheStream.bind(this)
|
|
||||||
], callback);
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
exports.RollingFileStream = require('./RollingFileStream');
|
|
||||||
exports.DateRollingFileStream = require('./DateRollingFileStream');
|
|
||||||
@@ -31,7 +31,9 @@
|
|||||||
"async": "0.1.15",
|
"async": "0.1.15",
|
||||||
"semver": "~1.1.4",
|
"semver": "~1.1.4",
|
||||||
"readable-stream": "~1.0.2",
|
"readable-stream": "~1.0.2",
|
||||||
"debug": "~0.7.2"
|
"debug": "~0.7.2",
|
||||||
|
"streamroller": "0.0.0",
|
||||||
|
"date-format": "0.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"sandboxed-module": "0.1.3",
|
"sandboxed-module": "0.1.3",
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ describe('../lib/appenders/dateFile', function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
requires: {
|
requires: {
|
||||||
'../streams': {
|
'streamroller': {
|
||||||
DateRollingFileStream: function(filename) {
|
DateRollingFileStream: function(filename) {
|
||||||
openedFiles.push(filename);
|
openedFiles.push(filename);
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ describe('../lib/appenders/dateFile', function() {
|
|||||||
|
|
||||||
before(function(done) {
|
before(function(done) {
|
||||||
var log4js = require('../lib/log4js')
|
var log4js = require('../lib/log4js')
|
||||||
, format = require('../lib/date_format')
|
, format = require('date-format')
|
||||||
, logger
|
, logger
|
||||||
, options = {
|
, options = {
|
||||||
"appenders": {
|
"appenders": {
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var should = require('should')
|
|
||||||
, dateFormat = require('../lib/date_format');
|
|
||||||
|
|
||||||
describe('date_format', function() {
|
|
||||||
var date = new Date(2010, 0, 11, 14, 31, 30, 5);
|
|
||||||
|
|
||||||
it('should format a date as string using a pattern', function() {
|
|
||||||
dateFormat.asString(dateFormat.DATETIME_FORMAT, date).should.eql("11 01 2010 14:31:30.005");
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should default to the ISO8601 format', function() {
|
|
||||||
dateFormat.asString(date).should.eql('2010-01-11 14:31:30.005');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide a ISO8601 with timezone offset format', function() {
|
|
||||||
date.getTimezoneOffset = function() { return -660; };
|
|
||||||
dateFormat.asString(
|
|
||||||
dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT,
|
|
||||||
date
|
|
||||||
).should.eql(
|
|
||||||
"2010-01-11T14:31:30+1100"
|
|
||||||
);
|
|
||||||
|
|
||||||
date.getTimezoneOffset = function() { return 120; };
|
|
||||||
dateFormat.asString(
|
|
||||||
dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT,
|
|
||||||
date
|
|
||||||
).should.eql(
|
|
||||||
"2010-01-11T14:31:30-0200"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide a just-the-time format', function() {
|
|
||||||
dateFormat.asString(dateFormat.ABSOLUTETIME_FORMAT, date).should.eql('14:31:30.005');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide a custom format', function() {
|
|
||||||
date.getTimezoneOffset = function() { return 120; };
|
|
||||||
dateFormat.asString("O.SSS.ss.mm.hh.dd.MM.yy", date).should.eql('-0200.005.30.31.14.11.01.10');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -62,7 +62,7 @@ describe('log4js fileAppender', function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
requires: {
|
requires: {
|
||||||
'../streams': {
|
'streamroller': {
|
||||||
RollingFileStream: function(filename) {
|
RollingFileStream: function(filename) {
|
||||||
openedFiles.push(filename);
|
openedFiles.push(filename);
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ describe('log4js fileAppender', function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
requires: {
|
requires: {
|
||||||
'../streams': {
|
'streamroller': {
|
||||||
RollingFileStream: function(filename) {
|
RollingFileStream: function(filename) {
|
||||||
|
|
||||||
this.end = function() {};
|
this.end = function() {};
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var should = require('should')
|
|
||||||
, fs = require('fs')
|
|
||||||
, sandbox = require('sandboxed-module');
|
|
||||||
|
|
||||||
describe('../../lib/streams/BaseRollingFileStream', function() {
|
|
||||||
describe('when node version < 0.10.0', function() {
|
|
||||||
it('should use readable-stream to maintain compatibility', function() {
|
|
||||||
|
|
||||||
var streamLib = sandbox.load(
|
|
||||||
'../../lib/streams/BaseRollingFileStream',
|
|
||||||
{
|
|
||||||
globals: {
|
|
||||||
process: {
|
|
||||||
version: '0.8.11'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
requires: {
|
|
||||||
'readable-stream': {
|
|
||||||
Writable: function() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
streamLib.required.should.have.property('readable-stream');
|
|
||||||
streamLib.required.should.not.have.property('stream');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when node version > 0.10.0', function() {
|
|
||||||
it('should use the core stream module', function() {
|
|
||||||
var streamLib = sandbox.load(
|
|
||||||
'../../lib/streams/BaseRollingFileStream',
|
|
||||||
{
|
|
||||||
globals: {
|
|
||||||
process: {
|
|
||||||
version: '0.10.1'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
requires: {
|
|
||||||
'stream': {
|
|
||||||
Writable: function() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
streamLib.required.should.have.property('stream');
|
|
||||||
streamLib.required.should.not.have.property('readable-stream');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when no filename is passed', function() {
|
|
||||||
it('should throw an error', function() {
|
|
||||||
var BaseRollingFileStream = require('../../lib/streams/BaseRollingFileStream');
|
|
||||||
(function() {
|
|
||||||
new BaseRollingFileStream();
|
|
||||||
}).should.throw();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('default behaviour', function() {
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
before(function() {
|
|
||||||
var BaseRollingFileStream = require('../../lib/streams/BaseRollingFileStream');
|
|
||||||
stream = new BaseRollingFileStream('basetest.log');
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
fs.unlink('basetest.log', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not want to roll', function() {
|
|
||||||
stream.shouldRoll().should.eql(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not roll', function() {
|
|
||||||
var cbCalled = false;
|
|
||||||
//just calls the callback straight away, no async calls
|
|
||||||
stream.roll('basetest.log', function() { cbCalled = true; });
|
|
||||||
cbCalled.should.eql(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var should = require('should')
|
|
||||||
, fs = require('fs')
|
|
||||||
, semver = require('semver')
|
|
||||||
, streams
|
|
||||||
, DateRollingFileStream
|
|
||||||
, testTime = new Date(2012, 8, 12, 10, 37, 11);
|
|
||||||
|
|
||||||
if (semver.satisfies(process.version, '>=0.10.0')) {
|
|
||||||
streams = require('stream');
|
|
||||||
} else {
|
|
||||||
streams = require('readable-stream');
|
|
||||||
}
|
|
||||||
DateRollingFileStream = require('../../lib/streams').DateRollingFileStream;
|
|
||||||
|
|
||||||
function remove(filename, cb) {
|
|
||||||
fs.unlink(filename, function() { cb(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
function now() {
|
|
||||||
return testTime.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('DateRollingFileStream', function() {
|
|
||||||
describe('arguments', function() {
|
|
||||||
var stream = new DateRollingFileStream(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-1',
|
|
||||||
'yyyy-mm-dd.hh'
|
|
||||||
);
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-1', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should take a filename and a pattern and return a WritableStream', function() {
|
|
||||||
stream.filename.should.eql(__dirname + '/test-date-rolling-file-stream-1');
|
|
||||||
stream.pattern.should.eql('yyyy-mm-dd.hh');
|
|
||||||
stream.should.be.instanceOf(streams.Writable);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('with default settings for the underlying stream', function() {
|
|
||||||
stream.theStream.mode.should.eql(420);
|
|
||||||
stream.theStream.flags.should.eql('a');
|
|
||||||
//encoding is not available on the underlying stream
|
|
||||||
//assert.equal(stream.encoding, 'utf8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('default arguments', function() {
|
|
||||||
var stream = new DateRollingFileStream(__dirname + '/test-date-rolling-file-stream-2');
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-2', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have pattern of .yyyy-MM-dd', function() {
|
|
||||||
stream.pattern.should.eql('.yyyy-MM-dd');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with stream arguments', function() {
|
|
||||||
var stream = new DateRollingFileStream(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-3',
|
|
||||||
'yyyy-MM-dd',
|
|
||||||
{ mode: parseInt('0666', 8) }
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-3', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should pass them to the underlying stream', function() {
|
|
||||||
stream.theStream.mode.should.eql(parseInt('0666', 8));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with stream arguments but no pattern', function() {
|
|
||||||
var stream = new DateRollingFileStream(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-4',
|
|
||||||
{ mode: parseInt('0666', 8) }
|
|
||||||
);
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-4', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should pass them to the underlying stream', function() {
|
|
||||||
stream.theStream.mode.should.eql(parseInt('0666', 8));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use default pattern', function() {
|
|
||||||
stream.pattern.should.eql('.yyyy-MM-dd');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with a pattern of .yyyy-MM-dd', function() {
|
|
||||||
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
stream = new DateRollingFileStream(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-5', '.yyyy-MM-dd',
|
|
||||||
null,
|
|
||||||
now
|
|
||||||
);
|
|
||||||
stream.write("First message\n", 'utf8', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-5', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a file with the base name', function(done) {
|
|
||||||
fs.readFile(__dirname + '/test-date-rolling-file-stream-5', 'utf8', function(err, contents) {
|
|
||||||
contents.should.eql("First message\n");
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the day changes', function() {
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
testTime = new Date(2012, 8, 13, 0, 10, 12);
|
|
||||||
stream.write("Second message\n", 'utf8', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-5.2012-09-12', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the number of files', function() {
|
|
||||||
var files = [];
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
fs.readdir(__dirname, function(err, list) {
|
|
||||||
files = list;
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be two', function() {
|
|
||||||
files.filter(
|
|
||||||
function(file) {
|
|
||||||
return file.indexOf('test-date-rolling-file-stream-5') > -1;
|
|
||||||
}
|
|
||||||
).should.have.length(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the file without a date', function() {
|
|
||||||
it('should contain the second message', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-5', 'utf8',
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("Second message\n");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the file with the date', function() {
|
|
||||||
it('should contain the first message', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-5.2012-09-12', 'utf8',
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("First message\n");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with alwaysIncludePattern', function() {
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
testTime = new Date(2012, 8, 12, 0, 10, 12);
|
|
||||||
remove(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-pattern.2012-09-12',
|
|
||||||
function() {
|
|
||||||
stream = new DateRollingFileStream(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-pattern',
|
|
||||||
'.yyyy-MM-dd',
|
|
||||||
{ alwaysIncludePattern: true },
|
|
||||||
now
|
|
||||||
);
|
|
||||||
stream.write("First message\n", 'utf8', done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-pattern.2012-09-12', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a file with the pattern set', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-pattern.2012-09-12', 'utf8',
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("First message\n");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the day changes', function() {
|
|
||||||
before(function(done) {
|
|
||||||
testTime = new Date(2012, 8, 13, 0, 10, 12);
|
|
||||||
stream.write("Second message\n", 'utf8', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-date-rolling-file-stream-pattern.2012-09-13', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('the number of files', function() {
|
|
||||||
it('should be two', function(done) {
|
|
||||||
fs.readdir(__dirname, function(err, files) {
|
|
||||||
files.filter(
|
|
||||||
function(file) {
|
|
||||||
return file.indexOf('test-date-rolling-file-stream-pattern') > -1;
|
|
||||||
}
|
|
||||||
).should.have.length(2);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the file with the later date', function() {
|
|
||||||
it('should contain the second message', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-pattern.2012-09-13', 'utf8',
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("Second message\n");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the file with the date', function() {
|
|
||||||
it('should contain the first message', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-date-rolling-file-stream-pattern.2012-09-12', 'utf8',
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("First message\n");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var async = require('async')
|
|
||||||
, should = require('should')
|
|
||||||
, fs = require('fs')
|
|
||||||
, semver = require('semver')
|
|
||||||
, streams
|
|
||||||
, RollingFileStream;
|
|
||||||
|
|
||||||
if (semver.satisfies(process.version, '>=0.10.0')) {
|
|
||||||
streams = require('stream');
|
|
||||||
} else {
|
|
||||||
streams = require('readable-stream');
|
|
||||||
}
|
|
||||||
RollingFileStream = require('../../lib/streams').RollingFileStream;
|
|
||||||
|
|
||||||
function remove(filename, cb) {
|
|
||||||
fs.unlink(filename, function(err) { cb(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
function create(filename, cb) {
|
|
||||||
fs.writeFile(filename, "test file", cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('RollingFileStream', function() {
|
|
||||||
|
|
||||||
describe('arguments', function() {
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
remove(__dirname + "/test-rolling-file-stream", function() {
|
|
||||||
stream = new RollingFileStream("test-rolling-file-stream", 1024, 5);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + "/test-rolling-file-stream", done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should take a filename, file size (bytes), no. backups, return Writable', function() {
|
|
||||||
stream.should.be.an.instanceOf(streams.Writable);
|
|
||||||
stream.filename.should.eql("test-rolling-file-stream");
|
|
||||||
stream.size.should.eql(1024);
|
|
||||||
stream.backups.should.eql(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should apply default settings to the underlying stream', function() {
|
|
||||||
stream.theStream.mode.should.eql(420);
|
|
||||||
stream.theStream.flags.should.eql('a');
|
|
||||||
//encoding isn't a property on the underlying stream
|
|
||||||
//assert.equal(stream.theStream.encoding, 'utf8');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with stream arguments', function() {
|
|
||||||
it('should pass them to the underlying stream', function() {
|
|
||||||
var stream = new RollingFileStream(
|
|
||||||
'test-rolling-file-stream',
|
|
||||||
1024,
|
|
||||||
5,
|
|
||||||
{ mode: parseInt('0666', 8) }
|
|
||||||
);
|
|
||||||
stream.theStream.mode.should.eql(parseInt('0666', 8));
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + '/test-rolling-file-stream', done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('without size', function() {
|
|
||||||
it('should throw an error', function() {
|
|
||||||
(function() {
|
|
||||||
new RollingFileStream(__dirname + "/test-rolling-file-stream");
|
|
||||||
}).should.throw();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('without number of backups', function() {
|
|
||||||
it('should default to 1 backup', function() {
|
|
||||||
var stream = new RollingFileStream(__dirname + "/test-rolling-file-stream", 1024);
|
|
||||||
stream.backups.should.eql(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + "/test-rolling-file-stream", done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('writing less than the file size', function() {
|
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
remove(__dirname + "/test-rolling-file-stream-write-less", function() {
|
|
||||||
var stream = new RollingFileStream(
|
|
||||||
__dirname + "/test-rolling-file-stream-write-less",
|
|
||||||
100
|
|
||||||
);
|
|
||||||
stream.write("cheese", "utf8", function() {
|
|
||||||
stream.end(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
remove(__dirname + "/test-rolling-file-stream-write-less", done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write to the file', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + "/test-rolling-file-stream-write-less", "utf8",
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql("cheese");
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write one file', function(done) {
|
|
||||||
fs.readdir(__dirname, function(err, files) {
|
|
||||||
files.filter(
|
|
||||||
function(file) { return file.indexOf('test-rolling-file-stream-write-less') > -1; }
|
|
||||||
).should.have.length(1);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('writing more than the file size', function() {
|
|
||||||
before(function(done) {
|
|
||||||
async.forEach(
|
|
||||||
[
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more",
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more.1"
|
|
||||||
],
|
|
||||||
remove,
|
|
||||||
function() {
|
|
||||||
var stream = new RollingFileStream(
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more",
|
|
||||||
45
|
|
||||||
);
|
|
||||||
async.forEachSeries(
|
|
||||||
[0, 1, 2, 3, 4, 5, 6],
|
|
||||||
function(i, cb) {
|
|
||||||
stream.write(i +".cheese\n", "utf8", cb);
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
stream.end(done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
async.forEach(
|
|
||||||
[
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more",
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more.1"
|
|
||||||
],
|
|
||||||
remove,
|
|
||||||
done
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write two files' , function(done) {
|
|
||||||
fs.readdir(__dirname, function(err, files) {
|
|
||||||
files.filter(
|
|
||||||
function(file) {
|
|
||||||
return file.indexOf('test-rolling-file-stream-write-more') > -1;
|
|
||||||
}
|
|
||||||
).should.have.length(2);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write the last two log messages to the first file', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + "/test-rolling-file-stream-write-more", "utf8",
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql('5.cheese\n6.cheese\n');
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should write the first five log messages to the second file', function(done) {
|
|
||||||
fs.readFile(
|
|
||||||
__dirname + '/test-rolling-file-stream-write-more.1', "utf8",
|
|
||||||
function(err, contents) {
|
|
||||||
contents.should.eql('0.cheese\n1.cheese\n2.cheese\n3.cheese\n4.cheese\n');
|
|
||||||
done(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when many files already exist', function() {
|
|
||||||
before(function(done) {
|
|
||||||
async.forEach(
|
|
||||||
[
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.11',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.20',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.-1',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.1.1',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.1'
|
|
||||||
],
|
|
||||||
remove,
|
|
||||||
function(err) {
|
|
||||||
if (err) done(err);
|
|
||||||
|
|
||||||
async.forEach(
|
|
||||||
[
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.11',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.20',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.-1',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.1.1',
|
|
||||||
__dirname + '/test-rolling-stream-with-existing-files.1'
|
|
||||||
],
|
|
||||||
create,
|
|
||||||
function(err) {
|
|
||||||
if (err) done(err);
|
|
||||||
|
|
||||||
var stream = new RollingFileStream(
|
|
||||||
__dirname + "/test-rolling-stream-with-existing-files",
|
|
||||||
45,
|
|
||||||
5
|
|
||||||
);
|
|
||||||
|
|
||||||
async.forEachSeries(
|
|
||||||
[0, 1, 2, 3, 4, 5, 6],
|
|
||||||
function(i, cb) {
|
|
||||||
stream.write(i +".cheese\n", "utf8", cb);
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
stream.end(done);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
async.forEach([
|
|
||||||
'test-rolling-stream-with-existing-files',
|
|
||||||
'test-rolling-stream-with-existing-files.1',
|
|
||||||
'test-rolling-stream-with-existing-files.2',
|
|
||||||
'test-rolling-stream-with-existing-files.11',
|
|
||||||
'test-rolling-stream-with-existing-files.20'
|
|
||||||
], remove, done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should roll the files', function(done) {
|
|
||||||
fs.readdir(__dirname, function(err, files) {
|
|
||||||
files.should.include('test-rolling-stream-with-existing-files');
|
|
||||||
files.should.include('test-rolling-stream-with-existing-files.1');
|
|
||||||
files.should.include('test-rolling-stream-with-existing-files.2');
|
|
||||||
files.should.include('test-rolling-stream-with-existing-files.11');
|
|
||||||
files.should.include('test-rolling-stream-with-existing-files.20');
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user