Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
rotating-file-stream
Advanced tools
Opens a stream.Writable to a file rotated by interval and/or size. A logrotate alternative.
The rotating-file-stream npm package is used to create a stream that writes to a file and rotates the file based on a specified condition, such as file size or time interval. This is particularly useful for logging purposes where you want to manage log file sizes and avoid having a single, ever-growing log file.
Time-based rotation
This feature allows you to rotate the log file based on a time interval. In this example, the log file 'access.log' will be rotated daily and stored in the '/var/log' directory.
const rfs = require('rotating-file-stream');
const stream = rfs.createStream('access.log', {
interval: '1d', // rotate daily
path: '/var/log'
});
Size-based rotation
This feature allows you to rotate the log file based on its size. In this example, the log file 'access.log' will be rotated every time it reaches 10MB and stored in the '/var/log' directory.
const rfs = require('rotating-file-stream');
const stream = rfs.createStream('access.log', {
size: '10M', // rotate every 10 MegaBytes written
path: '/var/log'
});
Compression
This feature allows you to compress the rotated log files. In this example, the log file 'access.log' will be rotated daily and compressed using gzip, then stored in the '/var/log' directory.
const rfs = require('rotating-file-stream');
const stream = rfs.createStream('access.log', {
interval: '1d', // rotate daily
compress: 'gzip', // compress rotated files
path: '/var/log'
});
Custom rotation
This feature allows you to specify a custom rotation policy. In this example, the log file 'access.log' will be rotated and up to 7 rotated files will be kept in the '/var/log' directory.
const rfs = require('rotating-file-stream');
const stream = rfs.createStream('access.log', {
rotate: 7, // keep 7 rotated files
path: '/var/log'
});
The winston-daily-rotate-file package is a transport for the winston logging library that allows you to rotate log files based on a time interval. It is similar to rotating-file-stream in that it supports time-based rotation and compression, but it is specifically designed to work with the winston logging library.
The logrotate-stream package provides a writable stream that rotates log files based on size or time. It is similar to rotating-file-stream in terms of functionality, but it offers a simpler API and fewer configuration options.
The file-stream-rotator package is another option for rotating log files based on size or time. It offers similar features to rotating-file-stream, including time-based and size-based rotation, as well as compression. However, it is less actively maintained compared to rotating-file-stream.
Creates a stream.Writable to a file which is rotated. Rotation behaviour can be deeply customized; optionally, classical UNIX logrotate behaviour can be used.
var rfs = require('rotating-file-stream');
var stream = rfs('file.log', {
size: '10M', // rotate every 10 MegaBytes written
interval: '1d', // rotate daily
compress: 'gzip' // compress rotated files
});
With npm:
$ npm install --save rotating-file-stream
require('rotating-file-stream');
Returns RotatingFileStream constructor.
Extends stream.Writable.
Returns a new RotatingFileStream to filename as fs.createWriteStream does. The file is rotated following options rules.
The most complex problem about file name is: "how to call the rotated file name?"
The answer to this question may vary in many forms depending on application requirements and/or specifications. If there are no requirements, a String can be used and default rotated file name generator will be used; otherwise a Function which returns the rotated file name can be used.
An example of a complex rotated file name generator function could be:
function pad(num) {
return (num > 9 ? "" : "0") + num;
}
function generator(time, index) {
if(! time)
return "file.log";
var month = time.getFullYear() + "" + pad(time.getMonth() + 1);
var day = pad(time.getDate());
var hour = pad(time.getHours());
var minute = pad(time.getMinutes());
return "/storage/" + month + "/" + month +
day + "-" + hour + minute + "-" + index + "-file.log";
}
var rfs = require('rotating-file-stream');
var stream = rfs(generator, {
size: '10M',
interval: '30m'
});
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).
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.
If present, it is prepended to generated file names as well as for history file.
Accepts a positive integer followed by one of these possible letters:
size: '300B', // rotates the file when size exceeds 300 Bytes
// useful for tests
size: '300K', // rotates the file when size exceeds 300 KiloBytes
size: '100M', // rotates the file when size exceeds 100 MegaBytes
size: '1G', // rotates the file when size exceeds a GigaByte
Accepts a positive integer followed by one of these possible letters:
interval: '5s', // rotates at seconds 0, 5, 10, 15 and so on
// useful for tests
interval: '5m', // rotates at minutes 0, 5, 10, 15 and so on
interval: '2h', // rotates at midnight, 02:00, 04:00 and so on
interval: '1d', // rotates at every midnight
Due the nature of Node.js compression may be done with an external command (to use other CPUs than the one used by Node.js) or with internal code (to use the CPU used by Node.js). This decision is left to you.
Following fixed strings are allowed to compress the files with internal libraries:
To enable external compression, a function can be used or simply the boolean true value to use default external compression. The function should accept source and dest file names and must return the shell command to be executed to compress the file. The two following code snippets have exactly the same effect:
var rfs = require('rotating-file-stream');
var stream = rfs('file.log', {
size: '10M',
compress: true
});
var rfs = require('rotating-file-stream');
var stream = rfs('file.log', {
size: '10M',
compress: function(source, dest) {
return "cat " + source + " | gzip -c9 > " + dest;
}
});
Note: the shell command to compress the rotated file should not remove the source file, it will be removed by the package if rotation job complete with success.
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.
If specified, classical UNIX logrotate behaviour is enabled and the value of this option has same effect in logrotate.conf file.
Note: following options are ignored if rotate option is specified.
Due to the complexity that rotated file names can have because of the filename generator function, if number or size of rotated files should not exceed a given limit, the package needs a file where to store this information. This option specifies the name of that file. This option takes effects only if at least one of maxFiles or maxSize is used. If null, the not rotated filename with the '.txt' suffix is used.
If specified, it's value is the maximum number of rotated files to be kept.
If specified, it's value must respect same syntax of (size) option and is the maximum size of rotated files to be kept.
Custom Events are emitted by the stream.
var rfs = require('rotating-file-stream');
var stream = rfs(...);
stream.on('error', function(err) {
// here are reported blocking errors
// once this event is emitted, the stream will be closed as well
});
stream.on('open', function() {
// no rotated file is open (emitted after each rotation as well)
});
stream.on('removed', function(filename, number) {
// rotation job removed the specified old rotated file
// number == true, the file was removed to not exceed maxFiles
// number == false, the file was removed to not exceed maxSize
});
stream.on('rotation', function() {
// rotation job started
});
stream.on('rotated', function(filename) {
// rotation job completed with success producing given filename
});
stream.on('warning', function(err) {
// here are reported non blocking errors
});
Regardless of when and why rotation happens, the content of a single stream.write will never be split among two files.
Once the not-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.
The package sets a Timeout to start a rotation job at the right moment.
Logs should be handled so carefully, so this package tries to never overwrite files.
At stream creation, if the not-rotated log file already exists and its size exceeds the rotation size, an initial rotation attempt is done.
At each rotation attempt a check is done to verify that destination rotated file does not exists yet; if this is not the case a new destination rotated file name is generated and the same check is performed before going on. This is repeated until a not existing destination file name is found or the package is exhausted. For this reason the rotated file name generator function may be called several times for each rotation job.
If requested by maxFiles or maxSize options, at the end of a rotation job, a check is performed to ensure that given limits are respected. This means that while rotation job is running both the limits could be not respected, the same can happend (if maxFiles or maxSize are changed) till the end of first rotation job. The first check performed is the one against maxFiles, in case some files are removed, than the check against maxSize is performed, finally other files can be removed. When maxFiles or maxSize are enabled for first time, an history file can be created with one rotated filename (as returned by filename generator function) at each line.
Once an error event is emitted, nothing more can be done: the stream is closed as well.
This package is written following Node.js 4.0 specifications always taking care about backward compatibility. The package it tested under several Node.js versions.
Required: Node.js 0.11
Do not hesitate to report any bug or inconsistency @github.
If you find useful this package, please consider the opportunity to donate some satoshis to this bitcoin address: 12p1p5q7sK75tPyuesZmssiMYr4TKzpSCN
FAQs
Opens a stream.Writable to a file rotated by interval and/or size. A logrotate alternative.
We found that rotating-file-stream demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.