New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fm-log

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fm-log - npm Package Compare versions

Comparing version 0.7.4 to 0.8.0

0

demo.js

@@ -0,0 +0,0 @@ // Grab module name automatically

50

Gruntfile.js

@@ -1,30 +0,30 @@

module.exports = function (grunt) {
module.exports = function( grunt ) {
// Project configuration.
grunt.initConfig(
{
pkg: grunt.file.readJSON("package.json"),
// Project configuration.
grunt.initConfig(
{
pkg : grunt.file.readJSON( "package.json" ),
jshint: {
options: {
jshintrc: true
},
lib: {
src: [
"lib/*.js"
]
}
},
jshint : {
options : {
jshintrc : true
},
lib : {
src : [
"lib/*.js"
]
}
},
watch: {
files: [ "lib/*.js" ],
tasks: [ "jshint" ]
}
}
);
watch : {
files : [ "lib/*.js" ],
tasks : [ "jshint" ]
}
}
);
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks( "grunt-contrib-jshint" );
grunt.loadNpmTasks( "grunt-contrib-watch" );
grunt.registerTask("default", [ "jshint" ]);
};
grunt.registerTask( "default", [ "jshint" ] );
};
"use strict";
var colors = require( "colors" );
var chalk = require( "chalk" );
var http = require( "http" );

@@ -37,6 +37,6 @@ var util = require( "util" );

function Untraceable( message ) {
this.message = message;
this.message = message;
}
Untraceable.prototype.toString = function() {
return this.message;
return this.message;
};

@@ -50,15 +50,15 @@

var shouldLog = function( level, logger, message ) {
if( lastMessage && message == lastMessage.message && level == lastMessage.level && logger == lastMessage.logger ) {
++lastMessageRepeated;
return false;
if( lastMessage && message == lastMessage.message && level == lastMessage.level && logger == lastMessage.logger ) {
++lastMessageRepeated;
return false;
} else if( lastMessage && 0 < lastMessageRepeated ) {
lastMessage = undefined;
lastLogger( new Untraceable( "Last message repeated " + lastMessageRepeated + " times." ) );
lastMessageRepeated = 0;
} else if( lastMessage && 0 < lastMessageRepeated ) {
lastMessage = undefined;
lastLogger( new Untraceable( "Last message repeated " + lastMessageRepeated + " times." ) );
lastMessageRepeated = 0;
} else {
lastMessage = {level : level, logger : logger, message : message};
}
return true;
} else {
lastMessage = { level : level, logger : logger, message : message };
}
return true;
};

@@ -70,386 +70,388 @@

var Logger = (function() {
/**
* Construct a new Logger instance.
* @param {String} [prefix] An optional prefix to put in front of every
* logged message. Usually this is the name of the module where the
* logger is created. By default, prefixes are padded so that all logged
* messages line up.
* @constructor
*/
function Logger( prefix ) {
this.prefix = prefix;
}
/**
* Construct a new Logger instance.
* @param {String} [prefix] An optional prefix to put in front of every
* logged message. Usually this is the name of the module where the
* logger is created. By default, prefixes are padded so that all logged
* messages line up.
* @constructor
*/
function Logger( prefix ) {
this.prefix = prefix;
}
/**
* Pad a given prefix to the largest given length of all prefixes.
* @param {String} prefix The prefix to pad.
* @param {Boolean} multiline Are we constructing the prefix for the second or later line in a multiline construct?
* @returns {string} The padded prefix.
*/
var constructPrefix = function( prefix, multiline ) {
// If there is no prefix and nothing else has a prefix, then the .module construction scheme is never used.
// In this case, don't pad anything.
if( !prefix && !moduleMaxLength ) return "";
/**
* Pad a given prefix to the largest given length of all prefixes.
* @param {String} prefix The prefix to pad.
* @param {Boolean} multiline Are we constructing the prefix for the second or later line in a multiline construct?
* @returns {string} The padded prefix.
*/
var constructPrefix = function( prefix, multiline ) {
// If there is no prefix and nothing else has a prefix, then the .module construction scheme is never used.
// In this case, don't pad anything.
if( !prefix && !moduleMaxLength ) return "";
// If we have a prefix, pad it to the max prefix length, otherwise, leave off the parenthesis and just use spaces.
return (prefix && !multiline) ? "(" + pad( prefix, moduleMaxLength, " " ) + ")" : pad( "", moduleMaxLength + 2, " " );
};
// If we have a prefix, pad it to the max prefix length, otherwise, leave off the parenthesis and just use spaces.
return (prefix && !multiline) ? "(" + pad( prefix, moduleMaxLength, " " ) + ")" : pad( "", moduleMaxLength + 2, " " );
};
/**
* Prefix a message with supplied prefix.
* @param {String} prefix The prefix to place in front of the message.
* @param {String} message The message that should be prefixed.
* @param {Boolean} multiline Are we constructing the prefix for the second or later line in a multiline construct?
* @returns {string} The properly prefixed message.
*/
var prefixMessage = function( prefix, message, multiline ) {
// Pad the prefix so that all logged messages line up
prefix = constructPrefix( prefix, multiline );
return (prefix) ? (prefix + " " + message ) : message;
};
/**
* Prefix a message with supplied prefix.
* @param {String} prefix The prefix to place in front of the message.
* @param {String} message The message that should be prefixed.
* @param {Boolean} multiline Are we constructing the prefix for the second or later line in a multiline construct?
* @returns {string} The properly prefixed message.
*/
var prefixMessage = function( prefix, message, multiline ) {
// Pad the prefix so that all logged messages line up
prefix = constructPrefix( prefix, multiline );
return (prefix) ? (prefix + " " + message ) : message;
};
/**
* Pad a given string with another string(usually a single character), to a certain length.
* @param {String|Number} padWhat The string that should be padded.
* @param {Number} [length=2] How long the resulting string should be.
* @param {String} [padWith="0"] What character should be used for the padding.
* @returns {string} The properly padded string.
*/
var pad = function( padWhat, length, padWith ) {
length = length || 2;
padWith = padWith || "0";
var padding = length - ("" + padWhat).length;
return padding ? (new Array( padding + 1 ).join( padWith ) + padWhat) : padWhat;
};
/**
* Pad a given string with another string(usually a single character), to a certain length.
* @param {String|Number} padWhat The string that should be padded.
* @param {Number} [length=2] How long the resulting string should be.
* @param {String} [padWith="0"] What character should be used for the padding.
* @returns {string} The properly padded string.
*/
var pad = function( padWhat, length, padWith ) {
length = length || 2;
padWith = padWith || "0";
var padding = length - ("" + padWhat).length;
return padding ? (new Array( padding + 1 ).join( padWith ) + padWhat) : padWhat;
};
/**
* If the supplied message is an express request, a new message will be generated which only contains relevant properties.
* @param {*} message
* @returns {*}
*/
var unrollRequest = function( message ) {
if( message instanceof http.IncomingMessage && message.originalUrl ) {
message = {
httpVersion : message.httpVersion,
headers : message.headers,
trailers : message.trailers,
method : message.method,
url : message.url,
statusCode : message.statusCode,
/**
* If the supplied message is an express request, a new message will be generated which only contains relevant properties.
* @param {*} message
* @returns {*}
*/
var unrollRequest = function( message ) {
if( message instanceof http.IncomingMessage && message.originalUrl ) {
message = {
httpVersion : message.httpVersion,
headers : message.headers,
trailers : message.trailers,
method : message.method,
url : message.url,
statusCode : message.statusCode,
body : message.body,
params : message.params,
query : message.query,
cookies : message.cookies,
signedCookies : message.signedCookies,
ip : message.ip,
ips : message.ips,
path : message.path,
host : message.hostname || message.host,
fresh : message.fresh,
stale : message.stale,
xhr : message.xhr,
protocol : message.protocol,
secure : message.secure,
subdomains : message.subdomains,
originalUrl : message.originalUrl
}
}
return message;
}
body : message.body,
params : message.params,
query : message.query,
cookies : message.cookies,
signedCookies : message.signedCookies,
ip : message.ip,
ips : message.ips,
path : message.path,
host : message.hostname || message.host,
fresh : message.fresh,
stale : message.stale,
xhr : message.xhr,
protocol : message.protocol,
secure : message.secure,
subdomains : message.subdomains,
originalUrl : message.originalUrl
}
}
return message;
}
/**
* Log a debug message.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.debug = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[DEBUG ]", this, colors.grey, this.debug.bind( this ), message );
};
/**
* Log an informational message.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.info = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[INFO ]", this, colors.cyan, this.info.bind( this ), message );
};
/**
* Log a notice.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.notice = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[NOTICE]", this, colors.green, this.notice.bind( this ), message );
};
/**
* Log a warning.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.warn = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[WARN ]", this, colors.yellow, this.warn.bind( this ), message );
};
/**
* Log an error.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.error = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[ERROR ]", this, colors.red, this.error.bind( this ), message );
};
/**
* Log a critical event.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.critical = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[CRITIC]", this, function( str ) { return colors.bold( colors.red( str ) ); }, this.critical.bind( this ), message );
};
/**
* Log a debug message.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.debug = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[DEBUG ]", this, chalk.grey, this.debug.bind( this ), message );
};
/**
* Log an informational message.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.info = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[INFO ]", this, chalk.cyan, this.info.bind( this ), message );
};
/**
* Log a notice.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.notice = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[NOTICE]", this, chalk.green, this.notice.bind( this ), message );
};
/**
* Log a warning.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.warn = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[WARN ]", this, chalk.yellow, this.warn.bind( this ), message );
};
/**
* Log an error.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.error = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[ERROR ]", this, chalk.red, this.error.bind( this ), message );
};
/**
* Log a critical event.
* @param {String|Error|IncomingMessage} message The message to log.
*/
Logger.prototype.critical = function( message ) {
if( !module.exports.enableLogging ) return;
message = (typeof message == "string" || message instanceof String) ? formatString.apply( this, arguments ) : message;
message = unrollRequest( message );
preLog( "[CRITIC]", this, function( str ) {
return chalk.bold( chalk.red( str ) );
}, this.critical.bind( this ), message );
};
// Aliases
Logger.prototype.verbose = Logger.prototype.debug;
Logger.prototype.err = Logger.prototype.error;
Logger.prototype.crit = Logger.prototype.critical;
// Aliases
Logger.prototype.verbose = Logger.prototype.debug;
Logger.prototype.err = Logger.prototype.error;
Logger.prototype.crit = Logger.prototype.critical;
/**
* Apply util.format on the supplied arguments, as applicable.
* @returns {String} The formatted string.
*/
var formatString = function() {
return (1 < arguments.length) ? util.format.apply( this, arguments ) : arguments[0];
}
/**
* Pre-processes a logging subject. Like breaking it into further subjects or grabbing stacks from Errors.
* @param {String} level The log level indicator.
* @param {Logger} logger The logger that called this function.
* @param {Function} colorizer A function to be used to colorize the output.
* @param {Function} more A callback to use when further output needs to be logged.
* @param {String} message The subject that should be logged.
*/
var preLog = function( level, logger, colorizer, more, message ) {
if( !shouldLog( level, logger, message ) ) {
return;
}
lastLogger = more;
/**
* Apply util.format on the supplied arguments, as applicable.
* @returns {String} The formatted string.
*/
var formatString = function() {
return (1 < arguments.length) ? util.format.apply( this, arguments ) : arguments[ 0 ];
}
/**
* Pre-processes a logging subject. Like breaking it into further subjects or grabbing stacks from Errors.
* @param {String} level The log level indicator.
* @param {Logger} logger The logger that called this function.
* @param {Function} colorizer A function to be used to colorize the output.
* @param {Function} more A callback to use when further output needs to be logged.
* @param {String} message The subject that should be logged.
*/
var preLog = function( level, logger, colorizer, more, message ) {
if( !shouldLog( level, logger, message ) ) {
return;
}
lastLogger = more;
// If we're supposed to trace the call sites, grab the location here.
var location;
if( logger.traceLoggingCalls && !( message instanceof Untraceable ) ) {
var stack = new Error().stack;
// Wrap it into an untraceable, to make sure that logging it won't cause another trace.
location = new Untraceable( " " + analyzeStack( stack ) );
}
// If we're supposed to trace the call sites, grab the location here.
var location;
if( logger.traceLoggingCalls && !( message instanceof Untraceable ) ) {
var stack = new Error().stack;
// Wrap it into an untraceable, to make sure that logging it won't cause another trace.
location = new Untraceable( " " + analyzeStack( stack ) );
}
// If the supplied subject is an Error instance, grab the call stack and log that instead.
if( util.isError( message ) ) {
/** @type {Error} */
var error = message;
// Wrap the stack into an untraceable, to avoid that this more() call causes another trace down the line.
more( new Untraceable( error.stack || error.message || "<invalid error>" ) );
if( location ) {
more( location );
}
return;
}
// If the supplied subject is an Error instance, grab the call stack and log that instead.
if( util.isError( message ) ) {
/** @type {Error} */
var error = message;
// Wrap the stack into an untraceable, to avoid that this more() call causes another trace down the line.
more( new Untraceable( error.stack || error.message || "<invalid error>" ) );
if( location ) {
more( location );
}
return;
}
if( message instanceof Untraceable ) {
message = message.toString();
}
if( message === void(0) ) {
message = "undefined";
}
if( message === null ) {
message = "null";
}
if( message instanceof Untraceable ) {
message = message.toString();
}
// Break up the logging subject into multiple lines as appropriate.
var toLog = generateLogStack( level, logger, message, colorizer );
log( toLog );
if( location ) {
more( location );
}
};
if( message === void(0) ) {
message = "undefined";
}
if( message === null ) {
message = "null";
}
/**
* Take a stack trace and extract a location identifier from it.
* The location identifier represents the location from where the logger was invoked.
* @param {String} stack The traced stack
* @returns {String} A location identifier for the location from where the logger was invoked.
*/
var analyzeStack = function( stack ) {
/**
* Group 1: Function name (optional)
* Group 2: File name
* Group 3: Line
* Group 4: Column
*/
var callSitePattern = new RegExp( /at (?:(.*) )?\(?(.*):(\d+):(\d+)\)?/g );
var sites = stack.match( callSitePattern );
// Break up the logging subject into multiple lines as appropriate.
var toLog = generateLogStack( level, logger, message, colorizer );
log( toLog );
if( location ) {
more( location );
}
};
// The method that invoked the logger is located at index 2 of the stack
if( sites && 2 <= sites.length ) {
var callSiteElementPattern = new RegExp( /at (?:(.*) )?\(?(.*):(\d+):(\d+)\)?/ );
// Pick apart
var callSiteElements = sites[ 2 ].match( callSiteElementPattern );
var functionName, fileName, line, column;
// Assume either 4 (no function name) or 5 elements.
if( callSiteElements.length == 5 ) {
functionName = callSiteElements[ 1 ];
fileName = callSiteElements[ 2 ];
line = callSiteElements[ 3 ];
column = callSiteElements[ 4 ];
} else {
functionName = "(unnamed)";
fileName = callSiteElements[ 1 ];
line = callSiteElements[ 2 ];
column = callSiteElements[ 3 ];
}
/**
* Take a stack trace and extract a location identifier from it.
* The location identifier represents the location from where the logger was invoked.
* @param {String} stack The traced stack
* @returns {String} A location identifier for the location from where the logger was invoked.
*/
var analyzeStack = function( stack ) {
/**
* Group 1: Function name (optional)
* Group 2: File name
* Group 3: Line
* Group 4: Column
*/
var callSitePattern = new RegExp( /at (?:(.*) )?\(?(.*):(\d+):(\d+)\)?/g );
var sites = stack.match( callSitePattern );
return functionName + "@" + fileName + ":" + line + ":" + column;
}
return null;
};
// The method that invoked the logger is located at index 2 of the stack
if( sites && 2 <= sites.length ) {
var callSiteElementPattern = new RegExp( /at (?:(.*) )?\(?(.*):(\d+):(\d+)\)?/ );
// Pick apart
var callSiteElements = sites[ 2 ].match( callSiteElementPattern );
var functionName, fileName, line, column;
// Assume either 4 (no function name) or 5 elements.
if( callSiteElements.length == 5 ) {
functionName = callSiteElements[ 1 ];
fileName = callSiteElements[ 2 ];
line = callSiteElements[ 3 ];
column = callSiteElements[ 4 ];
} else {
functionName = "(unnamed)";
fileName = callSiteElements[ 1 ];
line = callSiteElements[ 2 ];
column = callSiteElements[ 3 ];
}
/**
* Convert an object to a JSON formatted string.
* @param {*} subject The object that should be serialized to JSON.
* @returns {*}
*/
var stringify = function( subject ) {
var cache = [];
var json = JSON.stringify( subject, function( key, value ) {
if( typeof value === "object" && value !== null ) {
if( cache.indexOf( value ) !== -1 ) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push( value );
}
return value;
}, 2 );
return json;
}
return functionName + "@" + fileName + ":" + line + ":" + column;
}
return null;
};
/**
* For a given input, generates a stack of lines that should be logged.
* @param {String} level The log level indicator.
* @param {Logger} logger The logger that invoked this function.
* @param {String} subject The subject that should be logged.
* @param {Function} colorizer A function to be used to colorize the output.
* @returns {Array|String} Either a single string to log, or an array of strings to log.
*/
var generateLogStack = function( level, logger, subject, colorizer ) {
var subjectString = (util.isArray( subject ) || typeof( subject ) == "object") ? stringify( subject ) : subject.toString();
var lines = subjectString.split( "\n" );
/**
* Convert an object to a JSON formatted string.
* @param {*} subject The object that should be serialized to JSON.
* @returns {*}
*/
var stringify = function( subject ) {
var cache = [];
var json = JSON.stringify( subject, function( key, value ) {
if( typeof value === "object" && value !== null ) {
if( cache.indexOf( value ) !== -1 ) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push( value );
}
return value;
}, 2 );
return json;
}
// Most common case, a single line.
if( lines.count == 1 ) {
return colorizer( level + " " + prefixMessage( logger.prefix, subject ) );
}
// Multiple lines, prepare them all nice like.
for( var lineIndex = 0, lineCount = lines.length; lineIndex < lineCount; ++lineIndex ) {
lines[lineIndex] = colorizer( level + " " + prefixMessage( logger.prefix, lines[ lineIndex ], lineIndex > 0 ) );
// Replace the level prefix with whitespace for lines other than the first
if( 0 == lineIndex ) {
level = pad( "", level.length, " " );
}
}
return 1 < lines.length ? lines : lines[ 0 ];
};
/**
* For a given input, generates a stack of lines that should be logged.
* @param {String} level The log level indicator.
* @param {Logger} logger The logger that invoked this function.
* @param {String} subject The subject that should be logged.
* @param {Function} colorizer A function to be used to colorize the output.
* @returns {Array|String} Either a single string to log, or an array of strings to log.
*/
var generateLogStack = function( level, logger, subject, colorizer ) {
var subjectString = (util.isArray( subject ) || typeof( subject ) == "object") ? stringify( subject ) : subject.toString();
var lines = subjectString.split( "\n" );
/**
* Log a message.
* @param {String} message The message to log.
*/
var log = function( message ) {
var time = new Date();
var timestamp = formatDate( time );
if( util.isArray( message ) ) {
for( var messageIndex = 0, messageCount = message.length; messageIndex < messageCount; ++messageIndex ) {
console.log( timestamp + " " + message[ messageIndex ] );
}
} else {
console.log( timestamp + " " + message );
}
};
// Most common case, a single line.
if( lines.count == 1 ) {
return colorizer( level + " " + prefixMessage( logger.prefix, subject ) );
}
// Multiple lines, prepare them all nice like.
for( var lineIndex = 0, lineCount = lines.length; lineIndex < lineCount; ++lineIndex ) {
lines[ lineIndex ] = colorizer( level + " " + prefixMessage( logger.prefix, lines[ lineIndex ], lineIndex > 0 ) );
// Replace the level prefix with whitespace for lines other than the first
if( 0 == lineIndex ) {
level = pad( "", level.length, " " );
}
}
return 1 < lines.length ? lines : lines[ 0 ];
};
/**
* Format the given date to our desired log timestamp format.
* @param {Date} date The date that should be formatted.
* @returns {string} A string in the format of YYYY-MM-DD HH:mm:SS.sss
*/
var formatDate = function( date ) {
return date.getFullYear() + "-" + pad( date.getMonth() + 1 ) + "-" + pad( date.getDate() ) + " " +
pad( date.getHours() ) + ":" + pad( date.getMinutes() ) + ":" + pad( date.getSeconds() ) + "." + pad( date.getMilliseconds(), 3 );
};
/**
* Log a message.
* @param {String} message The message to log.
*/
var log = function( message ) {
var time = new Date();
var timestamp = formatDate( time );
if( util.isArray( message ) ) {
for( var messageIndex = 0, messageCount = message.length; messageIndex < messageCount; ++messageIndex ) {
console.log( timestamp + " " + message[ messageIndex ] );
}
} else {
console.log( timestamp + " " + message );
}
};
/**
* Enable or disable debug output.
* @param {Boolean} [enable=true] Should debug output be enabled?
*/
Logger.prototype.withSource = function( enable ) {
this.traceLoggingCalls = !!!enable;
return this;
};
/**
* Format the given date to our desired log timestamp format.
* @param {Date} date The date that should be formatted.
* @returns {string} A string in the format of YYYY-MM-DD HH:mm:SS.sss
*/
var formatDate = function( date ) {
return date.getFullYear() + "-" + pad( date.getMonth() + 1 ) + "-" + pad( date.getDate() ) + " " +
pad( date.getHours() ) + ":" + pad( date.getMinutes() ) + ":" + pad( date.getSeconds() ) + "." + pad( date.getMilliseconds(), 3 );
};
/**
* Create and wrap a morgan instance.+
* @param {String} format The format string to pass to morgan.
* @param {Object} [options] The options object that will be passed to the morgan constructor.
* @param {Function} [how] How to log the output provided by morgan. Usually something like log.info.bind( log )
* @returns {Function} The middleware that can be placed in the express pipeline. Also has a "morgan" member, referencing the actual morgan instance.
*/
Logger.prototype.morgan = function( format, options, how ) {
how = how || this.debug.bind( this );
options = options || {};
var Stream = require( "stream" ).Writable;
var logStream = new Stream();
logStream.write = function( data ) {
// Remove trailing newline
data = data.slice( 0, data.length - 1 );
how( data );
};
options.stream = logStream;
var morgan = require( "morgan" )( format, options );
// morgan, morgan, morgan, morgan
morgan.morgan = morgan;
return function( req, res, next ) {
morgan( req, res, next );
}
};
/**
* Enable or disable debug output.
* @param {Boolean} [enable=true] Should debug output be enabled?
*/
Logger.prototype.withSource = function( enable ) {
this.traceLoggingCalls = !!!enable;
return this;
};
/**
* Construct a new Logger instance for a module with the given name.
* @param {String} [moduleName] The name of the module.
* @returns {Logger} The Logger for the module.
*/
Logger.fromModule = function( moduleName ) {
if( !moduleName ) {
var error = new Error().stack;
var matches = error.match( /at Object.<anonymous> .*[\\/](.*?):/ );
if( matches && matches.length >= 2 ) {
moduleName = matches[ 1 ];
}
}
if( moduleName ) {
moduleMaxLength = Math.max( moduleMaxLength, moduleName.length );
}
return new Logger( moduleName );
};
return Logger;
/**
* Create and wrap a morgan instance.+
* @param {String} format The format string to pass to morgan.
* @param {Object} [options] The options object that will be passed to the morgan constructor.
* @param {Function} [how] How to log the output provided by morgan. Usually something like log.info.bind( log )
* @returns {Function} The middleware that can be placed in the express pipeline. Also has a "morgan" member, referencing the actual morgan instance.
*/
Logger.prototype.morgan = function( format, options, how ) {
how = how || this.debug.bind( this );
options = options || {};
var Stream = require( "stream" ).Writable;
var logStream = new Stream();
logStream.write = function( data ) {
// Remove trailing newline
data = data.slice( 0, data.length - 1 );
how( data );
};
options.stream = logStream;
var morgan = require( "morgan" )( format, options );
// morgan, morgan, morgan, morgan
morgan.morgan = morgan;
return function( req, res, next ) {
morgan( req, res, next );
}
};
/**
* Construct a new Logger instance for a module with the given name.
* @param {String} [moduleName] The name of the module.
* @returns {Logger} The Logger for the module.
*/
Logger.fromModule = function( moduleName ) {
if( !moduleName ) {
var error = new Error().stack;
var matches = error.match( /at Object.<anonymous> .*[\\/](.*?):/ );
if( matches && matches.length >= 2 ) {
moduleName = matches[ 1 ];
}
}
if( moduleName ) {
moduleMaxLength = Math.max( moduleMaxLength, moduleName.length );
}
return new Logger( moduleName );
};
return Logger;
}());

@@ -456,0 +458,0 @@

{
"name": "fm-log",
"version": "0.7.4",
"version": "0.8.0",
"description": "Console logging facility for Node",

@@ -25,10 +25,10 @@ "main": "lib/log.js",

"devDependencies": {
"grunt": ">= 0.4.4",
"grunt-contrib-jshint": "~0.10.0",
"grunt": "0.4.5",
"grunt-contrib-jshint": "0.11.0",
"grunt-contrib-watch": "~0.6.1",
"should": "^3.3.1"
"should": "5.0.1"
},
"dependencies": {
"colors": "^0.6.2"
"chalk": "1.0.0"
}
}

@@ -1,119 +0,119 @@

var colors = require( "colors" );
var should = require( 'should' );
var chalk = require( "chalk" );
var should = require( "should" );
describe( "Logger", function() {
var log;
var consoleLogOrig = console.log;
var consoleLog = console.log;
var result;
beforeEach( function() {
result = [];
consoleLog = function() {
result.push( arguments[0].stripColors );
consoleLogOrig.apply( console, arguments );
};
console.log = consoleLog;
} );
afterEach( function() {
consoleLog = consoleLogOrig;
} );
var log;
var consoleLogOrig = console.log;
var consoleLog = console.log;
var result;
beforeEach( function() {
result = [];
consoleLog = function() {
result.push( chalk.stripColor( arguments[ 0 ] ) );
consoleLogOrig.apply( console, arguments );
};
console.log = consoleLog;
} );
afterEach( function() {
consoleLog = consoleLogOrig;
} );
describe( "without prefix", function() {
beforeEach( function() {
log = require( "../lib/log.js" );
} );
describe( "without prefix", function() {
beforeEach( function() {
log = require( "../lib/log.js" );
} );
it( "should log without errors", function( done ) {
log.info( "!" );
result[0].should.match( /\d \[INFO \] !/ );
setTimeout( done, 200 );
} );
it( "should log without errors", function( done ) {
log.info( "!" );
result[ 0 ].should.match( /\d \[INFO ] !/ );
setTimeout( done, 200 );
} );
it( "should log multiline", function( done ) {
log.info( "!\n!" );
result.length.should.equal( 2 );
result[0].should.match( /\d \[INFO \] !/ );
result[1].should.match( /\d !/ );
setTimeout( done, 200 );
} );
it( "should log multiline", function( done ) {
log.info( "!\n!" );
result.length.should.equal( 2 );
result[ 0 ].should.match( /\d \[INFO ] !/ );
result[ 1 ].should.match( /\d !/ );
setTimeout( done, 200 );
} );
it( "should indent all log levels properly", function( done ) {
log.debug( "!" );
result[0].should.match( /\d \[DEBUG \] !/ );
log.info( "!" );
result[1].should.match( /\d \[INFO \] !/ );
log.notice( "!" );
result[2].should.match( /\d \[NOTICE\] !/ );
log.warn( "!" );
result[3].should.match( /\d \[WARN \] !/ );
log.error( "!" );
result[4].should.match( /\d \[ERROR \] !/ );
log.critical( "!" );
result[5].should.match( /\d \[CRITIC\] !/ );
setTimeout( done, 200 );
} );
} );
it( "should indent all log levels properly", function( done ) {
log.debug( "!" );
result[ 0 ].should.match( /\d \[DEBUG ] !/ );
log.info( "!" );
result[ 1 ].should.match( /\d \[INFO ] !/ );
log.notice( "!" );
result[ 2 ].should.match( /\d \[NOTICE] !/ );
log.warn( "!" );
result[ 3 ].should.match( /\d \[WARN ] !/ );
log.error( "!" );
result[ 4 ].should.match( /\d \[ERROR ] !/ );
log.critical( "!" );
result[ 5 ].should.match( /\d \[CRITIC] !/ );
setTimeout( done, 200 );
} );
} );
describe( "with prefix", function() {
beforeEach( function() {
log = require( "../lib/log.js" ).module( "foo" );
} );
describe( "with prefix", function() {
beforeEach( function() {
log = require( "../lib/log.js" ).module( "foo" );
} );
it( "should log without errors", function( done ) {
log.info( "!" );
result[0].should.match( /\d \[INFO \] \(foo\) !/ );
setTimeout( done, 200 );
} );
it( "should log without errors", function( done ) {
log.info( "!" );
result[ 0 ].should.match( /\d \[INFO ] \(foo\) !/ );
setTimeout( done, 200 );
} );
it( "should log multiline", function( done ) {
log.info( "!\n!" );
result.length.should.equal( 2 );
result[0].should.match( /\d \[INFO \] \(foo\) !/ );
result[1].should.match( /\d !/ );
setTimeout( done, 200 );
} );
it( "should log multiline", function( done ) {
log.info( "!\n!" );
result.length.should.equal( 2 );
result[ 0 ].should.match( /\d \[INFO ] \(foo\) !/ );
result[ 1 ].should.match( /\d !/ );
setTimeout( done, 200 );
} );
it( "should indent all log levels properly", function( done ) {
log.debug( "!" );
result[0].should.match( /\d \[DEBUG \] \(foo\) !/ );
log.info( "!" );
result[1].should.match( /\d \[INFO \] \(foo\) !/ );
log.notice( "!" );
result[2].should.match( /\d \[NOTICE\] \(foo\) !/ );
log.warn( "!" );
result[3].should.match( /\d \[WARN \] \(foo\) !/ );
log.error( "!" );
result[4].should.match( /\d \[ERROR \] \(foo\) !/ );
log.critical( "!" );
result[5].should.match( /\d \[CRITIC\] \(foo\) !/ );
setTimeout( done, 200 );
} );
} );
it( "should indent all log levels properly", function( done ) {
log.debug( "!" );
result[ 0 ].should.match( /\d \[DEBUG ] \(foo\) !/ );
log.info( "!" );
result[ 1 ].should.match( /\d \[INFO ] \(foo\) !/ );
log.notice( "!" );
result[ 2 ].should.match( /\d \[NOTICE] \(foo\) !/ );
log.warn( "!" );
result[ 3 ].should.match( /\d \[WARN ] \(foo\) !/ );
log.error( "!" );
result[ 4 ].should.match( /\d \[ERROR ] \(foo\) !/ );
log.critical( "!" );
result[ 5 ].should.match( /\d \[CRITIC] \(foo\) !/ );
setTimeout( done, 200 );
} );
} );
describe( "mixed prefixes", function() {
it( "should log multiline", function( done ) {
log = require( "../lib/log.js" ).module( "module" );
log = require( "../lib/log.js" ).module( "foo" );
log.info( "!\n!" );
result.length.should.equal( 2 );
result[0].should.match( /\d \[INFO \] \( foo\) !/ );
result[1].should.match( /\d !/ );
describe( "mixed prefixes", function() {
it( "should log multiline", function( done ) {
log = require( "../lib/log.js" ).module( "module" );
log = require( "../lib/log.js" ).module( "foo" );
log.info( "!\n!" );
result.length.should.equal( 2 );
result[ 0 ].should.match( /\d \[INFO ] \( foo\) !/ );
result[ 1 ].should.match( /\d !/ );
log = require( "../lib/log.js" );
log.info( "!\n!" );
result.length.should.equal( 4 );
result[2].should.match( /\d \[INFO \] !/ );
result[3].should.match( /\d !/ );
setTimeout( done, 200 );
} );
} );
log = require( "../lib/log.js" );
log.info( "!\n!" );
result.length.should.equal( 4 );
result[ 2 ].should.match( /\d \[INFO ] !/ );
result[ 3 ].should.match( /\d !/ );
setTimeout( done, 200 );
} );
} );
describe( "errors", function() {
it( "should render them properly", function( done ) {
log = require( "../lib/log.js" ).module( "module" );
log.error( new Error( "boom" ) );
setTimeout( done, 200 );
} )
} )
describe( "errors", function() {
it( "should render them properly", function( done ) {
log = require( "../lib/log.js" ).module( "module" );
log.error( new Error( "boom" ) );
setTimeout( done, 200 );
} )
} )
} );
} );

Sorry, the diff of this file is not supported yet

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