Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rotating-file-stream

Package Overview
Dependencies
Maintainers
1
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rotating-file-stream - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

utils.js

226

index.js
"use strict";
var fs = require("fs");
var fs = require("fs");
var util = require("util");
var utils = require("./utils");
var Writable = require("stream").Writable;
var RotatingFileStream = require("./constructor");
function RotatingFileStream(filename, options) {
if(! (this instanceof RotatingFileStream))
return new RotatingFileStream(filename, options);
function unexpected(msg) {
throw new Error("Unexpected case ( https://www.npmjs.com/package/rotating-file-stream#unexpected ): " + msg);
if(typeof filename == "function")
this.generator = filename;
else
if(typeof filename == "string")
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);
utils.checkOptions(options);
Writable.call(this, options.highWaterMark ? { highWaterMark: options.highWaterMark } : {} );
this.options = options;
this.size = 0;
utils.setEvents(this);
this.firstOpen();
}
RotatingFileStream.prototype._write = function(chunk, encoding, callback) {
if(this.err)
unexpected("_write after error");
util.inherits(RotatingFileStream, Writable);
if(this.callback)
unexpected("_write before callback");
RotatingFileStream.prototype._callback = function(err) {
if(! this.callback) {
if(err)
process.nextTick(this.emit.bind(this, "error", err));
if(! this.stream) {
this.buffer += chunk;
this.callback = callback;
return;
}
var self = this;
if(err)
process.nextTick(this.callback.bind(null, err));
else
process.nextTick(this._rewrite.bind(this, this.chunks, this.index, this.callback));
this.size += chunk.length;
this.stream.write(chunk, function(err) {
if(err)
return callback(err);
this.callback = null;
};
if(self.options.size && self.size >= self.options.size)
return self.rotate(callback);
RotatingFileStream.prototype._postrewrite = function(chunks, index, callback, next) {
this.callback = callback;
this.chunks = chunks;
this.index = index;
callback();
});
if(next)
next();
};
RotatingFileStream.prototype._writev = function(chunks, callback) {
if(this.err)
unexpected("_writev after error");
RotatingFileStream.prototype._rewrite = function(chunks, index, callback, err) {
if(err)
return callback(err);
if(this.callback)
unexpected("_writev before callback");
if(! this.stream)
unexpected("_writev while initial rotation");
return this._postrewrite(chunks, index, callback);
var buffer = "";
var enough = true;
var i;
var self = this;
if(this.options.size && this.size >= this.options.size)
return this._postrewrite(chunks, index, callback, this.rotate.bind(this));
for(i = 0; i < chunks.length && enough; ++i) {
buffer += chunks[i].chunk;
if(chunks.length == index)
return callback();
if(this.options.size && (buffer.length + this.size >= this.options.size))
enough = false;
var buffer = new Buffer(0);
var chunk;
if(index + 1 == chunks.length) {
chunk = chunks[index++].chunk;
this.size += chunk.length;
buffer = chunk;
}
else
while(index < chunks.length && ((! this.options.size) || this.size < this.options.size)) {
chunk = chunks[index++].chunk;
this.size += chunk.length;
buffer = Buffer.concat([buffer, chunk], buffer.length + chunk.length);
}
this.size += buffer.length;
this.stream.write(buffer, function(err) {
if(err)
return self.error(err, callback);
this.stream.write(buffer, this._rewrite.bind(this, chunks, index, callback));
};
if(enough)
return callback();
for(0; i < chunks.length; ++i)
self.buffer += chunks[i].chunk;
self.rotate(callback);
});
RotatingFileStream.prototype._write = function(chunk, encoding, callback) {
this._rewrite([{ chunk: chunk }], 0, callback);
};
RotatingFileStream.prototype.error = function(err, callback) {
if(this.callback)
callback = this.callback;
this.callback = null;
if(callback)
return callback(err);
this.emit("error", err);
RotatingFileStream.prototype._writev = function(chunks, callback) {
this._rewrite(chunks, 0, callback);
};

@@ -130,2 +145,48 @@

RotatingFileStream.prototype._interval = function(now) {
now = new Date(now);
var year = now.getFullYear();
var month = now.getMonth();
var day = now.getDate();
var hours = now.getHours();
var num = this.options.interval.num;
var unit = this.options.interval.unit;
if(unit == "d")
hours = 0;
else
hours = parseInt(hours / num) * num;
this.prev = new Date(year, month, day, hours, 0, 0, 0).getTime();
if(unit == "d")
this.next = new Date(year, month, day + num, hours, 0, 0, 0).getTime();
else
this.next = new Date(year, month, day, hours + num, 0, 0, 0).getTime();
};
RotatingFileStream.prototype.interval = function() {
if(! this.options.interval)
return;
var now = new Date().getTime();
var unit = this.options.interval.unit;
if(unit == "d" || unit == "h") {
this._interval(now);
}
else {
var period = 1000 * this.options.interval.num;
if(unit == "m")
period *= 60;
this.prev = parseInt(now / period) * period;
this.next = this.prev + period;
}
this.timer = setTimeout(this.rotate.bind(this), this.next - now);
this.timer.unref();
};
RotatingFileStream.prototype.move = function(attempts) {

@@ -145,9 +206,6 @@ if(! attempts)

return this.error(err, this.callback);
return this._callback(err);
}
if(this.options.interval)
throw new Error("not implemented yet");
var name = this.generator(this.rotation, count + 1);
var name = this.generator(this.options.interval ? new Date(this.prev) : this.rotation, count + 1);
var self = this;

@@ -170,6 +228,7 @@

if(err)
return self.error(err, this.callback);
return self._callback(err);
self.emit("rotated", name);
self.open();
self.size = 0;
});

@@ -184,12 +243,6 @@ });

var callback = function(err) {
var cb = self.callback;
self._callback(err);
if(cb) {
self.callback = null;
return cb(err);
}
if(err)
throw err;
if(! err)
self.interval();
};

@@ -209,23 +262,14 @@

if(! this.buffer.length)
return callback();
this.stream.write(this.buffer, function(err) {
if(err)
return self.error(err, callback);
callback();
});
this.size += this.buffer.length;
this.buffer = "";
callback();
};
RotatingFileStream.prototype.rotate = function(callback) {
if(callback)
this.callback = callback;
RotatingFileStream.prototype.rotate = function() {
if(this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.size = 0;
this.size = 0;
this.rotation = new Date();
this.emit("rotation");
process.nextTick(this.emit.bind(this, "rotation"));

@@ -232,0 +276,0 @@ if(this.stream) {

{
"name": "rotating-file-stream",
"version": "0.0.2",
"version": "0.0.3",
"description": "Opens a stream.Writable to a file rotated by interval and/or size. A logrotate alternative.",
"scripts": {
"test": "rm -rf *log ; echo '.jshintrc\\n.gitignore\\n.travis.yml\\ntest\\nsleep.js' > .npmignore ; cat .gitignore >> .npmignore\n ./node_modules/.bin/jshint index.js test || exit 1\n ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --recursive test"
"coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --recursive test",
"jshint": "./node_modules/.bin/jshint *.js test",
"npmignore": "echo '.jshintrc\\n.gitignore\\n.travis.yml\\ntest\\nsleep.js' > .npmignore ; cat .gitignore >> .npmignore",
"t": "./node_modules/.bin/_mocha test",
"test": "npm run npmignore && npm run jshint && npm run coverage"
},

@@ -16,10 +20,13 @@ "bugs": "https://github.com/iccicci/rotating-file-stream/issues",

"author": "Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
"contributors": [
"allevo"
],
"license": "MIT",
"readmeFilename": "README.md",
"devDependencies": {
"istanbul": "0.3.19",
"istanbul": "0.3.21",
"jshint": "2.8.0",
"mocha": "2.3.2",
"mocha": "2.3.3",
"mocha-istanbul": "0.2.0"
}
}

@@ -62,3 +62,3 @@ # rotating-file-stream

function pad(num) {
return (num + "").length == 1 ? "0" + num : num;
return (num > 9 ? "" : "0") + num;
}

@@ -107,2 +107,7 @@

```javascript
size: '300B', // rotates the file when its size exceeds 300 Bytes
// useful for tests
```
```javascript
size: '300K', // rotates the file when its size exceeds 300 KiloBytes

@@ -116,3 +121,3 @@ ```

```javascript
size: '1G', // rotates the file when its size exceeds a GigaBytes
size: '1G', // rotates the file when its size exceeds a GigaByte
```

@@ -130,2 +135,7 @@

```javascript
interval: '5s', // rotates the file at seconds 0, 5, 10, 15 and so on
// useful for tests
```
```javascript
interval: '5m', // rotates the file at minutes 0, 5, 10, 15 and so on

@@ -201,2 +211,16 @@ ```

### Rotation logic
Regardless of when and why rotation happens, the content of a single __stream.write__ will never be
split among two files.
#### by size
Once the no rotated file is opened first time, its size is checked and if it is greater or equal to
size limit, a first rotation happens. After each __stream.write__, the same check is performed.
#### by interval
The package sets a _Timeout_ to start a rotation job at the right moment.
### Under the hood

@@ -215,14 +239,4 @@

### Unexpected
Once an __error__ _event_ is emitted, nothing more can be done: the stream is closed as well.
```
If I understood correctly, there are some case which should never happen.
Anyway I want to be sure, so I decided to throw an Error if code runs
through one of these cases.
If it happen that you catch one of these, please make me aware of that as
soon as possible in order to handle the case.
The author
```
### Compatibility

@@ -232,2 +246,3 @@

compatibility. The package it tested under following versions:
* 4.1
* 4.0

@@ -248,11 +263,13 @@ * 0.12

* Rotate by interval
* Create missing directories in paths
* External compression
* Internal compression gzip
* Internal compression bzip
* Create missing directories in paths
* Test all error case handling
### Changelog
### ChangeLog
* 2015-09-29 - v0.0.3
* Rotation by interval
* __Buffer__ optimization (thanks to [allevo](https://www.npmjs.com/~allevo))
* 2015-09-17 - v0.0.2

@@ -259,0 +276,0 @@ * Rotation by size

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc