Socket
Socket
Sign inDemoInstall

winston-daily-rotate-file

Package Overview
Dependencies
Maintainers
4
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 4.7.1 to 5.0.0

277

daily-rotate-file.js

@@ -1,14 +0,12 @@

'use strict';
const fs = require("fs");
const os = require("os");
const path = require("path");
const util = require("util");
const zlib = require("zlib");
const hash = require("object-hash");
const MESSAGE = require("triple-beam").MESSAGE;
const PassThrough = require("stream").PassThrough;
const Transport = require("winston-transport");
var fs = require('fs');
var os = require('os');
var path = require('path');
var util = require('util');
var zlib = require('zlib');
var hash = require('object-hash');
var MESSAGE = require('triple-beam').MESSAGE;
var PassThrough = require('stream').PassThrough;
var Transport = require('winston-transport');
var loggerDefaults = {
const loggerDefaults = {
json: false,

@@ -23,3 +21,3 @@ colorize: false,

showLevel: true,
timestamp: function () {
timestamp: () => {
return new Date().toISOString();

@@ -29,3 +27,3 @@ }

var DailyRotateFile = function (options) {
const DailyRotateFile = function(options) {
options = options || {};

@@ -35,5 +33,5 @@ Transport.call(this, options);

function throwIf(target /* , illegal... */) {
Array.prototype.slice.call(arguments, 1).forEach(function (name) {
Array.prototype.slice.call(arguments, 1).forEach((name) => {
if (options[name]) {
throw new Error('Cannot set ' + name + ' and ' + target + ' together');
throw new Error("Cannot set " + name + " and " + target + " together");
}

@@ -44,10 +42,9 @@ });

function getMaxSize(size) {
if (size && typeof size === 'string') {
var _s = size.toLowerCase().match(/^((?:0\.)?\d+)([k|m|g])$/);
if (_s) {
if (size && typeof size === "string") {
if (size.toLowerCase().match(/^((?:0\.)?\d+)([kmg])$/)) {
return size;
}
} else if (size && Number.isInteger(size)) {
var sizeK = Math.round(size / 1024);
return sizeK === 0 ? '1k' : sizeK + 'k';
const sizeK = Math.round(size / 1024);
return sizeK === 0 ? "1k" : sizeK + "k";
}

@@ -60,3 +57,5 @@

// eslint-disable-next-line no-control-regex
return !/["<>|:*?\\/\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(filename);
return !/["<>|:*?\\/\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(
filename
);
}

@@ -66,3 +65,5 @@

// eslint-disable-next-line no-control-regex
return !/["<>|\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(dirname);
return !/["<>|\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(
dirname
);
}

@@ -73,19 +74,19 @@

if (options.stream) {
throwIf('stream', 'filename', 'maxsize');
throwIf("stream", "filename", "maxsize");
this.logStream = new PassThrough();
this.logStream.pipe(options.stream);
} else {
this.filename = options.filename ? path.basename(options.filename) : 'winston.log';
this.filename = options.filename
? path.basename(options.filename)
: "winston.log";
this.dirname = options.dirname || path.dirname(options.filename);
if (!isValidFileName(this.filename) || !isValidDirName(this.dirname)) {
throw new Error('Your path or filename contain an invalid character.');
throw new Error("Your path or filename contain an invalid character.");
}
var self = this;
this.logStream = require('file-stream-rotator').getStream({
this.logStream = require("file-stream-rotator").getStream({
filename: path.join(this.dirname, this.filename),
frequency: options.frequency ? options.frequency : 'custom',
date_format: options.datePattern ? options.datePattern : 'YYYY-MM-DD',
frequency: options.frequency ? options.frequency : "custom",
date_format: options.datePattern ? options.datePattern : "YYYY-MM-DD",
verbose: false,

@@ -95,58 +96,88 @@ size: getMaxSize(options.maxSize),

end_stream: true,
audit_file: options.auditFile ? options.auditFile : path.join(self.dirname, '.' + hash(options) + '-audit.json'),
file_options: options.options ? options.options : {flags: 'a'},
audit_file: options.auditFile
? options.auditFile
: path.join(this.dirname, "." + hash(options) + "-audit.json"),
file_options: options.options ? options.options : { flags: "a" },
utc: options.utc ? options.utc : false,
extension: options.extension ? options.extension : '',
extension: options.extension ? options.extension : "",
create_symlink: options.createSymlink ? options.createSymlink : false,
symlink_name: options.symlinkName ? options.symlinkName : 'current.log',
symlink_name: options.symlinkName ? options.symlinkName : "current.log",
watch_log: options.watchLog ? options.watchLog : false,
audit_hash_type: options.auditHashType ? options.auditHashType : 'sha256'
audit_hash_type: options.auditHashType ? options.auditHashType : "sha256"
});
this.logStream.on('new', function (newFile) {
self.emit('new', newFile);
this.logStream.on("new", (newFile) => {
this.emit("new", newFile);
});
this.logStream.on('rotate', function (oldFile, newFile) {
self.emit('rotate', oldFile, newFile);
this.logStream.on("rotate", (oldFile, newFile) => {
this.emit("rotate", oldFile, newFile);
});
this.logStream.on('logRemoved', function (params) {
this.logStream.on("logRemoved", (params) => {
if (options.zippedArchive) {
var gzName = params.name + '.gz';
if (fs.existsSync(gzName)) {
try {
fs.unlinkSync(gzName);
const gzName = params.name + ".gz";
try {
fs.unlinkSync(gzName);
} catch (err) {
// ENOENT is okay, means file doesn't exist, other errors prevent deletion, so report it
if (err.code !== "ENOENT") {
err.message = `Error occurred while removing ${gzName}: ${err.message}`;
this.emit("error", err);
return;
}
catch (_err) {
// file is there but we got an error when trying to delete,
// so permissions problem or concurrency issue and another
// process already deleted it we could detect the concurrency
// issue by checking err.type === ENOENT or EACCESS for
// permissions ... but then?
}
self.emit('logRemoved', gzName);
return;
}
this.emit("logRemoved", gzName);
return;
}
self.emit('logRemoved', params.name);
this.emit("logRemoved", params.name);
});
if (options.zippedArchive) {
this.logStream.on('rotate', function (oldFile) {
var oldFileExist = fs.existsSync(oldFile);
var gzExist = fs.existsSync(oldFile + '.gz');
if (!oldFileExist || gzExist) {
this.logStream.on("rotate", (oldFile) => {
try {
if (!fs.existsSync(oldFile)) {
return;
}
} catch (err) {
err.message = `Error occurred while checking existence of ${oldFile}: ${err.message}`;
this.emit("error", err);
return;
}
try {
if (fs.existsSync(`${oldFile}.gz`)) {
return;
}
} catch (err) {
err.message = `Error occurred while checking existence of ${oldFile}.gz: ${err.message}`;
this.emit("error", err);
return;
}
var gzip = zlib.createGzip();
var inp = fs.createReadStream(oldFile);
var out = fs.createWriteStream(oldFile + '.gz');
inp.pipe(gzip).pipe(out).on('finish', function () {
if (fs.existsSync(oldFile)) {
fs.unlinkSync(oldFile);
}
self.emit('archive', oldFile + '.gz');
const gzip = zlib.createGzip();
const inp = fs.createReadStream(oldFile);
inp.on("error", (err) => {
err.message = `Error occurred while reading ${oldFile}: ${err.message}`;
this.emit("error", err);
});
const out = fs.createWriteStream(oldFile + ".gz");
out.on("error", (err) => {
err.message = `Error occurred while writing ${oldFile}.gz: ${err.message}`;
this.emit("error", err);
});
inp
.pipe(gzip)
.pipe(out)
.on("finish", () => {
try {
fs.unlinkSync(oldFile);
} catch (err) {
if (err.code !== "ENOENT") {
err.message = `Error occurred while removing ${oldFile}: ${err.message}`;
this.emit("error", err);
return;
}
}
this.emit("archive", oldFile + ".gz");
});
});

@@ -156,5 +187,5 @@ }

if (options.watchLog) {
this.logStream.on('addWatcher', (newFile) => {
self.emit('addWatcher', newFile);
})
this.logStream.on("addWatcher", (newFile) => {
this.emit("addWatcher", newFile);
});
}

@@ -168,5 +199,5 @@ }

DailyRotateFile.prototype.name = 'dailyRotateFile';
DailyRotateFile.prototype.name = "dailyRotateFile";
var noop = function () {};
const noop = function() {};
DailyRotateFile.prototype.log = function (info, callback) {

@@ -176,3 +207,3 @@ callback = callback || noop;

this.logStream.write(info[MESSAGE] + this.options.eol);
this.emit('logged', info);
this.emit("logged", info);
callback(null, true);

@@ -182,6 +213,5 @@ };

DailyRotateFile.prototype.close = function () {
var self = this;
if (this.logStream) {
this.logStream.end(function () {
self.emit('finish');
this.logStream.end(() => {
this.emit("finish");
});

@@ -192,3 +222,3 @@ }

DailyRotateFile.prototype.query = function (options, callback) {
if (typeof options === 'function') {
if (typeof options === "function") {
callback = options;

@@ -199,11 +229,12 @@ options = {};

if (!this.options.json) {
throw new Error('query() may not be used without the json option being set to true');
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');
throw new Error("query() may not be used when initializing with a stream");
}
var self = this;
var results = [];
let results = [];
options = options || {};

@@ -218,4 +249,4 @@

// now
options.until = options.until || new Date;
if (typeof options.until !== 'object') {
options.until = options.until || new Date();
if (typeof options.until !== "object") {
options.until = new Date(options.until);

@@ -225,4 +256,4 @@ }

// now - 24
options.from = options.from || (options.until - (24 * 60 * 60 * 1000));
if (typeof options.from !== 'object') {
options.from = options.from || options.until - 24 * 60 * 60 * 1000;
if (typeof options.from !== "object") {
options.from = new Date(options.from);

@@ -232,9 +263,7 @@ }

// 'asc' or 'desc'
options.order = options.order || 'desc';
options.order = options.order || "desc";
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);
});
const logFiles = (() => {
const fileRegex = new RegExp(this.filename.replace("%DATE%", ".*"), "i");
return fs.readdirSync(this.dirname).filter((file) => path.basename(file).match(fileRegex));
})();

@@ -246,3 +275,3 @@

(function processLogFile(file) {
const processLogFile = (file) => {
if (!file) {

@@ -252,17 +281,22 @@ return;

var logFile = path.join(self.dirname, file);
var buff = '';
const logFile = path.join(this.dirname, file);
let buff = "";
var stream;
let stream;
if (file.endsWith('.gz')) {
if (file.endsWith(".gz")) {
stream = new PassThrough();
fs.createReadStream(logFile).pipe(zlib.createGunzip()).pipe(stream);
const inp = fs.createReadStream(logFile);
inp.on("error", (err) => {
err.message = `Error occurred while reading ${logFile}: ${err.message}`;
stream.emit("error", err);
});
inp.pipe(zlib.createGunzip()).pipe(stream);
} else {
stream = fs.createReadStream(logFile, {
encoding: 'utf8'
encoding: "utf8",
});
}
stream.on('error', function (err) {
stream.on("error", (err) => {
if (stream.readable) {

@@ -276,10 +310,10 @@ stream.destroy();

return err.code === 'ENOENT' ? callback(null, results) : callback(err);
return err.code === "ENOENT" ? callback(null, results) : callback(err);
});
stream.on('data', function (data) {
stream.on("data", (data) => {
data = (buff + data).split(/\n+/);
var l = data.length - 1;
const l = data.length - 1;
for (var i = 0; i < l; i++) {
for (let i = 0; i < l; i++) {
add(data[i]);

@@ -291,3 +325,3 @@ }

stream.on('end', function () {
stream.on("end", () => {
if (buff) {

@@ -300,5 +334,5 @@ add(buff, true);

} else if (callback) {
results.sort(function (a, b) {
var d1 = new Date(a.timestamp).getTime();
var d2 = new Date(b.timestamp).getTime();
results.sort( (a, b) => {
const d1 = new Date(a.timestamp).getTime();
const d2 = new Date(b.timestamp).getTime();

@@ -308,8 +342,8 @@ return d1 > d2 ? 1 : d1 < d2 ? -1 : 0;

if (options.order === 'desc') {
if (options.order === "desc") {
results = results.reverse();
}
var start = options.start || 0;
var limit = options.limit || results.length;
const start = options.start || 0;
const limit = options.limit || results.length;

@@ -319,5 +353,5 @@ results = results.slice(start, start + limit);

if (options.fields) {
results = results.map(function (log) {
var obj = {};
options.fields.forEach(function (key) {
results = results.map( (log) => {
const obj = {};
options.fields.forEach( (key) => {
obj[key] = log[key];

@@ -335,11 +369,13 @@ });

try {
var log = JSON.parse(buff);
if (!log || typeof log !== 'object') {
const log = JSON.parse(buff);
if (!log || typeof log !== "object") {
return;
}
var time = new Date(log.timestamp);
if ((options.from && time < options.from) ||
const time = new Date(log.timestamp);
if (
(options.from && time < options.from) ||
(options.until && time > options.until) ||
(options.level && options.level !== log.level)) {
(options.level && options.level !== log.level)
) {
return;

@@ -351,7 +387,8 @@ }

if (!attempt) {
stream.emit('error', e);
stream.emit("error", e);
}
}
}
})(logFiles.shift());
};
processLogFile(logFiles.shift());
};

@@ -68,3 +68,3 @@ import TransportStream = require("winston-transport");

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

@@ -71,0 +71,0 @@ auditFile?: string;

@@ -1,7 +0,5 @@

'use strict';
const winston = require("winston");
const DailyRotateFile = require("./daily-rotate-file");
var winston = require('winston');
var DailyRotateFile = require('./daily-rotate-file');
winston.transports.DailyRotateFile = DailyRotateFile;
module.exports = DailyRotateFile;
{
"name": "winston-daily-rotate-file",
"version": "4.7.1",
"version": "5.0.0",
"description": "A transport for winston which logs to a rotating file each day.",

@@ -11,3 +11,4 @@ "main": "index.js",

"scripts": {
"test": "mocha --ignore **/*.worker.js && eslint ."
"test": "mocha --ignore **/*.worker.js && eslint .",
"release": "release-script"
},

@@ -39,7 +40,9 @@ "repository": {

"devDependencies": {
"chai": "4.2.0",
"eslint": "^6.8.0",
"@alcalzone/release-script": "^3.7.0",
"@alcalzone/release-script-plugin-license": "^3.7.0",
"chai": "^4.4.1",
"eslint": "^8.56.0",
"eslint-plugin-node": "^11.1.0",
"mocha": "^7.2.0",
"rimraf": "^3.0.2",
"mocha": "^10.2.0",
"rimraf": "^5.0.5",
"threads": "^1.7.0"

@@ -49,6 +52,6 @@ },

"file-stream-rotator": "^0.6.1",
"object-hash": "^2.0.1",
"triple-beam": "^1.3.0",
"winston-transport": "^4.4.0"
"object-hash": "^3.0.0",
"triple-beam": "^1.4.1",
"winston-transport": "^4.7.0"
}
}

@@ -9,3 +9,3 @@ # winston-daily-rotate-file

Starting with version 2.0.0, the transport has been refactored to leverage the the [file-stream-rotator](https://github.com/rogerc/file-stream-rotator/) module. _Some of the options in the 1.x versions of the transport have changed._ Please review the options below to identify any changes needed.
Starting with version 2.0.0, the transport has been refactored to leverage the [file-stream-rotator](https://github.com/rogerc/file-stream-rotator/) module. _Some of the options in the 1.x versions of the transport have changed._ Please review the options below to identify any changes needed.

@@ -15,2 +15,6 @@ ## Compatibility

Starting with version 5.0.0 this module also emits an "error" event for all low level filesystem error cases. Make sure to listen for this event to prevent crashes in your application.
This library should work starting with Node.js 8.x, but tests are only executed for Node.js 14+. Use on your own risk in lower Node.js versions.
## Install

@@ -33,3 +37,3 @@ ```

* **options:** An object resembling https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options indicating additional options that should be passed to the file stream. (default: `{ flags: 'a' }`)
* **auditFile**: A string representing 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')
* **auditFile**: A string representing the path of the audit file, passed directly to [file-stream-rotator](https://github.com/rogerc/file-stream-rotator/) as `audit_file`. If not specified, a file name is generated that includes a hash computed from the options object, and uses the `dirname` option value as the directory. (default: `<dirname>/.<optionsHash>-audit.json`)
* **utc**: Use UTC time for date in filename. (default: false)

@@ -40,2 +44,3 @@ * **extension**: File extension to be appended to the filename. (default: '')

* **auditHashType**: Use specified hashing algorithm for audit. (default: 'sha256')
* **level**: Name of the logging level that will be used for the transport, if not specified option from `createLogger` method will be used

@@ -48,2 +53,3 @@ ## Usage

var transport = new winston.transports.DailyRotateFile({
level: 'info',
filename: 'application-%DATE%.log',

@@ -55,4 +61,8 @@ datePattern: 'YYYY-MM-DD-HH',

});
transport.on('error', error => {
// log or handle errors here
});
transport.on('rotate', function(oldFilename, newFilename) {
transport.on('rotate', (oldFilename, newFilename) => {
// do something fun

@@ -70,3 +80,53 @@ });

```
using multiple transports
``` js
var winston = require('winston');
require('winston-daily-rotate-file');
var transport1 = new winston.transports.DailyRotateFile({
filename: 'application-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
});
var transport2 = new winston.transports.DailyRotateFile({
level: 'error',
filename: 'application-error-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d'
});
transport1.on('error', error => {
// log or handle errors here
});
transport2.on('error', error => {
// log or handle errors here
});
transport1.on('rotate', function(oldFilename, newFilename) {
// do something fun
});
transport2.on('rotate', function(oldFilename, newFilename) {
// do something fun
});
var logger = winston.createLogger({
level: 'info'
transports: [
transport1, // will be used on info level
transport2 // will be used on error level
]
});
logger.info('Hello World!');
logger.error('Hello Error!');
```
### ES6

@@ -87,3 +147,7 @@

transport.on('rotate', function(oldFilename, newFilename) {
transport.on('error', error => {
// log or handle errors here
});
transport.on('rotate', (oldFilename, newFilename) => {
// do something fun

@@ -105,4 +169,4 @@ });

import * as winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';
import * as winston from 'winston';
import DailyRotateFile from 'winston-daily-rotate-file';

@@ -115,15 +179,20 @@ const transport: DailyRotateFile = new DailyRotateFile({

maxFiles: '14d'
});
});
transport.on('rotate', function(oldFilename, newFilename) {
// do something fun
});
transport.on('error', error => {
// log or handle errors here
});
transport.on('rotate', (oldFilename, newFilename) => {
// do something fun
});
const logger = winston.createLogger({
transports: [
transport
]});
transports: [
transport
]
});
logger.info('Hello World!');
```

@@ -138,2 +207,3 @@

* **logRemoved**: fired when a log file is removed from the file system. This event will pass one parameter to the callback (*removedFilename*).
* * **error**: fired when a low level filesystem error happens (e.g. EACCESS)

@@ -140,0 +210,0 @@ ## LICENSE

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