rotating-file-stream
Advanced tools
Comparing version 1.0.5 to 1.1.0
107
compress.js
@@ -9,2 +9,75 @@ "use strict"; | ||
function classical(count) { | ||
var prevName = count == 1 ? this.name : this.generator(count - 1); | ||
var thisName = this.generator(count); | ||
var self = this; | ||
if(this.options.rotate == count) | ||
delete this.rotatedName; | ||
var callback = function(err) { | ||
if(err) | ||
return self.emit("error", err); | ||
self.open(); | ||
if(self.options.compress) | ||
self.compress(thisName); | ||
else { | ||
self.emit("rotated", self.rotatedName); | ||
self.interval(); | ||
} | ||
}; | ||
var doIt = function(done) { | ||
fs.rename(prevName, thisName, function(err) { | ||
if(err) { | ||
if(err.code != "ENOENT") | ||
return callback(err); | ||
return utils.makePath(thisName, function(err) { | ||
if(err) | ||
return callback(err); | ||
fs.rename(prevName, thisName, function(err) { | ||
if(err) | ||
return callback(err); | ||
process.nextTick(done); | ||
}); | ||
}); | ||
} | ||
process.nextTick(done); | ||
}); | ||
}; | ||
fs.stat(prevName, function(err) { | ||
if(! err) { | ||
if(! self.rotatedName) | ||
self.rotatedName = thisName; | ||
if(count != 1) | ||
return doIt(self.classical.bind(self, count - 1)); | ||
if(self.options.compress) | ||
return self.findName({}, true, function(err, name) { | ||
if(err) | ||
return callback(err); | ||
thisName = name; | ||
doIt(callback); | ||
}); | ||
return doIt(callback); | ||
} | ||
if(err.code != "ENOENT") | ||
return callback(err); | ||
self.classical(count - 1); | ||
}); | ||
} | ||
function compress(tmp) { | ||
@@ -29,3 +102,7 @@ var self = this; | ||
self.emit("rotated", name); | ||
if(self.options.rotate) | ||
self.emit("rotated", self.rotatedName); | ||
else | ||
self.emit("rotated", name); | ||
self.interval(); | ||
@@ -90,3 +167,3 @@ }); | ||
var name = this.name + "." + count + ".log"; | ||
var name = this.name + "." + count + ".rfs.tmp"; | ||
var self = this; | ||
@@ -96,3 +173,12 @@ | ||
try { | ||
name = this.generator(this.options.interval ? new Date(this.prev) : this.rotation, count + 1); | ||
var pars = [count + 1]; | ||
if(! this.options.rotate) { | ||
if(this.options.interval && ! this.options.rotationTime) | ||
pars.unshift(new Date(this.prev)); | ||
else | ||
pars.unshift(this.rotation); | ||
} | ||
name = this.generator.apply(this, pars); | ||
} | ||
@@ -104,3 +190,3 @@ catch(err) { | ||
fs.stat(name, function(err) { | ||
if((! err) || err.code != "ENOENT" ) { | ||
if((! err) || err.code != "ENOENT") { | ||
if(name in attempts) | ||
@@ -127,3 +213,3 @@ attempts[name]++; | ||
out.once("finish", callback); | ||
out.once("finish", process.nextTick.bind(process, callback)); | ||
@@ -153,7 +239,8 @@ inp.pipe(zip).pipe(out); | ||
module.exports = { | ||
compress: compress, | ||
external: external, | ||
findName: findName, | ||
gzip: gzip, | ||
touch: touch | ||
classical: classical, | ||
compress: compress, | ||
external: external, | ||
findName: findName, | ||
gzip: gzip, | ||
touch: touch | ||
}; |
35
index.js
@@ -14,16 +14,22 @@ "use strict"; | ||
if(! options) | ||
options = {}; | ||
else | ||
if(typeof options != "object") | ||
throw new Error("Don't know how to handle 'options' type: " + typeof options); | ||
utils.checkOptions(options); | ||
if(typeof filename == "function") | ||
this.generator = filename; | ||
else | ||
if(typeof filename == "string") | ||
this.generator = utils.createGenerator(filename); | ||
if(typeof filename == "string") { | ||
if(options.rotate) | ||
this.generator = utils.createClassical(filename); | ||
else | ||
this.generator = utils.createGenerator(filename); | ||
} | ||
else | ||
throw new Error("Don't know how to handle 'filename' type: " + typeof filename); | ||
if(! options) | ||
options = {}; | ||
else | ||
if(typeof options != "object") | ||
throw new Error("Don't know how to handle 'options' type: " + typeof options); | ||
if(options.path) { | ||
@@ -37,5 +43,12 @@ var generator = this.generator; | ||
utils.checkOptions(options); | ||
Writable.call(this, options.highWaterMark ? { highWaterMark: options.highWaterMark } : {} ); | ||
var opt = {}; | ||
if(options.highWaterMark) | ||
opt.highWaterMark = options.highWaterMark; | ||
if(options.mode) | ||
opt.mode = options.mode; | ||
Writable.call(this, opt); | ||
this.chunks = []; | ||
@@ -298,3 +311,3 @@ this.options = options; | ||
this._clear(); | ||
this._close(this.move.bind(this)); | ||
this._close(this.options.rotate ? this.classical.bind(this, this.options.rotate) : this.move.bind(this)); | ||
this.emit("rotation"); | ||
@@ -301,0 +314,0 @@ }; |
{ | ||
"name": "rotating-file-stream", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"description": "Opens a stream.Writable to a file rotated by interval and/or size. A logrotate alternative.", | ||
@@ -32,7 +32,7 @@ "engines": { | ||
"devDependencies": { | ||
"istanbul": "0.4.3", | ||
"jshint": "2.9.2", | ||
"mocha": "2.4.5", | ||
"mocha-istanbul": "0.2.0" | ||
"istanbul": "0.4.5", | ||
"jshint": "2.9.3", | ||
"mocha": "3.1.2", | ||
"mocha-istanbul": "0.3.0" | ||
} | ||
} |
@@ -11,2 +11,7 @@ # rotating-file-stream | ||
### Description | ||
Creates a [stream.Writable](https://nodejs.org/api/stream.html#stream_class_stream_writable) to a file which is rotated. | ||
Rotation behaviour can be deeply customized; optionally, classical UNIX __logrotate__ behaviour can be used. | ||
### Usage | ||
@@ -87,2 +92,12 @@ | ||
__Note:__ | ||
If both rotation by interval and rotation by time are used, returned _rotated file name_ __must__ be function of both parameters _time_ and _index_. | ||
Alternatively, __rotationTime__ _option_ can be used (to see below). | ||
#### function filename(index) | ||
* index {Number} The progressive index of rotation. If __null__, the _not-rotated file name_ must be returned. | ||
If classical __logrotate__ behaviour is enabled _rotated file name_ is only a function of _index_. | ||
__Note:__ | ||
If part of returned destination path does not exists, the rotation job will try to create it. | ||
@@ -95,2 +110,4 @@ | ||
* path: {String} (default: null) Specifies the base path for files. | ||
* rotate: {Integer} (default: null) Enables the classical UNIX __logrotate__ behaviour. | ||
* rotationTime: {Boolean} (default: null) Makes rotated file name with time of rotation instead of start time of period. | ||
* size: {String} (default: null) Specifies the file size to rotate the file. | ||
@@ -193,2 +210,11 @@ * highWaterMark: {Number} (default: 16K) Proxied to [new stream.Writable](https://nodejs.org/api/stream.html#stream_new_stream_writable_options) | ||
#### rotationTime | ||
As specified above, if rotation by interval is enabled, the parameter _time_ passed to _rotatle name generator_ is the start time of | ||
rotation period. Setting this option to __true__, parameter _time_ passed is time when rotation job started. | ||
#### rotate | ||
If specified, classical UNIX __logrotate__ behaviour is enabled and the value of this option has same effect in _logrotate.conf_ file. | ||
### Events | ||
@@ -281,2 +307,5 @@ | ||
* 2016-10-18 - v1.1.0 | ||
* Added classical __UNIX logrotate__ tool behaviour. | ||
* Dependencies update | ||
* 2016-04-29 - v1.0.5 | ||
@@ -283,0 +312,0 @@ * Tested on node v6.0 |
19
utils.js
@@ -114,2 +114,11 @@ "use strict"; | ||
"rotate": function(typ, options, val) { | ||
var rotate = parseInt(val); | ||
if(rotate != val || rotate <= 0) | ||
throw new Error("'rotate' option must be a positive integer number"); | ||
}, | ||
"rotationTime": function() {}, | ||
"size": function(typ, options, val) { | ||
@@ -139,2 +148,11 @@ if(typ != "string") | ||
function createClassical(filename) { | ||
return function(index) { | ||
if(! index) | ||
return filename; | ||
return filename + "." + index; | ||
}; | ||
} | ||
function createGenerator(filename) { | ||
@@ -189,2 +207,3 @@ return function(time, index) { | ||
checkOptions: checkOptions, | ||
createClassical: createClassical, | ||
createGenerator: createGenerator, | ||
@@ -191,0 +210,0 @@ makePath: makePath, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28989
581
337