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

metalog

Package Overview
Dependencies
Maintainers
4
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metalog - npm Package Compare versions

Comparing version 1.0.2 to 1.0.3

300

metalog.js
'use strict';
const fs = require('fs');
const util = require('util');
const events = require('events');

@@ -48,4 +47,9 @@ const common = require('@metarhia/common');

const normalizeStack = stack => stack.replace(/\s+at\s+/g, '\n\t');
const lineStack = stack => stack.replace(/[\n\r]\s*/g, '; ');
const pad = (s, len, char = ' ') => s + char.repeat(len - s.length);
// Logger wrapper to bind it to certain application
class ApplicationLogger {

@@ -65,3 +69,3 @@

fatal(message) {
const msg = Logger.normalizeStack(message);
const msg = normalizeStack(message);
this.logger.write('fatal', msg, this.application);

@@ -71,3 +75,3 @@ }

error(message) {
const msg = Logger.normalizeStack(message);
const msg = normalizeStack(message);
this.logger.write('error', msg, this.application);

@@ -85,3 +89,3 @@ }

debug(message) {
const msg = Logger.normalizeStack(message);
const msg = normalizeStack(message);
this.logger.write('debug', msg, this.application);

@@ -100,163 +104,157 @@ }

// Logger constructor
// path <string> log directory
// node <string> nodeId
// writeInterval <number> flush log to disk interval
// writeBuffer <number> buffer size 64kb
// keepDays <number> delete files after N days, 0 to disable
// toFile <string[]> write log types to file
// toStdout <string[]> write log types to stdout
function Logger(options) {
const { path, node } = options;
const { writeInterval, writeBuffer, keepDays } = options;
const { toFile, toStdout } = options;
this.active = false;
this.path = path;
this.node = node;
this.writeInterval = writeInterval || 3000;
this.writeBuffer = writeBuffer || 64 * 1024;
this.keepDays = keepDays || 0;
this.options = { flags: 'a', highWaterMark: this.writeBuffer };
this.stream = null;
this.reopenTimer = null;
this.flushTimer = null;
this.lock = false;
this.buffer = [];
this.file = '';
this.toFile = logTypes(toFile);
this.toStdout = logTypes(toStdout);
this.open();
}
class Logger extends events.EventEmitter {
util.inherits(Logger, events.EventEmitter);
// path <string> log directory
// node <string> nodeId
// writeInterval <number> flush log to disk interval
// writeBuffer <number> buffer size 64kb
// keepDays <number> delete files after N days, 0 to disable
// toFile <string[]> write log types to file
// toStdout <string[]> write log types to stdout
constructor(options) {
super();
const { path, node } = options;
const { writeInterval, writeBuffer, keepDays } = options;
const { toFile, toStdout } = options;
this.active = false;
this.path = path;
this.node = node;
this.writeInterval = writeInterval || 3000;
this.writeBuffer = writeBuffer || 64 * 1024;
this.keepDays = keepDays || 0;
this.options = { flags: 'a', highWaterMark: this.writeBuffer };
this.stream = null;
this.reopenTimer = null;
this.flushTimer = null;
this.lock = false;
this.buffer = [];
this.file = '';
this.toFile = logTypes(toFile);
this.toStdout = logTypes(toStdout);
this.open();
}
Logger.prototype.open = function() {
if (this.active) return;
this.active = true;
const date = common.nowDate();
this.file = this.path + '/' + date + '-' + this.node + '.log';
const now = new Date();
const nextDate = new Date();
nextDate.setUTCHours(0, 0, 0, 0);
const nextReopen = nextDate - now + DAY_MILLISECONDS;
this.reopenTimer = setTimeout(() => {
this.once('close', () => {
this.open();
open() {
if (this.active) return;
this.active = true;
const date = common.nowDate();
this.file = `${this.path}/${date}-${this.node}.log`;
const now = new Date();
const nextDate = new Date();
nextDate.setUTCHours(0, 0, 0, 0);
const nextReopen = nextDate - now + DAY_MILLISECONDS;
this.reopenTimer = setTimeout(() => {
this.once('close', () => {
this.open();
});
this.close();
}, nextReopen);
if (this.keepDays) this.rotate();
this.stream = fs.createWriteStream(this.file, this.options);
this.flushTimer = setInterval(() => {
this.flush();
}, this.writeInterval);
this.stream.on('open', () => {
this.emit('open');
});
this.close();
}, nextReopen);
if (this.keepDays) this.rotate();
this.stream = fs.createWriteStream(this.file, this.options);
this.flushTimer = setInterval(() => {
this.flush();
}, this.writeInterval);
this.stream.on('open', () => {
this.emit('open');
});
this.stream.on('error', () => {
this.emit('error', new Error('Can\'t open log file:' + this.file));
});
};
this.stream.on('error', () => {
this.emit('error', new Error(`Can't open log file: ${this.file}`));
});
}
Logger.prototype.close = function() {
if (!this.active) return;
const stream = this.stream;
if (!stream || stream.destroyed || stream.closed) return;
this.flush((err) => {
if (err) return;
this.active = false;
this.stream.end(() => {
clearInterval(this.flushTimer);
clearTimeout(this.reopenTimer);
this.flushTimer = null;
this.reopenTimer = null;
const fileName = this.file;
this.emit('close');
fs.stat(fileName, (err, stats) => {
if (err) {
console.log(err);
return;
}
if (stats.size > 0) return;
fs.unlink(this.file, (err) => {
console.log(err);
close() {
if (!this.active) return;
const stream = this.stream;
if (!stream || stream.destroyed || stream.closed) return;
this.flush(err => {
if (err) return;
this.active = false;
this.stream.end(() => {
clearInterval(this.flushTimer);
clearTimeout(this.reopenTimer);
this.flushTimer = null;
this.reopenTimer = null;
const fileName = this.file;
this.emit('close');
fs.stat(fileName, (err, stats) => {
if (err) {
process.stdout.write(`${err}\n`);
return;
}
if (stats.size > 0) return;
fs.unlink(this.file, err => {
process.stdout.write(`${err}\n`);
});
});
});
});
});
};
}
Logger.prototype.rotate = function() {
if (!this.keepDays) return;
fs.readdir(this.path, (err, files) => {
if (err) {
console.log(err);
return;
}
const now = new Date();
const date = new Date(
now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0, 0
);
const time = date.getTime();
let i, fileName, fileTime, fileAge;
for (i in files) {
fileName = files[i];
fileTime = new Date(fileName.substring(0, 10)).getTime();
fileAge = Math.floor((time - fileTime) / DAY_MILLISECONDS);
if (fileAge > 1 && fileAge > this.keepDays - 1) {
fs.unlink(this.path + '/' + fileName, (err) => {
console.log(err);
});
rotate() {
if (!this.keepDays) return;
fs.readdir(this.path, (err, files) => {
if (err) {
process.stdout.write(`${err}\n`);
return;
}
const now = new Date();
const date = new Date(
now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0, 0
);
const time = date.getTime();
let i, fileName, fileTime, fileAge;
for (i in files) {
fileName = files[i];
fileTime = new Date(fileName.substring(0, 10)).getTime();
fileAge = Math.floor((time - fileTime) / DAY_MILLISECONDS);
if (fileAge > 1 && fileAge > this.keepDays - 1) {
fs.unlink(this.path + '/' + fileName, err => {
process.stdout.write(`${err}\n`);
});
}
}
});
}
write(type, message, application = 'default') {
const date = new Date();
if (this.toStdout[type]) {
const normalColor = textColor[type];
const markColor = typeColor[type];
const time = normalColor(date.toTimeString().substring(0, 8));
const mark = markColor(' ' + pad(type, 7));
const msg = normalColor(`${this.node}/${application} ${message}`);
const line = `${time} ${mark} ${msg}`;
process.stdout.write(`${line}\n`);
}
});
};
if (this.toFile[type]) {
const time = date.toISOString();
const multiline = (/[\n\r]/g).test(message);
const line = multiline ? lineStack(message) : message;
const data = `${time} [${type}] ${this.node}/${application} ${line}\n`;
const buffer = Buffer.from(data);
this.buffer.push(buffer);
}
}
Logger.normalizeStack = (stack) => stack.replace(/\s+at\s+/g, '\n\t');
Logger.lineStack = (stack) => stack.replace(/[\n\r]\s*/g, '; ');
Logger.formatStack = (stack) => stack.replace(/; /g, '\n\t');
const pad = (s, len, char = ' ') => s + char.repeat(len - s.length);
Logger.prototype.write = function(type, message, application = 'default') {
const date = new Date();
if (this.toStdout[type]) {
const normalColor = textColor[type];
const markColor = typeColor[type];
const time = normalColor(date.toTimeString().substring(0, 8));
const mark = markColor(' ' + pad(type, 7));
const msg = normalColor(`${this.node}/${application} ${message}`);
const line = `${time} ${mark} ${msg}`;
console.log(line);
flush(callback) {
if (!this.active || this.lock || !this.buffer.length) {
if (callback) callback(new Error('Can\'t flush log buffer'));
return;
}
this.lock = true;
const buffer = Buffer.concat(this.buffer);
this.buffer.length = 0;
this.stream.write(buffer, err => {
this.lock = false;
if (callback) callback(err);
});
}
if (this.toFile[type]) {
const time = date.toISOString();
const multiline = (/[\n\r]/g).test(message);
const line = multiline ? Logger.lineStack(message) : message;
const data = `${time} [${type}] ${this.node}/${application} ${line}\n`;
const buffer = Buffer.from(data);
this.buffer.push(buffer);
}
};
Logger.prototype.flush = function(callback) {
if (!this.active || this.lock || !this.buffer.length) {
if (callback) callback(new Error('Can\'t flush log buffer'));
return;
bind(application) {
return new ApplicationLogger(this, application);
}
this.lock = true;
const buffer = Buffer.concat(this.buffer);
this.buffer.length = 0;
this.stream.write(buffer, (err) => {
this.lock = false;
if (callback) callback(err);
});
};
Logger.prototype.bind = function(application) {
return new ApplicationLogger(this, application);
};
}
module.exports = (args) => new Logger(args);
module.exports = args => new Logger(args);
{
"name": "metalog",
"version": "1.0.2",
"version": "1.0.3",
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>",

@@ -23,4 +23,3 @@ "description": "Meta Logger for Metarhia",

"test": "eslint . && metatests test/",
"lint": "eslint .",
"docs": "metaschema ./metalog.js"
"lint": "eslint ."
},

@@ -35,6 +34,5 @@ "engines": {

"devDependencies": {
"eslint": "^5.11.1",
"metaschema": "0.0.29",
"eslint": "^5.12.0",
"metatests": "^0.4.0"
}
}
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