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

winston-daily-rotate-file

Package Overview
Dependencies
Maintainers
2
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

winston-daily-rotate-file - npm Package Compare versions

Comparing version 3.10.0 to 4.0.0

172

daily-rotate-file.js

@@ -7,10 +7,7 @@ 'use strict';

var util = require('util');
var semver = require('semver');
var zlib = require('zlib');
var hash = require('object-hash');
var winston = require('winston');
var compat = require('winston-compat');
var MESSAGE = require('triple-beam').MESSAGE;
var PassThrough = require('stream').PassThrough;
var Transport = semver.major(winston.version) === 2 ? compat.Transport : require('winston-transport');
var Transport = require('winston-transport');

@@ -93,3 +90,5 @@ var loggerDefaults = {

audit_file: options.auditFile ? options.auditFile : path.join(self.dirname, '.' + hash(options) + '-audit.json'),
file_options: options.options ? options.options : {flags: 'a'}
file_options: options.options ? options.options : {flags: 'a'},
utc: options.utc ? options.utc : false,
extension: options.extension ? options.extension : ''
});

@@ -105,2 +104,6 @@

this.logStream.on('logRemoved', function (params) {
self.emit('logRemoved', params.name);
});
if (options.zippedArchive) {

@@ -133,26 +136,10 @@ this.logStream.on('rotate', function (oldFile) {

var noop = function () {};
if (semver.major(winston.version) === 2) {
DailyRotateFile.prototype.log = function (level, msg, meta, callback) {
callback = callback || noop;
var options = Object.assign({}, this.options, {
level: level,
message: msg,
meta: meta
});
DailyRotateFile.prototype.log = function (info, callback) {
callback = callback || noop;
var output = compat.log(options) + options.eol;
this.logStream.write(output);
callback(null, true);
};
} else {
DailyRotateFile.prototype.normalizeQuery = compat.Transport.prototype.normalizeQuery;
DailyRotateFile.prototype.log = function (info, callback) {
callback = callback || noop;
this.logStream.write(info[MESSAGE] + this.options.eol);
this.emit('logged', info);
callback(null, true);
};
this.logStream.write(info[MESSAGE] + this.options.eol);
this.emit('logged', info);
callback(null, true);
};
}
DailyRotateFile.prototype.close = function () {

@@ -166,132 +153,1 @@ var self = this;

};
DailyRotateFile.prototype.query = function (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
if (!this.options.json) {
throw new Error('query() may not be used without the json option being set to true');
}
if (!this.filename) {
throw new Error('query() may not be used when initializing with a stream');
}
var self = this;
var results = [];
options = self.normalizeQuery(options);
var logFiles = (function () {
var fileRegex = new RegExp(self.filename.replace('%DATE%', '.*'), 'i');
return fs.readdirSync(self.dirname).filter(function (file) {
return path.basename(file).match(fileRegex);
});
})();
if (logFiles.length === 0 && callback) {
callback(null, results);
}
(function processLogFile(file) {
if (!file) {
return;
}
var logFile = path.join(self.dirname, file);
var buff = '';
var stream;
if (file.endsWith('.gz')) {
stream = new PassThrough();
fs.createReadStream(logFile).pipe(zlib.createGunzip()).pipe(stream);
} else {
stream = fs.createReadStream(logFile, {
encoding: 'utf8'
});
}
stream.on('error', function (err) {
if (stream.readable) {
stream.destroy();
}
if (!callback) {
return;
}
return err.code === 'ENOENT' ? callback(null, results) : callback(err);
});
stream.on('data', function (data) {
data = (buff + data).split(/\n+/);
var l = data.length - 1;
for (var i = 0; i < l; i++) {
add(data[i]);
}
buff = data[l];
});
stream.on('end', function () {
if (buff) {
add(buff, true);
}
if (logFiles.length) {
processLogFile(logFiles.shift());
} else if (callback) {
results.sort(function (a, b) {
var d1 = new Date(a.timestamp).getTime();
var d2 = new Date(b.timestamp).getTime();
return d1 > d2 ? 1 : d1 < d2 ? -1 : 0;
});
if (options.order === 'desc') {
results = results.reverse();
}
var start = options.start || 0;
var limit = options.limit || results.length;
results = results.slice(start, start + limit);
if (options.fields) {
results = results.map(function (log) {
var obj = {};
options.fields.forEach(function (key) {
obj[key] = log[key];
});
return obj;
});
}
callback(null, results);
}
});
function add(buff, attempt) {
try {
var log = JSON.parse(buff);
if (!log || typeof log !== 'object') {
return;
}
var time = new Date(log.timestamp);
if ((options.from && time < options.from) || (options.until && time > options.until)) {
return;
}
results.push(log);
} catch (e) {
if (!attempt) {
stream.emit('error', e);
}
}
}
})(logFiles.shift());
};

16

index.d.ts

@@ -50,5 +50,5 @@ declare module "winston-daily-rotate-file" {

/**
* A string representing the name of the name of the audit file. (default: './hash-audit.json' )
* A string representing the name of the name of the audit file. (default: './hash-audit.json')
*/
auditFile?: string
auditFile?: string;

@@ -58,3 +58,13 @@ /**

*/
frequency?: string
frequency?: string;
/**
* A boolean whether or not to generate file name from "datePattern" in UTC format. (default: false)
*/
utc?: boolean;
/**
* A string representing an extension to be added to the filename, if not included in the filename property. (default: '')
*/
extension?: string;
}

@@ -61,0 +71,0 @@ }

{
"name": "winston-daily-rotate-file",
"version": "3.10.0",
"version": "4.0.0",
"description": "A transport for winston which logs to a rotating file each day.",

@@ -8,3 +8,3 @@ "main": "index.js",

"engines": {
"node": ">=6"
"node": ">=8"
},

@@ -33,3 +33,3 @@ "scripts": {

"peerDependencies": {
"winston": "^2 || ^3"
"winston": "^3"
},

@@ -45,9 +45,7 @@ "devDependencies": {

"dependencies": {
"file-stream-rotator": "^0.4.1",
"file-stream-rotator": "^0.5.4",
"object-hash": "^1.3.0",
"semver": "^6.2.0",
"triple-beam": "^1.3.0",
"winston-compat": "^0.1.4",
"winston-transport": "^4.2.0"
}
}

@@ -9,2 +9,5 @@ # winston-daily-rotate-file

## Compatibility
Please note that if you are using `winston@2`, you will need to use `winston-daily-rotate-file@3`. `winston-daily-rotate-file@4` removed support for `winston@2`.
## Install

@@ -19,4 +22,4 @@ ```

* **frequency:** A string representing the frequency of rotation. This is useful if you want to have timed rotations, as opposed to rotations that happen at specific moments in time. Valid values are '#m' or '#h' (e.g., '5m' or '3h'). Leaving this null relies on `datePattern` for the rotation times. (default: null)
* **datePattern:** A string representing the [moment.js date format](http://momentjs.com/docs/#/displaying/format/) to be used for rotating. The meta characters used in this string will dictate the frequency of the file rotation. For example, if your datePattern is simply 'HH' you will end up with 24 log files that are picked up and appended to every day. (default 'YYYY-MM-DD')
* **zippedArchive:** A boolean to define whether or not to gzip archived log files. (default 'false')
* **datePattern:** A string representing the [moment.js date format](http://momentjs.com/docs/#/displaying/format/) to be used for rotating. The meta characters used in this string will dictate the frequency of the file rotation. For example, if your datePattern is simply 'HH' you will end up with 24 log files that are picked up and appended to every day. (default: 'YYYY-MM-DD')
* **zippedArchive:** A boolean to define whether or not to gzip archived log files. (default: 'false')
* **filename:** Filename to be used to log to. This filename can include the `%DATE%` placeholder which will include the formatted datePattern at that point in the filename. (default: 'winston.log.%DATE%)

@@ -29,2 +32,4 @@ * **dirname:** The directory name to save log files to. (default: '.')

* **auditFile**: A string representing the name of the name of the audit file. This can be used to override the default filename which is generated by computing a hash of the options object. (default: '.<optionsHash>.json')
* **utc**: Use UTC time for date in filename. (default: false)
* **extension**: File extension to be appended to the filename. (default: '')

@@ -57,4 +62,9 @@ ## Usage

This transport emits three custom events: *new*, *rotate*, and *archive*. You can listen for the *new* custom event, which is fired when a new log file is created. The new event will pass one parameter to the callback (*newFilename*). You can listen for the *rotate* custom event, which is fired when the log file is rotated. The rotate event will pass two parameters to the callback (*oldFilename*, *newFilename*). You can also listen for the *archive* custom event, which is fired when the log file is archived. The archive event will pass one parameter to the callback (*zipFilename*).
This transport emits the following custom events:
* **new**: fired when a new log file is created. This event will pass one parameter to the callback (*newFilename*).
* **rotate**: fired when the log file is rotated. This event will pass two parameters to the callback (*oldFilename*, *newFilename*).
* **archive**: fired when the log file is archived. This event will pass one parameter to the callback (*zipFilename*).
* **logRemoved**: fired when a log file is removed from the file system. This event will pass one parameter to the callback (*removedFilename*).
## LICENSE

@@ -61,0 +71,0 @@ MIT

@@ -9,3 +9,2 @@ /* eslint-disable max-nested-callbacks,no-unused-expressions,handle-callback-err */

var moment = require('moment');
var semver = require('semver');
var winston = require('winston');

@@ -17,20 +16,16 @@ var MemoryStream = require('./memory-stream');

function sendLogItem(transport, level, message, meta, cb) { // eslint-disable-line max-params
if (semver.major(winston.version) === 2) {
transport.log(level, message, meta, cb);
} else {
var logger = winston.createLogger({
transports: [transport]
});
var logger = winston.createLogger({
transports: [transport]
});
transport.on('logged', function () {
if (cb) {
cb(null, true);
}
});
transport.on('logged', function () {
if (cb) {
cb(null, true);
}
});
logger.info({
level: level,
message: message
});
}
logger.info({
level: level,
message: message
});
}

@@ -51,3 +46,2 @@

expect(transport).to.respondTo('log');
expect(transport).to.respondTo('query');
});

@@ -111,9 +105,11 @@

var logDir = path.join(__dirname, 'logs');
var now = moment().format('YYYY-MM-DD-HH');
var filename = path.join(logDir, 'application-' + now + '.log');
var now = moment().utc().format('YYYY-MM-DD-HH');
var filename = path.join(logDir, 'application-' + now + '.testlog');
var options = {
json: true,
dirname: logDir,
filename: 'application-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH'
filename: 'application-%DATE%',
datePattern: 'YYYY-MM-DD-HH',
utc: true,
extension: '.testlog'
};

@@ -167,5 +163,21 @@

it('should raise the logRemoved event when pruning old log files', function (done) {
var opts = Object.assign({}, options);
opts.maxSize = '1k';
opts.maxFiles = 1;
this.transport = new DailyRotateFile(opts);
this.transport.on('logRemoved', function (removedFilename) {
expect(removedFilename).to.equal(filename);
done();
});
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
this.transport.close();
});
describe('when setting zippedArchive', function () {
it('should archive the log after rotating', function (done) {
var self = this;
var opts = Object.assign({}, options);

@@ -187,70 +199,6 @@ opts.zippedArchive = true;

sendLogItem(this.transport, 'info', randomString(1056));
self.transport.close();
});
});
describe('query', function () {
it('should call callback when no files are present', function () {
this.transport.query(function (err, results) {
expect(results).to.not.be.null;
expect(results.length).to.equal(0);
});
});
it('should raise error when calling with stream', function () {
expect(function () {
var transport = new DailyRotateFile({stream: new MemoryStream()});
transport.query(null);
}).to.throw();
});
it('should raise error when calling with json set to false', function () {
expect(function () {
var opts = Object.assign({}, options);
opts.json = false;
var transport = new DailyRotateFile(opts);
transport.query(null);
}).to.throw();
});
it('should return log entries that match the query', function (done) {
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
var self = this;
this.transport.on('finish', function () {
self.transport.query(function (err, results) {
expect(results).to.not.be.null;
expect(results.length).to.equal(4);
done();
});
});
this.transport.close();
});
it('should search within archived files', function (done) {
var opts = Object.assign({}, options);
opts.zippedArchive = true;
opts.maxSize = '1k';
this.transport = new DailyRotateFile(opts);
sendLogItem(this.transport, 'info', randomString(1056));
sendLogItem(this.transport, 'info', randomString(1056));
var self = this;
self.transport.on('archive', function () {
self.transport.query(function (err, results) {
expect(results).to.not.be.null;
expect(results.length).to.equal(2);
done();
});
});
});
});
});
});

Sorry, the diff of this file is not supported yet

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