mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-12 18:52:50 +00:00
updated package.json
This commit is contained in:
163
node_modules/winston/lib/winston.js
generated
vendored
Normal file
163
node_modules/winston/lib/winston.js
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* winston.js: Top-level include defining Winston.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var winston = exports;
|
||||
|
||||
//
|
||||
// Expose version using `pkginfo`
|
||||
//
|
||||
require('pkginfo')(module, 'version');
|
||||
|
||||
//
|
||||
// Include transports defined by default by winston
|
||||
//
|
||||
winston.transports = require('./winston/transports');
|
||||
|
||||
//
|
||||
// Expose utility methods
|
||||
//
|
||||
var common = require('./winston/common');
|
||||
winston.hash = common.hash;
|
||||
winston.clone = common.clone;
|
||||
winston.longestElement = common.longestElement;
|
||||
winston.exception = require('./winston/exception');
|
||||
winston.config = require('./winston/config');
|
||||
winston.addColors = winston.config.addColors;
|
||||
|
||||
//
|
||||
// Expose core Logging-related prototypes.
|
||||
//
|
||||
winston.Container = require('./winston/container').Container;
|
||||
winston.Logger = require('./winston/logger').Logger;
|
||||
winston.Transport = require('./winston/transports/transport').Transport;
|
||||
|
||||
//
|
||||
// We create and expose a default `Container` to `winston.loggers` so that the
|
||||
// programmer may manage multiple `winston.Logger` instances without any additional overhead.
|
||||
//
|
||||
// ### some-file1.js
|
||||
//
|
||||
// var logger = require('winston').loggers.get('something');
|
||||
//
|
||||
// ### some-file2.js
|
||||
//
|
||||
// var logger = require('winston').loggers.get('something');
|
||||
//
|
||||
winston.loggers = new winston.Container();
|
||||
|
||||
//
|
||||
// We create and expose a 'defaultLogger' so that the programmer may do the
|
||||
// following without the need to create an instance of winston.Logger directly:
|
||||
//
|
||||
// var winston = require('winston');
|
||||
// winston.log('info', 'some message');
|
||||
// winston.error('some error');
|
||||
//
|
||||
var defaultLogger = new winston.Logger({
|
||||
transports: [new winston.transports.Console()]
|
||||
});
|
||||
|
||||
//
|
||||
// Pass through the target methods onto `winston.
|
||||
//
|
||||
var methods = [
|
||||
'log',
|
||||
'query',
|
||||
'stream',
|
||||
'add',
|
||||
'remove',
|
||||
'clear',
|
||||
'profile',
|
||||
'startTimer',
|
||||
'extend',
|
||||
'cli',
|
||||
'handleExceptions',
|
||||
'unhandleExceptions'
|
||||
];
|
||||
common.setLevels(winston, null, defaultLogger.levels);
|
||||
methods.forEach(function (method) {
|
||||
winston[method] = function () {
|
||||
return defaultLogger[method].apply(defaultLogger, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
//
|
||||
// ### function cli ()
|
||||
// Configures the default winston logger to have the
|
||||
// settings for command-line interfaces: no timestamp,
|
||||
// colors enabled, padded output, and additional levels.
|
||||
//
|
||||
winston.cli = function () {
|
||||
winston.padLevels = true;
|
||||
common.setLevels(winston, defaultLogger.levels, winston.config.cli.levels);
|
||||
defaultLogger.setLevels(winston.config.cli.levels);
|
||||
winston.config.addColors(winston.config.cli.colors);
|
||||
|
||||
if (defaultLogger.transports.console) {
|
||||
defaultLogger.transports.console.colorize = true;
|
||||
defaultLogger.transports.console.timestamp = false;
|
||||
}
|
||||
|
||||
return winston;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function setLevels (target)
|
||||
// #### @target {Object} Target levels to use
|
||||
// Sets the `target` levels specified on the default winston logger.
|
||||
//
|
||||
winston.setLevels = function (target) {
|
||||
common.setLevels(winston, defaultLogger.levels, target);
|
||||
defaultLogger.setLevels(target);
|
||||
};
|
||||
|
||||
//
|
||||
// Define getter / setter for the default logger level
|
||||
// which need to be exposed by winston.
|
||||
//
|
||||
Object.defineProperty(winston, 'level', {
|
||||
get: function () {
|
||||
return defaultLogger.level;
|
||||
},
|
||||
set: function (val) {
|
||||
defaultLogger.level = val;
|
||||
|
||||
Object.keys(defaultLogger.transports).forEach(function(key) {
|
||||
defaultLogger.transports[key].level = val;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Define getters / setters for appropriate properties of the
|
||||
// default logger which need to be exposed by winston.
|
||||
//
|
||||
['emitErrs', 'exitOnError', 'padLevels', 'levelLength', 'stripColors'].forEach(function (prop) {
|
||||
Object.defineProperty(winston, prop, {
|
||||
get: function () {
|
||||
return defaultLogger[prop];
|
||||
},
|
||||
set: function (val) {
|
||||
defaultLogger[prop] = val;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// @default {Object}
|
||||
// The default transports and exceptionHandlers for
|
||||
// the default winston logger.
|
||||
//
|
||||
Object.defineProperty(winston, 'default', {
|
||||
get: function () {
|
||||
return {
|
||||
transports: defaultLogger.transports,
|
||||
exceptionHandlers: defaultLogger.exceptionHandlers
|
||||
};
|
||||
}
|
||||
});
|
||||
347
node_modules/winston/lib/winston/common.js
generated
vendored
Normal file
347
node_modules/winston/lib/winston/common.js
generated
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* common.js: Internal helper and utility functions for winston
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
crypto = require('crypto'),
|
||||
cycle = require('cycle'),
|
||||
fs = require('fs'),
|
||||
config = require('./config');
|
||||
|
||||
//
|
||||
// ### function setLevels (target, past, current)
|
||||
// #### @target {Object} Object on which to set levels.
|
||||
// #### @past {Object} Previous levels set on target.
|
||||
// #### @current {Object} Current levels to set on target.
|
||||
// Create functions on the target objects for each level
|
||||
// in current.levels. If past is defined, remove functions
|
||||
// for each of those levels.
|
||||
//
|
||||
exports.setLevels = function (target, past, current, isDefault) {
|
||||
if (past) {
|
||||
Object.keys(past).forEach(function (level) {
|
||||
delete target[level];
|
||||
});
|
||||
}
|
||||
|
||||
target.levels = current || config.npm.levels;
|
||||
if (target.padLevels) {
|
||||
target.levelLength = exports.longestElement(Object.keys(target.levels));
|
||||
}
|
||||
|
||||
//
|
||||
// Define prototype methods for each log level
|
||||
// e.g. target.log('info', msg) <=> target.info(msg)
|
||||
//
|
||||
Object.keys(target.levels).forEach(function (level) {
|
||||
target[level] = function (msg) {
|
||||
// build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
|
||||
var args = [level].concat(Array.prototype.slice.call(arguments));
|
||||
target.log.apply(target, args);
|
||||
};
|
||||
});
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function longestElement
|
||||
// #### @xs {Array} Array to calculate against
|
||||
// Returns the longest element in the `xs` array.
|
||||
//
|
||||
exports.longestElement = function (xs) {
|
||||
return Math.max.apply(
|
||||
null,
|
||||
xs.map(function (x) { return x.length; })
|
||||
);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function clone (obj)
|
||||
// #### @obj {Object} Object to clone.
|
||||
// Helper method for deep cloning pure JSON objects
|
||||
// i.e. JSON objects that are either literals or objects (no Arrays, etc)
|
||||
//
|
||||
exports.clone = function (obj) {
|
||||
// we only need to clone refrence types (Object)
|
||||
if (!(obj instanceof Object)) {
|
||||
return obj;
|
||||
}
|
||||
else if (obj instanceof Date) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
var copy = {};
|
||||
for (var i in obj) {
|
||||
if (Array.isArray(obj[i])) {
|
||||
copy[i] = obj[i].slice(0);
|
||||
}
|
||||
else if (obj[i] instanceof Buffer) {
|
||||
copy[i] = obj[i].slice(0);
|
||||
}
|
||||
else if (typeof obj[i] != 'function') {
|
||||
copy[i] = obj[i] instanceof Object ? exports.clone(obj[i]) : obj[i];
|
||||
}
|
||||
else if (typeof obj[i] === 'function') {
|
||||
copy[i] = obj[i];
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function log (options)
|
||||
// #### @options {Object} All information about the log serialization.
|
||||
// Generic logging function for returning timestamped strings
|
||||
// with the following options:
|
||||
//
|
||||
// {
|
||||
// level: 'level to add to serialized message',
|
||||
// message: 'message to serialize',
|
||||
// meta: 'additional logging metadata to serialize',
|
||||
// colorize: false, // Colorizes output (only if `.json` is false)
|
||||
// timestamp: true // Adds a timestamp to the serialized message
|
||||
// label: 'label to prepend the message'
|
||||
// }
|
||||
//
|
||||
exports.log = function (options) {
|
||||
var timestampFn = typeof options.timestamp === 'function'
|
||||
? options.timestamp
|
||||
: exports.timestamp,
|
||||
timestamp = options.timestamp ? timestampFn() : null,
|
||||
meta = options.meta !== undefined || options.meta !== null ? exports.clone(cycle.decycle(options.meta)) : null,
|
||||
output;
|
||||
|
||||
//
|
||||
// raw mode is intended for outputing winston as streaming JSON to STDOUT
|
||||
//
|
||||
if (options.raw) {
|
||||
if (typeof meta !== 'object' && meta != null) {
|
||||
meta = { meta: meta };
|
||||
}
|
||||
output = exports.clone(meta) || {};
|
||||
output.level = options.level;
|
||||
output.message = options.message.stripColors;
|
||||
return JSON.stringify(output);
|
||||
}
|
||||
|
||||
//
|
||||
// json mode is intended for pretty printing multi-line json to the terminal
|
||||
//
|
||||
if (options.json) {
|
||||
if (typeof meta !== 'object' && meta != null) {
|
||||
meta = { meta: meta };
|
||||
}
|
||||
|
||||
output = exports.clone(meta) || {};
|
||||
output.level = options.level;
|
||||
output.message = options.message;
|
||||
|
||||
if (timestamp) {
|
||||
output.timestamp = timestamp;
|
||||
}
|
||||
|
||||
if (options.logstash === true) {
|
||||
// use logstash format
|
||||
var logstashOutput = {};
|
||||
if (output.message !== undefined) {
|
||||
logstashOutput['@message'] = output.message;
|
||||
delete output.message;
|
||||
}
|
||||
|
||||
if (output.timestamp !== undefined) {
|
||||
logstashOutput['@timestamp'] = output.timestamp;
|
||||
delete output.timestamp;
|
||||
}
|
||||
|
||||
logstashOutput['@fields'] = exports.clone(output);
|
||||
output = logstashOutput;
|
||||
}
|
||||
|
||||
if (typeof options.stringify === 'function') {
|
||||
return options.stringify(output);
|
||||
}
|
||||
|
||||
return JSON.stringify(output, function (key, value) {
|
||||
return value instanceof Buffer
|
||||
? value.toString('base64')
|
||||
: value;
|
||||
});
|
||||
}
|
||||
|
||||
output = timestamp ? timestamp + ' - ' : '';
|
||||
output += options.colorize ? config.colorize(options.level) : options.level;
|
||||
output += ': ';
|
||||
output += options.label ? ('[' + options.label + '] ') : '';
|
||||
output += options.message;
|
||||
|
||||
if (meta !== null && meta !== undefined) {
|
||||
if (meta && meta instanceof Error && meta.stack) {
|
||||
meta = meta.stack;
|
||||
}
|
||||
|
||||
if (typeof meta !== 'object') {
|
||||
output += ' ' + meta;
|
||||
}
|
||||
else if (Object.keys(meta).length > 0) {
|
||||
output += ' ' + (
|
||||
options.prettyPrint
|
||||
? ('\n' + util.inspect(meta, false, null, options.colorize))
|
||||
: exports.serialize(meta)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
exports.capitalize = function (str) {
|
||||
return str && str[0].toUpperCase() + str.slice(1);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function hash (str)
|
||||
// #### @str {string} String to hash.
|
||||
// Utility function for creating unique ids
|
||||
// e.g. Profiling incoming HTTP requests on the same tick
|
||||
//
|
||||
exports.hash = function (str) {
|
||||
return crypto.createHash('sha1').update(str).digest('hex');
|
||||
};
|
||||
|
||||
//
|
||||
// ### function pad (n)
|
||||
// Returns a padded string if `n < 10`.
|
||||
//
|
||||
exports.pad = function (n) {
|
||||
return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function timestamp ()
|
||||
// Returns a timestamp string for the current time.
|
||||
//
|
||||
exports.timestamp = function () {
|
||||
return new Date().toISOString();
|
||||
};
|
||||
|
||||
//
|
||||
// ### function serialize (obj, key)
|
||||
// #### @obj {Object|literal} Object to serialize
|
||||
// #### @key {string} **Optional** Optional key represented by obj in a larger object
|
||||
// Performs simple comma-separated, `key=value` serialization for Loggly when
|
||||
// logging to non-JSON inputs.
|
||||
//
|
||||
exports.serialize = function (obj, key) {
|
||||
if (obj === null) {
|
||||
obj = 'null';
|
||||
}
|
||||
else if (obj === undefined) {
|
||||
obj = 'undefined';
|
||||
}
|
||||
else if (obj === false) {
|
||||
obj = 'false';
|
||||
}
|
||||
|
||||
if (typeof obj !== 'object') {
|
||||
return key ? key + '=' + obj : obj;
|
||||
}
|
||||
|
||||
if (obj instanceof Buffer) {
|
||||
return key ? key + '=' + obj.toString('base64') : obj.toString('base64');
|
||||
}
|
||||
|
||||
var msg = '',
|
||||
keys = Object.keys(obj),
|
||||
length = keys.length;
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (Array.isArray(obj[keys[i]])) {
|
||||
msg += keys[i] + '=[';
|
||||
|
||||
for (var j = 0, l = obj[keys[i]].length; j < l; j++) {
|
||||
msg += exports.serialize(obj[keys[i]][j]);
|
||||
if (j < l - 1) {
|
||||
msg += ', ';
|
||||
}
|
||||
}
|
||||
|
||||
msg += ']';
|
||||
}
|
||||
else if (obj[keys[i]] instanceof Date) {
|
||||
msg += keys[i] + '=' + obj[keys[i]];
|
||||
}
|
||||
else {
|
||||
msg += exports.serialize(obj[keys[i]], keys[i]);
|
||||
}
|
||||
|
||||
if (i < length - 1) {
|
||||
msg += ', ';
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// ### function tailFile (options, callback)
|
||||
// #### @options {Object} Options for tail.
|
||||
// #### @callback {function} Callback to execute on every line.
|
||||
// `tail -f` a file. Options must include file.
|
||||
//
|
||||
exports.tailFile = function tail(options, callback) {
|
||||
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }),
|
||||
buff = '',
|
||||
destroy,
|
||||
row = 0;
|
||||
|
||||
destroy = stream.destroy.bind(stream);
|
||||
stream.destroy = function () {};
|
||||
|
||||
if (options.start === -1) {
|
||||
delete options.start;
|
||||
}
|
||||
|
||||
stream.on('data', function (data) {
|
||||
var data = (buff + data).split(/\n+/),
|
||||
l = data.length - 1,
|
||||
i = 0;
|
||||
|
||||
for (; i < l; i++) {
|
||||
if (options.start == null || row > options.start) {
|
||||
callback(null, data[i]);
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
buff = data[l];
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
callback(err);
|
||||
destroy();
|
||||
});
|
||||
|
||||
stream.on('end', function () {
|
||||
if (buff) {
|
||||
stream.emit('line', buff);
|
||||
buff = '';
|
||||
}
|
||||
|
||||
resume();
|
||||
});
|
||||
|
||||
function resume() {
|
||||
setTimeout(function () {
|
||||
stream.resume();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
return destroy;
|
||||
};
|
||||
59
node_modules/winston/lib/winston/config.js
generated
vendored
Normal file
59
node_modules/winston/lib/winston/config.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* config.js: Default settings for all levels that winston knows about
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var colors = require('colors');
|
||||
|
||||
var config = exports,
|
||||
allColors = exports.allColors = {};
|
||||
|
||||
config.addColors = function (colors) {
|
||||
mixin(allColors, colors);
|
||||
};
|
||||
|
||||
config.colorize = function (level) {
|
||||
var colorized = level;
|
||||
if (allColors[level] instanceof Array) {
|
||||
for (var i = 0, l = allColors[level].length; i < l; ++i) {
|
||||
colorized = colorized[allColors[level][i]];
|
||||
}
|
||||
} else if (allColors[level].match(/\s/)) {
|
||||
var colorArr = allColors[level].split(/\s+/);
|
||||
for (var i = 0; i < colorArr.length; ++i) {
|
||||
colorized = colorized[colorArr[i]];
|
||||
}
|
||||
allColors[level] = colorArr;
|
||||
} else {
|
||||
colorized = colorized[allColors[level]];
|
||||
}
|
||||
return colorized;
|
||||
};
|
||||
|
||||
//
|
||||
// Export config sets
|
||||
//
|
||||
config.cli = require('./config/cli-config');
|
||||
config.npm = require('./config/npm-config');
|
||||
config.syslog = require('./config/syslog-config');
|
||||
|
||||
//
|
||||
// Add colors for pre-defined config sets
|
||||
//
|
||||
config.addColors(config.npm.colors);
|
||||
config.addColors(config.syslog.colors);
|
||||
|
||||
function mixin (target) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
args.forEach(function (a) {
|
||||
var keys = Object.keys(a);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
target[keys[i]] = a[keys[i]];
|
||||
}
|
||||
});
|
||||
return target;
|
||||
};
|
||||
35
node_modules/winston/lib/winston/config/cli-config.js
generated
vendored
Normal file
35
node_modules/winston/lib/winston/config/cli-config.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* cli-config.js: Config that conform to commonly used CLI logging levels.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var cliConfig = exports;
|
||||
|
||||
cliConfig.levels = {
|
||||
silly: 0,
|
||||
input: 1,
|
||||
verbose: 2,
|
||||
prompt: 3,
|
||||
debug: 4,
|
||||
info: 5,
|
||||
data: 6,
|
||||
help: 7,
|
||||
warn: 8,
|
||||
error: 9
|
||||
};
|
||||
|
||||
cliConfig.colors = {
|
||||
silly: 'magenta',
|
||||
input: 'grey',
|
||||
verbose: 'cyan',
|
||||
prompt: 'grey',
|
||||
debug: 'blue',
|
||||
info: 'green',
|
||||
data: 'grey',
|
||||
help: 'cyan',
|
||||
warn: 'yellow',
|
||||
error: 'red'
|
||||
};
|
||||
27
node_modules/winston/lib/winston/config/npm-config.js
generated
vendored
Normal file
27
node_modules/winston/lib/winston/config/npm-config.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* npm-config.js: Config that conform to npm logging levels.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var npmConfig = exports;
|
||||
|
||||
npmConfig.levels = {
|
||||
silly: 0,
|
||||
debug: 1,
|
||||
verbose: 2,
|
||||
info: 3,
|
||||
warn: 4,
|
||||
error: 5
|
||||
};
|
||||
|
||||
npmConfig.colors = {
|
||||
silly: 'magenta',
|
||||
verbose: 'cyan',
|
||||
debug: 'blue',
|
||||
info: 'green',
|
||||
warn: 'yellow',
|
||||
error: 'red'
|
||||
};
|
||||
31
node_modules/winston/lib/winston/config/syslog-config.js
generated
vendored
Normal file
31
node_modules/winston/lib/winston/config/syslog-config.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* syslog-config.js: Config that conform to syslog logging levels.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var syslogConfig = exports;
|
||||
|
||||
syslogConfig.levels = {
|
||||
emerg: 0,
|
||||
alert: 1,
|
||||
crit: 2,
|
||||
error: 3,
|
||||
warning: 4,
|
||||
notice: 5,
|
||||
info: 6,
|
||||
debug: 7,
|
||||
};
|
||||
|
||||
syslogConfig.colors = {
|
||||
emerg: 'red',
|
||||
alert: 'yellow',
|
||||
crit: 'red',
|
||||
error: 'red',
|
||||
warning: 'red',
|
||||
notice: 'yellow',
|
||||
info: 'green',
|
||||
debug: 'blue',
|
||||
};
|
||||
112
node_modules/winston/lib/winston/container.js
generated
vendored
Normal file
112
node_modules/winston/lib/winston/container.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* container.js: Inversion of control container for winston logger instances
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var common = require('./common'),
|
||||
winston = require('../winston'),
|
||||
extend = require('util')._extend;
|
||||
|
||||
//
|
||||
// ### function Container (options)
|
||||
// #### @options {Object} Default pass-thru options for Loggers
|
||||
// Constructor function for the Container object responsible for managing
|
||||
// a set of `winston.Logger` instances based on string ids.
|
||||
//
|
||||
var Container = exports.Container = function (options) {
|
||||
this.loggers = {};
|
||||
this.options = options || {};
|
||||
this.default = {
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
level: 'silly',
|
||||
colorize: false
|
||||
})
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function get / add (id, options)
|
||||
// #### @id {string} Id of the Logger to get
|
||||
// #### @options {Object} **Optional** Options for the Logger instance
|
||||
// Retreives a `winston.Logger` instance for the specified `id`. If
|
||||
// an instance does not exist, one is created.
|
||||
//
|
||||
Container.prototype.get = Container.prototype.add = function (id, options) {
|
||||
var existing;
|
||||
if (!this.loggers[id]) {
|
||||
//
|
||||
// Remark: Simple shallow clone for configuration options in case we pass in
|
||||
// instantiated protoypal objects
|
||||
//
|
||||
options = extend({}, options || this.options || this.default);
|
||||
existing = options.transports || this.options.transports;
|
||||
//
|
||||
// Remark: Make sure if we have an array of transports we slice it to make copies
|
||||
// of those references.
|
||||
//
|
||||
options.transports = existing ? existing.slice() : [];
|
||||
|
||||
if (options.transports.length === 0 && (!options || !options['console'])) {
|
||||
options.transports.push(this.default.transports[0]);
|
||||
}
|
||||
|
||||
Object.keys(options).forEach(function (key) {
|
||||
if (key === 'transports') {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = common.capitalize(key);
|
||||
|
||||
if (!winston.transports[name]) {
|
||||
throw new Error('Cannot add unknown transport: ' + name);
|
||||
}
|
||||
|
||||
var namedOptions = options[key];
|
||||
namedOptions.id = id;
|
||||
options.transports.push(new (winston.transports[name])(namedOptions));
|
||||
});
|
||||
|
||||
this.loggers[id] = new winston.Logger(options);
|
||||
}
|
||||
|
||||
return this.loggers[id];
|
||||
};
|
||||
|
||||
//
|
||||
// ### function close (id)
|
||||
// #### @id {string} **Optional** Id of the Logger instance to find
|
||||
// Returns a boolean value indicating if this instance
|
||||
// has a logger with the specified `id`.
|
||||
//
|
||||
Container.prototype.has = function (id) {
|
||||
return !!this.loggers[id];
|
||||
};
|
||||
|
||||
//
|
||||
// ### function close (id)
|
||||
// #### @id {string} **Optional** Id of the Logger instance to close
|
||||
// Closes a `Logger` instance with the specified `id` if it exists.
|
||||
// If no `id` is supplied then all Loggers are closed.
|
||||
//
|
||||
Container.prototype.close = function (id) {
|
||||
var self = this;
|
||||
|
||||
function _close (id) {
|
||||
if (!self.loggers[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.loggers[id].close();
|
||||
delete self.loggers[id];
|
||||
}
|
||||
|
||||
return id ? _close(id) : Object.keys(this.loggers).forEach(function (id) {
|
||||
_close(id);
|
||||
});
|
||||
};
|
||||
|
||||
56
node_modules/winston/lib/winston/exception.js
generated
vendored
Normal file
56
node_modules/winston/lib/winston/exception.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* exception.js: Utility methods for gathing information about uncaughtExceptions.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var os = require('os'),
|
||||
stackTrace = require('stack-trace');
|
||||
|
||||
var exception = exports;
|
||||
|
||||
exception.getAllInfo = function (err) {
|
||||
return {
|
||||
date: new Date().toString(),
|
||||
process: exception.getProcessInfo(),
|
||||
os: exception.getOsInfo(),
|
||||
trace: exception.getTrace(err),
|
||||
stack: err.stack && err.stack.split('\n')
|
||||
};
|
||||
};
|
||||
|
||||
exception.getProcessInfo = function () {
|
||||
return {
|
||||
pid: process.pid,
|
||||
uid: process.getuid ? process.getuid() : null,
|
||||
gid: process.getgid ? process.getgid() : null,
|
||||
cwd: process.cwd(),
|
||||
execPath: process.execPath,
|
||||
version: process.version,
|
||||
argv: process.argv,
|
||||
memoryUsage: process.memoryUsage()
|
||||
};
|
||||
};
|
||||
|
||||
exception.getOsInfo = function () {
|
||||
return {
|
||||
loadavg: os.loadavg(),
|
||||
uptime: os.uptime()
|
||||
};
|
||||
};
|
||||
|
||||
exception.getTrace = function (err) {
|
||||
var trace = err ? stackTrace.parse(err) : stackTrace.get();
|
||||
return trace.map(function (site) {
|
||||
return {
|
||||
column: site.getColumnNumber(),
|
||||
file: site.getFileName(),
|
||||
function: site.getFunctionName(),
|
||||
line: site.getLineNumber(),
|
||||
method: site.getMethodName(),
|
||||
native: site.isNative(),
|
||||
}
|
||||
});
|
||||
};
|
||||
665
node_modules/winston/lib/winston/logger.js
generated
vendored
Executable file
665
node_modules/winston/lib/winston/logger.js
generated
vendored
Executable file
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* logger.js: Core logger object used by winston.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
util = require('util'),
|
||||
async = require('async'),
|
||||
config = require('./config'),
|
||||
common = require('./common'),
|
||||
exception = require('./exception'),
|
||||
Stream = require('stream').Stream;
|
||||
|
||||
//
|
||||
// Time constants
|
||||
//
|
||||
var ticksPerMillisecond = 10000;
|
||||
|
||||
//
|
||||
// ### function Logger (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Logger object responsible
|
||||
// for persisting log messages and metadata to one or more transports.
|
||||
//
|
||||
var Logger = exports.Logger = function (options) {
|
||||
events.EventEmitter.call(this);
|
||||
options = options || {};
|
||||
|
||||
var self = this,
|
||||
handleExceptions = false;
|
||||
|
||||
//
|
||||
// Set Levels and default logging level
|
||||
//
|
||||
this.padLevels = options.padLevels || false;
|
||||
this.setLevels(options.levels);
|
||||
if (options.colors) {
|
||||
config.addColors(options.colors);
|
||||
}
|
||||
|
||||
//
|
||||
// Hoist other options onto this instance.
|
||||
//
|
||||
this.level = options.level || 'info';
|
||||
this.emitErrs = options.emitErrs || false;
|
||||
this.stripColors = options.stripColors || false;
|
||||
this.exitOnError = typeof options.exitOnError !== 'undefined'
|
||||
? options.exitOnError
|
||||
: true;
|
||||
|
||||
//
|
||||
// Setup other intelligent default settings.
|
||||
//
|
||||
this.transports = {};
|
||||
this.rewriters = [];
|
||||
this.exceptionHandlers = {};
|
||||
this.profilers = {};
|
||||
this._names = [];
|
||||
this._hnames = [];
|
||||
|
||||
if (options.transports) {
|
||||
options.transports.forEach(function (transport) {
|
||||
self.add(transport, null, true);
|
||||
|
||||
if (transport.handleExceptions) {
|
||||
handleExceptions = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.rewriters) {
|
||||
options.rewriters.forEach(function (rewriter) {
|
||||
self.addRewriter(rewriter);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.exceptionHandlers) {
|
||||
handleExceptions = true;
|
||||
options.exceptionHandlers.forEach(function (handler) {
|
||||
self._hnames.push(handler.name);
|
||||
self.exceptionHandlers[handler.name] = handler;
|
||||
});
|
||||
}
|
||||
|
||||
if (options.handleExceptions || handleExceptions) {
|
||||
this.handleExceptions();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `events.EventEmitter`.
|
||||
//
|
||||
util.inherits(Logger, events.EventEmitter);
|
||||
|
||||
//
|
||||
// ### function extend (target)
|
||||
// #### @target {Object} Target to extend.
|
||||
// Extends the target object with a 'log' method
|
||||
// along with a method for each level in this instance.
|
||||
//
|
||||
Logger.prototype.extend = function (target) {
|
||||
var self = this;
|
||||
['log', 'profile', 'startTimer'].concat(Object.keys(this.levels)).forEach(function (method) {
|
||||
target[method] = function () {
|
||||
return self[method].apply(self, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
Logger.prototype.log = function (level) {
|
||||
var self = this,
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
while(args[args.length - 1] === null) {
|
||||
args.pop();
|
||||
}
|
||||
|
||||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
|
||||
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {},
|
||||
msg = util.format.apply(null, args);
|
||||
|
||||
// If we should pad for levels, do so
|
||||
if (this.padLevels) {
|
||||
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
|
||||
}
|
||||
|
||||
function onError (err) {
|
||||
if (callback) {
|
||||
callback(err);
|
||||
}
|
||||
else if (self.emitErrs) {
|
||||
self.emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.transports.length === 0) {
|
||||
return onError(new Error('Cannot log with no transports.'));
|
||||
}
|
||||
else if (typeof self.levels[level] === 'undefined') {
|
||||
return onError(new Error('Unknown log level: ' + level));
|
||||
}
|
||||
|
||||
this.rewriters.forEach(function (rewriter) {
|
||||
meta = rewriter(level, msg, meta);
|
||||
});
|
||||
|
||||
//
|
||||
// For consideration of terminal 'color" programs like colors.js,
|
||||
// which can add ANSI escape color codes to strings, we destyle the
|
||||
// ANSI color escape codes when `this.stripColors` is set.
|
||||
//
|
||||
// see: http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
//
|
||||
if (this.stripColors) {
|
||||
var code = /\u001b\[(\d+(;\d+)*)?m/g;
|
||||
msg = ('' + msg).replace(code, '');
|
||||
}
|
||||
|
||||
//
|
||||
// Log for each transport and emit 'logging' event
|
||||
//
|
||||
function emit(name, next) {
|
||||
var transport = self.transports[name];
|
||||
if ((transport.level && self.levels[transport.level] <= self.levels[level])
|
||||
|| (!transport.level && self.levels[self.level] <= self.levels[level])) {
|
||||
transport.log(level, msg, meta, function (err) {
|
||||
if (err) {
|
||||
err.transport = transport;
|
||||
cb(err);
|
||||
return next();
|
||||
}
|
||||
self.emit('logging', transport, level, msg, meta);
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Respond to the callback
|
||||
//
|
||||
function cb(err) {
|
||||
if (callback) {
|
||||
if (err) return callback(err);
|
||||
callback(null, level, msg, meta);
|
||||
}
|
||||
callback = null;
|
||||
if (!err) {
|
||||
self.emit('logged', level, msg, meta);
|
||||
}
|
||||
}
|
||||
|
||||
async.forEach(this._names, emit, cb);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function query (options, callback)
|
||||
// #### @options {Object} Query options for this instance.
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Queries the all transports for this instance with the specified `options`.
|
||||
// This will aggregate each transport's results into one object containing
|
||||
// a property per transport.
|
||||
//
|
||||
Logger.prototype.query = function (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
var self = this,
|
||||
options = options || {},
|
||||
results = {},
|
||||
query = common.clone(options.query) || {},
|
||||
transports;
|
||||
|
||||
//
|
||||
// Helper function to query a single transport
|
||||
//
|
||||
function queryTransport(transport, next) {
|
||||
if (options.query) {
|
||||
options.query = transport.formatQuery(query);
|
||||
}
|
||||
|
||||
transport.query(options, function (err, results) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
next(null, transport.formatResults(results, options.format));
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Helper function to accumulate the results from
|
||||
// `queryTransport` into the `results`.
|
||||
//
|
||||
function addResults (transport, next) {
|
||||
queryTransport(transport, function (err, result) {
|
||||
result = err || result;
|
||||
if (result) {
|
||||
results[transport.name] = result;
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// If an explicit transport is being queried then
|
||||
// respond with the results from only that transport
|
||||
//
|
||||
if (options.transport) {
|
||||
options.transport = options.transport.toLowerCase();
|
||||
return queryTransport(this.transports[options.transport], callback);
|
||||
}
|
||||
|
||||
//
|
||||
// Create a list of all transports for this instance.
|
||||
//
|
||||
transports = this._names.map(function (name) {
|
||||
return self.transports[name];
|
||||
}).filter(function (transport) {
|
||||
return !!transport.query;
|
||||
});
|
||||
|
||||
//
|
||||
// Iterate over the transports in parallel setting the
|
||||
// appropriate key in the `results`
|
||||
//
|
||||
async.forEach(transports, addResults, function () {
|
||||
callback(null, results);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function stream (options)
|
||||
// #### @options {Object} Stream options for this instance.
|
||||
// Returns a log stream for all transports. Options object is optional.
|
||||
//
|
||||
Logger.prototype.stream = function (options) {
|
||||
var self = this,
|
||||
options = options || {},
|
||||
out = new Stream,
|
||||
streams = [],
|
||||
transports;
|
||||
|
||||
if (options.transport) {
|
||||
var transport = this.transports[options.transport];
|
||||
delete options.transport;
|
||||
if (transport && transport.stream) {
|
||||
return transport.stream(options);
|
||||
}
|
||||
}
|
||||
|
||||
out._streams = streams;
|
||||
out.destroy = function () {
|
||||
var i = streams.length;
|
||||
while (i--) streams[i].destroy();
|
||||
};
|
||||
|
||||
//
|
||||
// Create a list of all transports for this instance.
|
||||
//
|
||||
transports = this._names.map(function (name) {
|
||||
return self.transports[name];
|
||||
}).filter(function (transport) {
|
||||
return !!transport.stream;
|
||||
});
|
||||
|
||||
transports.forEach(function (transport) {
|
||||
var stream = transport.stream(options);
|
||||
if (!stream) return;
|
||||
|
||||
streams.push(stream);
|
||||
|
||||
stream.on('log', function (log) {
|
||||
log.transport = log.transport || [];
|
||||
log.transport.push(transport.name);
|
||||
out.emit('log', log);
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
err.transport = err.transport || [];
|
||||
err.transport.push(transport.name);
|
||||
out.emit('error', err);
|
||||
});
|
||||
});
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function close ()
|
||||
// Cleans up resources (streams, event listeners) for all
|
||||
// transports associated with this instance (if necessary).
|
||||
//
|
||||
Logger.prototype.close = function () {
|
||||
var self = this;
|
||||
|
||||
this._names.forEach(function (name) {
|
||||
var transport = self.transports[name];
|
||||
if (transport && transport.close) {
|
||||
transport.close();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function handleExceptions ()
|
||||
// Handles `uncaughtException` events for the current process
|
||||
//
|
||||
Logger.prototype.handleExceptions = function () {
|
||||
var args = Array.prototype.slice.call(arguments),
|
||||
handlers = [],
|
||||
self = this;
|
||||
|
||||
args.forEach(function (a) {
|
||||
if (Array.isArray(a)) {
|
||||
handlers = handlers.concat(a);
|
||||
}
|
||||
else {
|
||||
handlers.push(a);
|
||||
}
|
||||
});
|
||||
|
||||
handlers.forEach(function (handler) {
|
||||
self.exceptionHandlers[handler.name] = handler;
|
||||
});
|
||||
|
||||
this._hnames = Object.keys(self.exceptionHandlers);
|
||||
|
||||
if (!this.catchExceptions) {
|
||||
this.catchExceptions = this._uncaughtException.bind(this);
|
||||
process.on('uncaughtException', this.catchExceptions);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function unhandleExceptions ()
|
||||
// Removes any handlers to `uncaughtException` events
|
||||
// for the current process
|
||||
//
|
||||
Logger.prototype.unhandleExceptions = function () {
|
||||
var self = this;
|
||||
|
||||
if (this.catchExceptions) {
|
||||
Object.keys(this.exceptionHandlers).forEach(function (name) {
|
||||
var handler = self.exceptionHandlers[name];
|
||||
if (handler.close) {
|
||||
handler.close();
|
||||
}
|
||||
});
|
||||
|
||||
this.exceptionHandlers = {};
|
||||
Object.keys(this.transports).forEach(function (name) {
|
||||
var transport = self.transports[name];
|
||||
if (transport.handleExceptions) {
|
||||
transport.handleExceptions = false;
|
||||
}
|
||||
})
|
||||
|
||||
process.removeListener('uncaughtException', this.catchExceptions);
|
||||
this.catchExceptions = false;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function add (transport, [options])
|
||||
// #### @transport {Transport} Prototype of the Transport object to add.
|
||||
// #### @options {Object} **Optional** Options for the Transport to add.
|
||||
// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
|
||||
// Adds a transport of the specified type to this instance.
|
||||
//
|
||||
Logger.prototype.add = function (transport, options, created) {
|
||||
var instance = created ? transport : (new (transport)(options));
|
||||
|
||||
if (!instance.name && !instance.log) {
|
||||
throw new Error('Unknown transport with no log() method');
|
||||
}
|
||||
else if (this.transports[instance.name]) {
|
||||
throw new Error('Transport already attached: ' + instance.name);
|
||||
}
|
||||
|
||||
this.transports[instance.name] = instance;
|
||||
this._names = Object.keys(this.transports);
|
||||
|
||||
//
|
||||
// Listen for the `error` event on the new Transport
|
||||
//
|
||||
instance._onError = this._onError.bind(this, instance)
|
||||
instance.on('error', instance._onError);
|
||||
|
||||
//
|
||||
// If this transport has `handleExceptions` set to `true`
|
||||
// and we are not already handling exceptions, do so.
|
||||
//
|
||||
if (instance.handleExceptions && !this.catchExceptions) {
|
||||
this.handleExceptions();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function addRewriter (transport, [options])
|
||||
// #### @transport {Transport} Prototype of the Transport object to add.
|
||||
// #### @options {Object} **Optional** Options for the Transport to add.
|
||||
// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
|
||||
// Adds a transport of the specified type to this instance.
|
||||
//
|
||||
Logger.prototype.addRewriter = function (rewriter) {
|
||||
this.rewriters.push(rewriter);
|
||||
}
|
||||
|
||||
//
|
||||
// ### function clear ()
|
||||
// Remove all transports from this instance
|
||||
//
|
||||
Logger.prototype.clear = function () {
|
||||
for (var name in this.transports) {
|
||||
this.remove({ name: name });
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function remove (transport)
|
||||
// #### @transport {Transport} Transport to remove.
|
||||
// Removes a transport of the specified type from this instance.
|
||||
//
|
||||
Logger.prototype.remove = function (transport) {
|
||||
var name = transport.name || transport.prototype.name;
|
||||
|
||||
if (!this.transports[name]) {
|
||||
throw new Error('Transport ' + name + ' not attached to this instance');
|
||||
}
|
||||
|
||||
var instance = this.transports[name];
|
||||
delete this.transports[name];
|
||||
this._names = Object.keys(this.transports);
|
||||
|
||||
if (instance.close) {
|
||||
instance.close();
|
||||
}
|
||||
|
||||
instance.removeListener('error', instance._onError);
|
||||
return this;
|
||||
};
|
||||
|
||||
var ProfileHandler = function (logger) {
|
||||
this.logger = logger;
|
||||
|
||||
this.start = Date.now();
|
||||
|
||||
this.done = function (msg) {
|
||||
var args, callback, meta;
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
|
||||
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
|
||||
|
||||
meta.duration = (Date.now()) - this.start + 'ms';
|
||||
|
||||
return this.logger.info(msg, meta, callback);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.prototype.startTimer = function () {
|
||||
return new ProfileHandler(this);
|
||||
}
|
||||
|
||||
//
|
||||
// ### function profile (id, [msg, meta, callback])
|
||||
// #### @id {string} Unique id of the profiler
|
||||
// #### @msg {string} **Optional** Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} **Optional** Continuation to respond to when complete.
|
||||
// Tracks the time inbetween subsequent calls to this method
|
||||
// with the same `id` parameter. The second call to this method
|
||||
// will log the difference in milliseconds along with the message.
|
||||
//
|
||||
Logger.prototype.profile = function (id) {
|
||||
var now = Date.now(), then, args,
|
||||
msg, meta, callback;
|
||||
|
||||
if (this.profilers[id]) {
|
||||
then = this.profilers[id];
|
||||
delete this.profilers[id];
|
||||
|
||||
// Support variable arguments: msg, meta, callback
|
||||
args = Array.prototype.slice.call(arguments);
|
||||
callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
|
||||
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
|
||||
msg = args.length === 2 ? args[1] : id;
|
||||
|
||||
// Set the duration property of the metadata
|
||||
meta.duration = now - then + 'ms';
|
||||
return this.info(msg, meta, callback);
|
||||
}
|
||||
else {
|
||||
this.profilers[id] = now;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function setLevels (target)
|
||||
// #### @target {Object} Target levels to use on this instance
|
||||
// Sets the `target` levels specified on this instance.
|
||||
//
|
||||
Logger.prototype.setLevels = function (target) {
|
||||
return common.setLevels(this, this.levels, target);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function cli ()
|
||||
// Configures this instance to have the default
|
||||
// settings for command-line interfaces: no timestamp,
|
||||
// colors enabled, padded output, and additional levels.
|
||||
//
|
||||
Logger.prototype.cli = function () {
|
||||
this.padLevels = true;
|
||||
this.setLevels(config.cli.levels);
|
||||
config.addColors(config.cli.colors);
|
||||
|
||||
if (this.transports.console) {
|
||||
this.transports.console.colorize = true;
|
||||
this.transports.console.timestamp = false;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _uncaughtException (err)
|
||||
// #### @err {Error} Error to handle
|
||||
// Logs all relevant information around the `err` and
|
||||
// exits the current process.
|
||||
//
|
||||
Logger.prototype._uncaughtException = function (err) {
|
||||
var self = this,
|
||||
responded = false,
|
||||
info = exception.getAllInfo(err),
|
||||
handlers = this._getExceptionHandlers(),
|
||||
timeout,
|
||||
doExit;
|
||||
|
||||
//
|
||||
// Calculate if we should exit on this error
|
||||
//
|
||||
doExit = typeof this.exitOnError === 'function'
|
||||
? this.exitOnError(err)
|
||||
: this.exitOnError;
|
||||
|
||||
function logAndWait(transport, next) {
|
||||
transport.logException('uncaughtException: ' + err.message, info, next, err);
|
||||
}
|
||||
|
||||
function gracefulExit() {
|
||||
if (doExit && !responded) {
|
||||
//
|
||||
// Remark: Currently ignoring any exceptions from transports
|
||||
// when catching uncaught exceptions.
|
||||
//
|
||||
clearTimeout(timeout);
|
||||
responded = true;
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handlers || handlers.length === 0) {
|
||||
return gracefulExit();
|
||||
}
|
||||
|
||||
//
|
||||
// Log to all transports and allow the operation to take
|
||||
// only up to `3000ms`.
|
||||
//
|
||||
async.forEach(handlers, logAndWait, gracefulExit);
|
||||
if (doExit) {
|
||||
timeout = setTimeout(gracefulExit, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _getExceptionHandlers ()
|
||||
// Returns the list of transports and exceptionHandlers
|
||||
// for this instance.
|
||||
//
|
||||
Logger.prototype._getExceptionHandlers = function () {
|
||||
var self = this;
|
||||
|
||||
return this._hnames.map(function (name) {
|
||||
return self.exceptionHandlers[name];
|
||||
}).concat(this._names.map(function (name) {
|
||||
return self.transports[name].handleExceptions && self.transports[name];
|
||||
})).filter(Boolean);
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _onError (transport, err)
|
||||
// #### @transport {Object} Transport on which the error occured
|
||||
// #### @err {Error} Error that occurred on the transport
|
||||
// Bubbles the error, `err`, that occured on the specified `transport`
|
||||
// up from this instance if `emitErrs` has been set.
|
||||
//
|
||||
Logger.prototype._onError = function (transport, err) {
|
||||
if (this.emitErrs) {
|
||||
this.emit('error', err, transport);
|
||||
}
|
||||
};
|
||||
34
node_modules/winston/lib/winston/transports.js
generated
vendored
Normal file
34
node_modules/winston/lib/winston/transports.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* transports.js: Set of all transports Winston knows about
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
common = require('./common');
|
||||
|
||||
var transports = exports;
|
||||
|
||||
//
|
||||
// Setup all transports as lazy-loaded getters.
|
||||
//
|
||||
fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) {
|
||||
var transport = file.replace('.js', ''),
|
||||
name = common.capitalize(transport);
|
||||
|
||||
if (transport === 'transport') {
|
||||
return;
|
||||
}
|
||||
else if (~transport.indexOf('-')) {
|
||||
name = transport.split('-').map(function (part) {
|
||||
return common.capitalize(part);
|
||||
}).join('');
|
||||
}
|
||||
|
||||
transports.__defineGetter__(name, function () {
|
||||
return require('./transports/' + transport)[name];
|
||||
});
|
||||
});
|
||||
89
node_modules/winston/lib/winston/transports/console.js
generated
vendored
Normal file
89
node_modules/winston/lib/winston/transports/console.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* console.js: Transport for outputting to the console
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
util = require('util'),
|
||||
colors = require('colors'),
|
||||
common = require('../common'),
|
||||
Transport = require('./transport').Transport;
|
||||
|
||||
//
|
||||
// ### function Console (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Console transport object responsible
|
||||
// for persisting log messages and metadata to a terminal or TTY.
|
||||
//
|
||||
var Console = exports.Console = function (options) {
|
||||
Transport.call(this, options);
|
||||
options = options || {};
|
||||
|
||||
this.json = options.json || false;
|
||||
this.colorize = options.colorize || false;
|
||||
this.prettyPrint = options.prettyPrint || false;
|
||||
this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
|
||||
this.label = options.label || null;
|
||||
|
||||
if (this.json) {
|
||||
this.stringify = options.stringify || function (obj) {
|
||||
return JSON.stringify(obj, null, 2);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `winston.Transport`.
|
||||
//
|
||||
util.inherits(Console, Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
Console.prototype.name = 'console';
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
Console.prototype.log = function (level, msg, meta, callback) {
|
||||
if (this.silent) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
var self = this,
|
||||
output;
|
||||
|
||||
output = common.log({
|
||||
colorize: this.colorize,
|
||||
json: this.json,
|
||||
level: level,
|
||||
message: msg,
|
||||
meta: meta,
|
||||
stringify: this.stringify,
|
||||
timestamp: this.timestamp,
|
||||
prettyPrint: this.prettyPrint,
|
||||
raw: this.raw,
|
||||
label: this.label
|
||||
});
|
||||
|
||||
if (level === 'error' || level === 'debug') {
|
||||
process.stderr.write(output + '\n');
|
||||
} else {
|
||||
process.stdout.write(output + '\n');
|
||||
}
|
||||
|
||||
//
|
||||
// Emit the `logged` event immediately because the event loop
|
||||
// will not exit until `process.stdout` has drained anyway.
|
||||
//
|
||||
self.emit('logged');
|
||||
callback(null, true);
|
||||
};
|
||||
569
node_modules/winston/lib/winston/transports/daily-rotate-file.js
generated
vendored
Normal file
569
node_modules/winston/lib/winston/transports/daily-rotate-file.js
generated
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* daily-rotate-file.js: Transport for outputting to a local log file
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
util = require('util'),
|
||||
colors = require('colors'),
|
||||
common = require('../common'),
|
||||
Transport = require('./transport').Transport,
|
||||
Stream = require('stream').Stream;
|
||||
|
||||
//
|
||||
// ### function DailyRotateFile (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the DailyRotateFile transport object responsible
|
||||
// for persisting log messages and metadata to one or more files.
|
||||
//
|
||||
var DailyRotateFile = exports.DailyRotateFile = function (options) {
|
||||
Transport.call(this, options);
|
||||
|
||||
//
|
||||
// Helper function which throws an `Error` in the event
|
||||
// that any of the rest of the arguments is present in `options`.
|
||||
//
|
||||
function throwIf (target /*, illegal... */) {
|
||||
Array.prototype.slice.call(arguments, 1).forEach(function (name) {
|
||||
if (options[name]) {
|
||||
throw new Error('Cannot set ' + name + ' and ' + target + 'together');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.filename || options.dirname) {
|
||||
throwIf('filename or dirname', 'stream');
|
||||
this._basename = this.filename = options.filename
|
||||
? path.basename(options.filename)
|
||||
: 'winston.log';
|
||||
|
||||
this.dirname = options.dirname || path.dirname(options.filename);
|
||||
this.options = options.options || { flags: 'a' };
|
||||
|
||||
//
|
||||
// "24 bytes" is maybe a good value for logging lines.
|
||||
//
|
||||
this.options.highWaterMark = this.options.highWaterMark || 24;
|
||||
}
|
||||
else if (options.stream) {
|
||||
throwIf('stream', 'filename', 'maxsize');
|
||||
this._stream = options.stream;
|
||||
|
||||
//
|
||||
// We need to listen for drain events when
|
||||
// write() returns false. This can make node
|
||||
// mad at times.
|
||||
//
|
||||
this._stream.setMaxListeners(Infinity);
|
||||
}
|
||||
else {
|
||||
throw new Error('Cannot log to file without filename or stream.');
|
||||
}
|
||||
|
||||
this.json = options.json !== false;
|
||||
this.colorize = options.colorize || false;
|
||||
this.maxsize = options.maxsize || null;
|
||||
this.maxFiles = options.maxFiles || null;
|
||||
this.prettyPrint = options.prettyPrint || false;
|
||||
this.timestamp = options.timestamp != null ? options.timestamp : true;
|
||||
this.datePattern = options.datePattern != null ? options.datePattern : '.yyyy-MM-dd';
|
||||
|
||||
if (this.json) {
|
||||
this.stringify = options.stringify;
|
||||
}
|
||||
|
||||
//
|
||||
// Internal state variables representing the number
|
||||
// of files this instance has created and the current
|
||||
// size (in bytes) of the current logfile.
|
||||
//
|
||||
this._size = 0;
|
||||
this._created = 0;
|
||||
this._buffer = [];
|
||||
this._draining = false;
|
||||
|
||||
var now = new Date();
|
||||
this._year = now.getFullYear();
|
||||
this._month = now.getMonth();
|
||||
this._date = now.getDate();
|
||||
this._hour = now.getHours();
|
||||
this._minute = now.getMinutes();
|
||||
|
||||
var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhM])\1?/g,
|
||||
pad = function (val, len) {
|
||||
val = String(val);
|
||||
len = len || 2;
|
||||
while (val.length < len) val = "0" + val;
|
||||
return val;
|
||||
};
|
||||
|
||||
this.getFormattedDate = function() {
|
||||
var flags = {
|
||||
yy: String(this._year).slice(2),
|
||||
yyyy: this._year,
|
||||
M: this._month + 1,
|
||||
MM: pad(this._month + 1),
|
||||
d: this._date,
|
||||
dd: pad(this._date),
|
||||
H: this._hour,
|
||||
HH: pad(this._hour),
|
||||
m: this._minute,
|
||||
mm: pad(this._minute)
|
||||
};
|
||||
return this.datePattern.replace(token, function ($0) {
|
||||
return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `winston.Transport`.
|
||||
//
|
||||
util.inherits(DailyRotateFile, Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
DailyRotateFile.prototype.name = 'dailyRotateFile';
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
DailyRotateFile.prototype.log = function (level, msg, meta, callback) {
|
||||
if (this.silent) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
var output = common.log({
|
||||
level: level,
|
||||
message: msg,
|
||||
meta: meta,
|
||||
json: this.json,
|
||||
colorize: this.colorize,
|
||||
prettyPrint: this.prettyPrint,
|
||||
timestamp: this.timestamp,
|
||||
stringify: this.stringify
|
||||
}) + '\n';
|
||||
|
||||
this._size += output.length;
|
||||
|
||||
if (!this.filename) {
|
||||
//
|
||||
// If there is no `filename` on this instance then it was configured
|
||||
// with a raw `WriteableStream` instance and we should not perform any
|
||||
// size restrictions.
|
||||
//
|
||||
this._write(output, callback);
|
||||
this._lazyDrain();
|
||||
}
|
||||
else {
|
||||
this.open(function (err) {
|
||||
if (err) {
|
||||
//
|
||||
// If there was an error enqueue the message
|
||||
//
|
||||
return self._buffer.push([output, callback]);
|
||||
}
|
||||
|
||||
self._write(output, callback);
|
||||
self._lazyDrain();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function _write (data, cb)
|
||||
// #### @data {String|Buffer} Data to write to the instance's stream.
|
||||
// #### @cb {function} Continuation to respond to when complete.
|
||||
// Write to the stream, ensure execution of a callback on completion.
|
||||
//
|
||||
DailyRotateFile.prototype._write = function(data, callback) {
|
||||
// If this is a file write stream, we could use the builtin
|
||||
// callback functionality, however, the stream is not guaranteed
|
||||
// to be an fs.WriteStream.
|
||||
var ret = this._stream.write(data);
|
||||
if (!callback) return;
|
||||
if (ret === false) {
|
||||
return this._stream.once('drain', function() {
|
||||
callback(null, true);
|
||||
});
|
||||
}
|
||||
callback(null, true);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function query (options, callback)
|
||||
// #### @options {Object} Loggly-like query options for this instance.
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Query the transport. Options object is optional.
|
||||
//
|
||||
DailyRotateFile.prototype.query = function (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
// TODO when maxfilesize rotate occurs
|
||||
var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
|
||||
options = this.normalizeQuery(options),
|
||||
buff = '',
|
||||
results = [],
|
||||
row = 0;
|
||||
|
||||
var stream = fs.createReadStream(file, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
if (stream.readable) {
|
||||
stream.destroy();
|
||||
}
|
||||
if (!callback) return;
|
||||
return err.code !== 'ENOENT'
|
||||
? callback(err)
|
||||
: callback(null, results);
|
||||
});
|
||||
|
||||
stream.on('data', function (data) {
|
||||
var data = (buff + data).split(/\n+/),
|
||||
l = data.length - 1,
|
||||
i = 0;
|
||||
|
||||
for (; i < l; i++) {
|
||||
if (!options.start || row >= options.start) {
|
||||
add(data[i]);
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
buff = data[l];
|
||||
});
|
||||
|
||||
stream.on('close', function () {
|
||||
if (buff) add(buff, true);
|
||||
if (options.order === 'desc') {
|
||||
results = results.reverse();
|
||||
}
|
||||
if (callback) callback(null, results);
|
||||
});
|
||||
|
||||
function add(buff, attempt) {
|
||||
try {
|
||||
var log = JSON.parse(buff);
|
||||
if (check(log)) push(log);
|
||||
} catch (e) {
|
||||
if (!attempt) {
|
||||
stream.emit('error', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function push(log) {
|
||||
if (options.rows && results.length >= options.rows) {
|
||||
if (stream.readable) {
|
||||
stream.destroy();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.fields) {
|
||||
var obj = {};
|
||||
options.fields.forEach(function (key) {
|
||||
obj[key] = log[key];
|
||||
});
|
||||
log = obj;
|
||||
}
|
||||
|
||||
results.push(log);
|
||||
}
|
||||
|
||||
function check(log) {
|
||||
if (!log) return;
|
||||
|
||||
if (typeof log !== 'object') return;
|
||||
|
||||
var time = new Date(log.timestamp);
|
||||
if ((options.from && time < options.from)
|
||||
|| (options.until && time > options.until)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function stream (options)
|
||||
// #### @options {Object} Stream options for this instance.
|
||||
// Returns a log stream for this transport. Options object is optional.
|
||||
//
|
||||
DailyRotateFile.prototype.stream = function (options) {
|
||||
var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
|
||||
options = options || {},
|
||||
stream = new Stream;
|
||||
|
||||
var tail = {
|
||||
file: file,
|
||||
start: options.start
|
||||
};
|
||||
|
||||
stream.destroy = common.tailFile(tail, function (err, line) {
|
||||
|
||||
if(err){
|
||||
return stream.emit('error',err);
|
||||
}
|
||||
|
||||
try {
|
||||
stream.emit('data', line);
|
||||
line = JSON.parse(line);
|
||||
stream.emit('log', line);
|
||||
} catch (e) {
|
||||
stream.emit('error', e);
|
||||
}
|
||||
});
|
||||
|
||||
if(stream.resume){
|
||||
stream.resume();
|
||||
}
|
||||
|
||||
return stream;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function open (callback)
|
||||
// #### @callback {function} Continuation to respond to when complete
|
||||
// Checks to see if a new file needs to be created based on the `maxsize`
|
||||
// (if any) and the current size of the file used.
|
||||
//
|
||||
DailyRotateFile.prototype.open = function (callback) {
|
||||
var now = new Date();
|
||||
if (this.opening) {
|
||||
//
|
||||
// If we are already attempting to open the next
|
||||
// available file then respond with a value indicating
|
||||
// that the message should be buffered.
|
||||
//
|
||||
return callback(true);
|
||||
}
|
||||
else if (!this._stream || (this.maxsize && this._size >= this.maxsize) ||
|
||||
(this._year < now.getFullYear() || this._month < now.getMonth() || this._date < now.getDate() || this._hour < now.getHours() || this._minute < now.getMinutes())) {
|
||||
//
|
||||
// If we dont have a stream or have exceeded our size, then create
|
||||
// the next stream and respond with a value indicating that
|
||||
// the message should be buffered.
|
||||
//
|
||||
callback(true);
|
||||
return this._createStream();
|
||||
}
|
||||
|
||||
//
|
||||
// Otherwise we have a valid (and ready) stream.
|
||||
//
|
||||
callback();
|
||||
};
|
||||
|
||||
//
|
||||
// ### function close ()
|
||||
// Closes the stream associated with this instance.
|
||||
//
|
||||
DailyRotateFile.prototype.close = function () {
|
||||
var self = this;
|
||||
|
||||
if (this._stream) {
|
||||
this._stream.end();
|
||||
this._stream.destroySoon();
|
||||
|
||||
this._stream.once('drain', function () {
|
||||
self.emit('flush');
|
||||
self.emit('closed');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function flush ()
|
||||
// Flushes any buffered messages to the current `stream`
|
||||
// used by this instance.
|
||||
//
|
||||
DailyRotateFile.prototype.flush = function () {
|
||||
var self = this;
|
||||
|
||||
//
|
||||
// Iterate over the `_buffer` of enqueued messaged
|
||||
// and then write them to the newly created stream.
|
||||
//
|
||||
this._buffer.forEach(function (item) {
|
||||
var str = item[0],
|
||||
callback = item[1];
|
||||
|
||||
process.nextTick(function () {
|
||||
self._write(str, callback);
|
||||
self._size += str.length;
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// Quickly truncate the `_buffer` once the write operations
|
||||
// have been started
|
||||
//
|
||||
self._buffer.length = 0;
|
||||
|
||||
//
|
||||
// When the stream has drained we have flushed
|
||||
// our buffer.
|
||||
//
|
||||
self._stream.once('drain', function () {
|
||||
self.emit('flush');
|
||||
self.emit('logged');
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _createStream ()
|
||||
// Attempts to open the next appropriate file for this instance
|
||||
// based on the common state (such as `maxsize` and `_basename`).
|
||||
//
|
||||
DailyRotateFile.prototype._createStream = function () {
|
||||
var self = this;
|
||||
this.opening = true;
|
||||
|
||||
(function checkFile (target) {
|
||||
var fullname = path.join(self.dirname, target);
|
||||
|
||||
//
|
||||
// Creates the `WriteStream` and then flushes any
|
||||
// buffered messages.
|
||||
//
|
||||
function createAndFlush (size) {
|
||||
if (self._stream) {
|
||||
self._stream.end();
|
||||
self._stream.destroySoon();
|
||||
}
|
||||
|
||||
self._size = size;
|
||||
self.filename = target;
|
||||
self._stream = fs.createWriteStream(fullname, self.options);
|
||||
|
||||
//
|
||||
// We need to listen for drain events when
|
||||
// write() returns false. This can make node
|
||||
// mad at times.
|
||||
//
|
||||
self._stream.setMaxListeners(Infinity);
|
||||
|
||||
//
|
||||
// When the current stream has finished flushing
|
||||
// then we can be sure we have finished opening
|
||||
// and thus can emit the `open` event.
|
||||
//
|
||||
self.once('flush', function () {
|
||||
self.opening = false;
|
||||
self.emit('open', fullname);
|
||||
});
|
||||
|
||||
//
|
||||
// Remark: It is possible that in the time it has taken to find the
|
||||
// next logfile to be written more data than `maxsize` has been buffered,
|
||||
// but for sensible limits (10s - 100s of MB) this seems unlikely in less
|
||||
// than one second.
|
||||
//
|
||||
self.flush();
|
||||
}
|
||||
|
||||
fs.stat(fullname, function (err, stats) {
|
||||
if (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
return self.emit('error', err);
|
||||
}
|
||||
|
||||
return createAndFlush(0);
|
||||
}
|
||||
|
||||
if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
|
||||
//
|
||||
// If `stats.size` is greater than the `maxsize` for
|
||||
// this instance then try again
|
||||
//
|
||||
return checkFile(self._getFile(true));
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
if (self._year < now.getFullYear() || self._month < now.getMonth() || self._date < now.getDate() || self._hour < now.getHours() || self._minute < now.getMinutes()) {
|
||||
self._year = now.getFullYear();
|
||||
self._month = now.getMonth();
|
||||
self._date = now.getDate();
|
||||
self._hour = now.getHours();
|
||||
self._minute = now.getMinutes();
|
||||
self._created = 0;
|
||||
return checkFile(self._getFile());
|
||||
}
|
||||
|
||||
createAndFlush(stats.size);
|
||||
});
|
||||
})(this._getFile());
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _getFile ()
|
||||
// Gets the next filename to use for this instance
|
||||
// in the case that log filesizes are being capped.
|
||||
//
|
||||
DailyRotateFile.prototype._getFile = function (inc) {
|
||||
var self = this,
|
||||
filename = this._basename + this.getFormattedDate(),
|
||||
remaining;
|
||||
|
||||
if (inc) {
|
||||
//
|
||||
// Increment the number of files created or
|
||||
// checked by this instance.
|
||||
//
|
||||
// Check for maxFiles option and delete file
|
||||
if (this.maxFiles && (this._created >= (this.maxFiles - 1))) {
|
||||
remaining = this._created - (this.maxFiles - 1);
|
||||
if (remaining === 0) {
|
||||
fs.unlinkSync(path.join(this.dirname, filename));
|
||||
}
|
||||
else {
|
||||
fs.unlinkSync(path.join(this.dirname, filename + '.' + remaining));
|
||||
}
|
||||
}
|
||||
|
||||
this._created += 1;
|
||||
}
|
||||
|
||||
return this._created
|
||||
? filename + '.' + this._created
|
||||
: filename;
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _lazyDrain ()
|
||||
// Lazily attempts to emit the `logged` event when `this.stream` has
|
||||
// drained. This is really just a simple mutex that only works because
|
||||
// Node.js is single-threaded.
|
||||
//
|
||||
DailyRotateFile.prototype._lazyDrain = function () {
|
||||
var self = this;
|
||||
|
||||
if (!this._draining && this._stream) {
|
||||
this._draining = true;
|
||||
|
||||
this._stream.once('drain', function () {
|
||||
this._draining = false;
|
||||
self.emit('logged');
|
||||
});
|
||||
}
|
||||
};
|
||||
538
node_modules/winston/lib/winston/transports/file.js
generated
vendored
Normal file
538
node_modules/winston/lib/winston/transports/file.js
generated
vendored
Normal file
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* file.js: Transport for outputting to a local log file
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
util = require('util'),
|
||||
colors = require('colors'),
|
||||
common = require('../common'),
|
||||
Transport = require('./transport').Transport,
|
||||
Stream = require('stream').Stream;
|
||||
|
||||
//
|
||||
// ### function File (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the File transport object responsible
|
||||
// for persisting log messages and metadata to one or more files.
|
||||
//
|
||||
var File = exports.File = function (options) {
|
||||
Transport.call(this, options);
|
||||
|
||||
//
|
||||
// Helper function which throws an `Error` in the event
|
||||
// that any of the rest of the arguments is present in `options`.
|
||||
//
|
||||
function throwIf (target /*, illegal... */) {
|
||||
Array.prototype.slice.call(arguments, 1).forEach(function (name) {
|
||||
if (options[name]) {
|
||||
throw new Error('Cannot set ' + name + ' and ' + target + 'together');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.filename || options.dirname) {
|
||||
throwIf('filename or dirname', 'stream');
|
||||
this._basename = this.filename = options.filename
|
||||
? path.basename(options.filename)
|
||||
: 'winston.log';
|
||||
|
||||
this.dirname = options.dirname || path.dirname(options.filename);
|
||||
this.options = options.options || { flags: 'a' };
|
||||
|
||||
//
|
||||
// "24 bytes" is maybe a good value for logging lines.
|
||||
//
|
||||
this.options.highWaterMark = this.options.highWaterMark || 24;
|
||||
}
|
||||
else if (options.stream) {
|
||||
throwIf('stream', 'filename', 'maxsize');
|
||||
this._stream = options.stream;
|
||||
|
||||
//
|
||||
// We need to listen for drain events when
|
||||
// write() returns false. This can make node
|
||||
// mad at times.
|
||||
//
|
||||
this._stream.setMaxListeners(Infinity);
|
||||
}
|
||||
else {
|
||||
throw new Error('Cannot log to file without filename or stream.');
|
||||
}
|
||||
|
||||
this.json = options.json !== false;
|
||||
this.colorize = options.colorize || false;
|
||||
this.maxsize = options.maxsize || null;
|
||||
this.maxFiles = options.maxFiles || null;
|
||||
this.prettyPrint = options.prettyPrint || false;
|
||||
this.label = options.label || null;
|
||||
this.timestamp = options.timestamp != null ? options.timestamp : true;
|
||||
this.logstash = options.logstash || false;
|
||||
|
||||
if (this.json) {
|
||||
this.stringify = options.stringify;
|
||||
}
|
||||
|
||||
//
|
||||
// Internal state variables representing the number
|
||||
// of files this instance has created and the current
|
||||
// size (in bytes) of the current logfile.
|
||||
//
|
||||
this._size = 0;
|
||||
this._created = 0;
|
||||
this._buffer = [];
|
||||
this._draining = false;
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `winston.Transport`.
|
||||
//
|
||||
util.inherits(File, Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
File.prototype.name = 'file';
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
File.prototype.log = function (level, msg, meta, callback) {
|
||||
if (this.silent) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
if (typeof msg !== 'string') {
|
||||
msg = '' + msg;
|
||||
}
|
||||
|
||||
var output = common.log({
|
||||
level: level,
|
||||
message: msg,
|
||||
meta: meta,
|
||||
json: this.json,
|
||||
colorize: this.colorize,
|
||||
prettyPrint: this.prettyPrint,
|
||||
timestamp: this.timestamp,
|
||||
stringify: this.stringify,
|
||||
label: this.label,
|
||||
logstash: this.logstash
|
||||
}) + '\n';
|
||||
|
||||
this._size += output.length;
|
||||
|
||||
if (!this.filename) {
|
||||
//
|
||||
// If there is no `filename` on this instance then it was configured
|
||||
// with a raw `WriteableStream` instance and we should not perform any
|
||||
// size restrictions.
|
||||
//
|
||||
this._write(output, callback);
|
||||
this._lazyDrain();
|
||||
}
|
||||
else {
|
||||
this.open(function (err) {
|
||||
if (err) {
|
||||
//
|
||||
// If there was an error enqueue the message
|
||||
//
|
||||
return self._buffer.push([output, callback]);
|
||||
}
|
||||
|
||||
self._write(output, callback);
|
||||
self._lazyDrain();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function _write (data, cb)
|
||||
// #### @data {String|Buffer} Data to write to the instance's stream.
|
||||
// #### @cb {function} Continuation to respond to when complete.
|
||||
// Write to the stream, ensure execution of a callback on completion.
|
||||
//
|
||||
File.prototype._write = function(data, callback) {
|
||||
// If this is a file write stream, we could use the builtin
|
||||
// callback functionality, however, the stream is not guaranteed
|
||||
// to be an fs.WriteStream.
|
||||
var ret = this._stream.write(data);
|
||||
if (!callback) return;
|
||||
if (ret === false) {
|
||||
return this._stream.once('drain', function() {
|
||||
callback(null, true);
|
||||
});
|
||||
}
|
||||
callback(null, true);
|
||||
};
|
||||
|
||||
//
|
||||
// ### function query (options, callback)
|
||||
// #### @options {Object} Loggly-like query options for this instance.
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Query the transport. Options object is optional.
|
||||
//
|
||||
File.prototype.query = function (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
var file = path.join(this.dirname, this.filename),
|
||||
options = this.normalizeQuery(options),
|
||||
buff = '',
|
||||
results = [],
|
||||
row = 0;
|
||||
|
||||
var stream = fs.createReadStream(file, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
if (stream.readable) {
|
||||
stream.destroy();
|
||||
}
|
||||
if (!callback) return;
|
||||
return err.code !== 'ENOENT'
|
||||
? callback(err)
|
||||
: callback(null, results);
|
||||
});
|
||||
|
||||
stream.on('data', function (data) {
|
||||
var data = (buff + data).split(/\n+/),
|
||||
l = data.length - 1,
|
||||
i = 0;
|
||||
|
||||
for (; i < l; i++) {
|
||||
if (!options.start || row >= options.start) {
|
||||
add(data[i]);
|
||||
}
|
||||
row++;
|
||||
}
|
||||
|
||||
buff = data[l];
|
||||
});
|
||||
|
||||
stream.on('close', function () {
|
||||
if (buff) add(buff, true);
|
||||
if (options.order === 'desc') {
|
||||
results = results.reverse();
|
||||
}
|
||||
if (callback) callback(null, results);
|
||||
});
|
||||
|
||||
function add(buff, attempt) {
|
||||
try {
|
||||
var log = JSON.parse(buff);
|
||||
if (check(log)) push(log);
|
||||
} catch (e) {
|
||||
if (!attempt) {
|
||||
stream.emit('error', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function push(log) {
|
||||
if (options.rows && results.length >= options.rows) {
|
||||
if (stream.readable) {
|
||||
stream.destroy();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.fields) {
|
||||
var obj = {};
|
||||
options.fields.forEach(function (key) {
|
||||
obj[key] = log[key];
|
||||
});
|
||||
log = obj;
|
||||
}
|
||||
|
||||
results.push(log);
|
||||
}
|
||||
|
||||
function check(log) {
|
||||
if (!log) return;
|
||||
|
||||
if (typeof log !== 'object') return;
|
||||
|
||||
var time = new Date(log.timestamp);
|
||||
if ((options.from && time < options.from)
|
||||
|| (options.until && time > options.until)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function stream (options)
|
||||
// #### @options {Object} Stream options for this instance.
|
||||
// Returns a log stream for this transport. Options object is optional.
|
||||
//
|
||||
File.prototype.stream = function (options) {
|
||||
var file = path.join(this.dirname, this.filename),
|
||||
options = options || {},
|
||||
stream = new Stream;
|
||||
|
||||
var tail = {
|
||||
file: file,
|
||||
start: options.start
|
||||
};
|
||||
|
||||
stream.destroy = common.tailFile(tail, function (err, line) {
|
||||
|
||||
if(err){
|
||||
return stream.emit('error',err);
|
||||
}
|
||||
|
||||
try {
|
||||
stream.emit('data', line);
|
||||
line = JSON.parse(line);
|
||||
stream.emit('log', line);
|
||||
} catch (e) {
|
||||
stream.emit('error', e);
|
||||
}
|
||||
});
|
||||
|
||||
return stream;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function open (callback)
|
||||
// #### @callback {function} Continuation to respond to when complete
|
||||
// Checks to see if a new file needs to be created based on the `maxsize`
|
||||
// (if any) and the current size of the file used.
|
||||
//
|
||||
File.prototype.open = function (callback) {
|
||||
if (this.opening) {
|
||||
//
|
||||
// If we are already attempting to open the next
|
||||
// available file then respond with a value indicating
|
||||
// that the message should be buffered.
|
||||
//
|
||||
return callback(true);
|
||||
}
|
||||
else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) {
|
||||
//
|
||||
// If we dont have a stream or have exceeded our size, then create
|
||||
// the next stream and respond with a value indicating that
|
||||
// the message should be buffered.
|
||||
//
|
||||
callback(true);
|
||||
return this._createStream();
|
||||
}
|
||||
|
||||
//
|
||||
// Otherwise we have a valid (and ready) stream.
|
||||
//
|
||||
callback();
|
||||
};
|
||||
|
||||
//
|
||||
// ### function close ()
|
||||
// Closes the stream associated with this instance.
|
||||
//
|
||||
File.prototype.close = function () {
|
||||
var self = this;
|
||||
|
||||
if (this._stream) {
|
||||
this._stream.end();
|
||||
this._stream.destroySoon();
|
||||
|
||||
this._stream.once('drain', function () {
|
||||
self.emit('flush');
|
||||
self.emit('closed');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// ### function flush ()
|
||||
// Flushes any buffered messages to the current `stream`
|
||||
// used by this instance.
|
||||
//
|
||||
File.prototype.flush = function () {
|
||||
var self = this;
|
||||
|
||||
// If nothing to flush, there will be no "flush" event from native stream
|
||||
// Thus, the "open" event will never be fired (see _createStream.createAndFlush function)
|
||||
// That means, self.opening will never set to false and no logs will be written to disk
|
||||
if (!this._buffer.length) {
|
||||
return self.emit('flush');
|
||||
}
|
||||
|
||||
//
|
||||
// Iterate over the `_buffer` of enqueued messaged
|
||||
// and then write them to the newly created stream.
|
||||
//
|
||||
this._buffer.forEach(function (item) {
|
||||
var str = item[0],
|
||||
callback = item[1];
|
||||
|
||||
process.nextTick(function () {
|
||||
self._write(str, callback);
|
||||
self._size += str.length;
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// Quickly truncate the `_buffer` once the write operations
|
||||
// have been started
|
||||
//
|
||||
self._buffer.length = 0;
|
||||
|
||||
//
|
||||
// When the stream has drained we have flushed
|
||||
// our buffer.
|
||||
//
|
||||
self._stream.once('drain', function () {
|
||||
self.emit('flush');
|
||||
self.emit('logged');
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _createStream ()
|
||||
// Attempts to open the next appropriate file for this instance
|
||||
// based on the common state (such as `maxsize` and `_basename`).
|
||||
//
|
||||
File.prototype._createStream = function () {
|
||||
var self = this;
|
||||
this.opening = true;
|
||||
|
||||
(function checkFile (target) {
|
||||
var fullname = path.join(self.dirname, target);
|
||||
|
||||
//
|
||||
// Creates the `WriteStream` and then flushes any
|
||||
// buffered messages.
|
||||
//
|
||||
function createAndFlush (size) {
|
||||
if (self._stream) {
|
||||
self._stream.end();
|
||||
self._stream.destroySoon();
|
||||
}
|
||||
|
||||
self._size = size;
|
||||
self.filename = target;
|
||||
self._stream = fs.createWriteStream(fullname, self.options);
|
||||
|
||||
//
|
||||
// We need to listen for drain events when
|
||||
// write() returns false. This can make node
|
||||
// mad at times.
|
||||
//
|
||||
self._stream.setMaxListeners(Infinity);
|
||||
|
||||
//
|
||||
// When the current stream has finished flushing
|
||||
// then we can be sure we have finished opening
|
||||
// and thus can emit the `open` event.
|
||||
//
|
||||
self.once('flush', function () {
|
||||
// Because "flush" event is based on native stream "drain" event,
|
||||
// logs could be written inbetween "self.flush()" and here
|
||||
// Therefore, we need to flush again to make sure everything is flushed
|
||||
self.flush();
|
||||
|
||||
self.opening = false;
|
||||
self.emit('open', fullname);
|
||||
});
|
||||
|
||||
//
|
||||
// Remark: It is possible that in the time it has taken to find the
|
||||
// next logfile to be written more data than `maxsize` has been buffered,
|
||||
// but for sensible limits (10s - 100s of MB) this seems unlikely in less
|
||||
// than one second.
|
||||
//
|
||||
self.flush();
|
||||
}
|
||||
|
||||
fs.stat(fullname, function (err, stats) {
|
||||
if (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
return self.emit('error', err);
|
||||
}
|
||||
|
||||
return createAndFlush(0);
|
||||
}
|
||||
|
||||
if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
|
||||
//
|
||||
// If `stats.size` is greater than the `maxsize` for
|
||||
// this instance then try again
|
||||
//
|
||||
return checkFile(self._getFile(true));
|
||||
}
|
||||
|
||||
createAndFlush(stats.size);
|
||||
});
|
||||
})(this._getFile());
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _getFile ()
|
||||
// Gets the next filename to use for this instance
|
||||
// in the case that log filesizes are being capped.
|
||||
//
|
||||
File.prototype._getFile = function (inc) {
|
||||
var self = this,
|
||||
ext = path.extname(this._basename),
|
||||
basename = path.basename(this._basename, ext),
|
||||
remaining;
|
||||
|
||||
if (inc) {
|
||||
//
|
||||
// Increment the number of files created or
|
||||
// checked by this instance.
|
||||
//
|
||||
// Check for maxFiles option and delete file
|
||||
if (this.maxFiles && (this._created >= (this.maxFiles - 1))) {
|
||||
remaining = this._created - (this.maxFiles - 1);
|
||||
if (remaining === 0) {
|
||||
fs.unlinkSync(path.join(this.dirname, basename + ext));
|
||||
}
|
||||
else {
|
||||
fs.unlinkSync(path.join(this.dirname, basename + remaining + ext));
|
||||
}
|
||||
}
|
||||
|
||||
this._created += 1;
|
||||
}
|
||||
|
||||
return this._created
|
||||
? basename + this._created + ext
|
||||
: basename + ext;
|
||||
};
|
||||
|
||||
//
|
||||
// ### @private function _lazyDrain ()
|
||||
// Lazily attempts to emit the `logged` event when `this.stream` has
|
||||
// drained. This is really just a simple mutex that only works because
|
||||
// Node.js is single-threaded.
|
||||
//
|
||||
File.prototype._lazyDrain = function () {
|
||||
var self = this;
|
||||
|
||||
if (!this._draining && this._stream) {
|
||||
this._draining = true;
|
||||
|
||||
this._stream.once('drain', function () {
|
||||
this._draining = false;
|
||||
self.emit('logged');
|
||||
});
|
||||
}
|
||||
};
|
||||
228
node_modules/winston/lib/winston/transports/http.js
generated
vendored
Normal file
228
node_modules/winston/lib/winston/transports/http.js
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
var util = require('util'),
|
||||
winston = require('../../winston'),
|
||||
http = require('http'),
|
||||
https = require('https'),
|
||||
Stream = require('stream').Stream,
|
||||
Transport = require('./transport').Transport;
|
||||
|
||||
//
|
||||
// ### function Http (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Http transport object responsible
|
||||
// for persisting log messages and metadata to a terminal or TTY.
|
||||
//
|
||||
var Http = exports.Http = function (options) {
|
||||
Transport.call(this, options);
|
||||
options = options || {};
|
||||
|
||||
this.name = 'http';
|
||||
this.ssl = !!options.ssl;
|
||||
this.host = options.host || 'localhost';
|
||||
this.port = options.port;
|
||||
this.auth = options.auth;
|
||||
this.path = options.path || '';
|
||||
|
||||
if (!this.port) {
|
||||
this.port = this.ssl ? 443 : 80;
|
||||
}
|
||||
};
|
||||
|
||||
util.inherits(Http, winston.Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
Http.prototype.name = 'http';
|
||||
|
||||
//
|
||||
// ### function _request (options, callback)
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Make a request to a winstond server or any http server which can
|
||||
// handle json-rpc.
|
||||
//
|
||||
Http.prototype._request = function (options, callback) {
|
||||
var options = options || {},
|
||||
auth = options.auth || this.auth,
|
||||
path = options.path || this.path || '';
|
||||
|
||||
delete options.auth;
|
||||
delete options.path;
|
||||
|
||||
// Prepare options for outgoing HTTP request
|
||||
req = (self.ssl ? https : http).request({
|
||||
host: this.host,
|
||||
port: this.port,
|
||||
path: path.replace(/^\//, ''),
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
auth: (auth) ? auth.username + ':' + auth.password : ''
|
||||
});
|
||||
|
||||
req.end(new Buffer(JSON.stringify(options), 'utf8'));
|
||||
|
||||
req.on('error', callback);
|
||||
|
||||
req.on('response', function (res) {
|
||||
res.on('end', function () {
|
||||
callback(null, res);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
Http.prototype.log = function (level, msg, meta, callback) {
|
||||
var self = this;
|
||||
|
||||
if (typeof meta === 'function') {
|
||||
callback = meta;
|
||||
meta = {};
|
||||
}
|
||||
|
||||
var options = {
|
||||
method: 'collect',
|
||||
params: {
|
||||
level: level,
|
||||
message: msg,
|
||||
meta: meta
|
||||
}
|
||||
};
|
||||
|
||||
if (meta) {
|
||||
if (meta.path) {
|
||||
options.path = meta.path;
|
||||
delete meta.path;
|
||||
}
|
||||
|
||||
if (meta.auth) {
|
||||
options.auth = meta.auth;
|
||||
delete meta.auth;
|
||||
}
|
||||
}
|
||||
|
||||
this._request(options, function (err, res) {
|
||||
if (res && res.statusCode !== 200) {
|
||||
err = new Error('HTTP Status Code: ' + res.statusCode);
|
||||
}
|
||||
|
||||
if (err) return callback(err);
|
||||
|
||||
// TODO: emit 'logged' correctly,
|
||||
// keep track of pending logs.
|
||||
self.emit('logged');
|
||||
|
||||
if (callback) callback(null, true);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function query (options, callback)
|
||||
// #### @options {Object} Loggly-like query options for this instance.
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Query the transport. Options object is optional.
|
||||
//
|
||||
Http.prototype.query = function (options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
var self = this,
|
||||
options = this.normalizeQuery(options);
|
||||
|
||||
options = {
|
||||
method: 'query',
|
||||
params: options
|
||||
};
|
||||
|
||||
if (options.params.path) {
|
||||
options.path = options.params.path;
|
||||
delete options.params.path;
|
||||
}
|
||||
|
||||
if (options.params.auth) {
|
||||
options.auth = options.params.auth;
|
||||
delete options.params.auth;
|
||||
}
|
||||
|
||||
this._request(options, function (err, res, body) {
|
||||
if (res && res.statusCode !== 200) {
|
||||
err = new Error('HTTP Status Code: ' + res.statusCode);
|
||||
}
|
||||
|
||||
if (err) return callback(err);
|
||||
|
||||
if (typeof body === 'string') {
|
||||
try {
|
||||
body = JSON.parse(body);
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, body);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// ### function stream (options)
|
||||
// #### @options {Object} Stream options for this instance.
|
||||
// Returns a log stream for this transport. Options object is optional.
|
||||
//
|
||||
Http.prototype.stream = function (options) {
|
||||
var self = this,
|
||||
options = options || {},
|
||||
stream = new Stream,
|
||||
req,
|
||||
buff;
|
||||
|
||||
stream.destroy = function () {
|
||||
req.destroy();
|
||||
};
|
||||
|
||||
options = {
|
||||
method: 'stream',
|
||||
params: options
|
||||
};
|
||||
|
||||
if (options.params.path) {
|
||||
options.path = options.params.path;
|
||||
delete options.params.path;
|
||||
}
|
||||
|
||||
if (options.params.auth) {
|
||||
options.auth = options.params.auth;
|
||||
delete options.params.auth;
|
||||
}
|
||||
|
||||
req = this._request(options);
|
||||
buff = '';
|
||||
|
||||
req.on('data', function (data) {
|
||||
var data = (buff + data).split(/\n+/),
|
||||
l = data.length - 1,
|
||||
i = 0;
|
||||
|
||||
for (; i < l; i++) {
|
||||
try {
|
||||
stream.emit('log', JSON.parse(data[i]));
|
||||
} catch (e) {
|
||||
stream.emit('error', e);
|
||||
}
|
||||
}
|
||||
|
||||
buff = data[l];
|
||||
});
|
||||
|
||||
req.on('error', function (err) {
|
||||
stream.emit('error', err);
|
||||
});
|
||||
|
||||
return stream;
|
||||
};
|
||||
85
node_modules/winston/lib/winston/transports/memory.js
generated
vendored
Normal file
85
node_modules/winston/lib/winston/transports/memory.js
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
var events = require('events'),
|
||||
util = require('util'),
|
||||
colors = require('colors'),
|
||||
common = require('../common'),
|
||||
Transport = require('./transport').Transport;
|
||||
|
||||
//
|
||||
// ### function Memory (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Memory transport object responsible
|
||||
// for persisting log messages and metadata to a memory array of messages.
|
||||
//
|
||||
var Memory = exports.Memory = function (options) {
|
||||
Transport.call(this, options);
|
||||
options = options || {};
|
||||
|
||||
this.errorOutput = [];
|
||||
this.writeOutput = [];
|
||||
|
||||
this.json = options.json || false;
|
||||
this.colorize = options.colorize || false;
|
||||
this.prettyPrint = options.prettyPrint || false;
|
||||
this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
|
||||
this.label = options.label || null;
|
||||
|
||||
if (this.json) {
|
||||
this.stringify = options.stringify || function (obj) {
|
||||
return JSON.stringify(obj, null, 2);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `winston.Transport`.
|
||||
//
|
||||
util.inherits(Memory, Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
Memory.prototype.name = 'memory';
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
Memory.prototype.log = function (level, msg, meta, callback) {
|
||||
if (this.silent) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
var self = this,
|
||||
output;
|
||||
|
||||
output = common.log({
|
||||
colorize: this.colorize,
|
||||
json: this.json,
|
||||
level: level,
|
||||
message: msg,
|
||||
meta: meta,
|
||||
stringify: this.stringify,
|
||||
timestamp: this.timestamp,
|
||||
prettyPrint: this.prettyPrint,
|
||||
raw: this.raw,
|
||||
label: this.label
|
||||
});
|
||||
|
||||
if (level === 'error' || level === 'debug') {
|
||||
this.errorOutput.push(output);
|
||||
} else {
|
||||
this.writeOutput.push(output);
|
||||
}
|
||||
|
||||
self.emit('logged');
|
||||
callback(null, true);
|
||||
};
|
||||
|
||||
Memory.prototype.clearLogs = function () {
|
||||
this.errorOutput = [];
|
||||
this.writeOutput = [];
|
||||
};
|
||||
121
node_modules/winston/lib/winston/transports/transport.js
generated
vendored
Normal file
121
node_modules/winston/lib/winston/transports/transport.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* transport.js: Base Transport object for all Winston transports.
|
||||
*
|
||||
* (C) 2010 Charlie Robbins
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
util = require('util');
|
||||
|
||||
//
|
||||
// ### function Transport (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Tranport object responsible
|
||||
// base functionality for all winston transports.
|
||||
//
|
||||
var Transport = exports.Transport = function (options) {
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
options = options || {};
|
||||
this.level = options.level === undefined ? 'info' : options.level;
|
||||
this.silent = options.silent || false;
|
||||
this.raw = options.raw || false;
|
||||
this.name = options.name || this.name;
|
||||
|
||||
this.handleExceptions = options.handleExceptions || false;
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `events.EventEmitter`.
|
||||
//
|
||||
util.inherits(Transport, events.EventEmitter);
|
||||
|
||||
//
|
||||
// ### function formatQuery (query)
|
||||
// #### @query {string|Object} Query to format
|
||||
// Formats the specified `query` Object (or string) to conform
|
||||
// with the underlying implementation of this transport.
|
||||
//
|
||||
Transport.prototype.formatQuery = function (query) {
|
||||
return query;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function normalizeQuery (query)
|
||||
// #### @options {string|Object} Query to normalize
|
||||
// Normalize options for query
|
||||
//
|
||||
Transport.prototype.normalizeQuery = function (options) {
|
||||
//
|
||||
// Use options similar to loggly.
|
||||
// [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional)
|
||||
//
|
||||
|
||||
options = options || {};
|
||||
|
||||
// limit
|
||||
options.rows = options.rows || options.limit || 10;
|
||||
|
||||
// starting row offset
|
||||
options.start = options.start || 0;
|
||||
|
||||
// now - 24
|
||||
options.from = options.from || new Date - (24 * 60 * 60 * 1000);
|
||||
if (typeof options.from !== 'object') {
|
||||
options.from = new Date(options.from);
|
||||
}
|
||||
|
||||
// now
|
||||
options.until = options.until || new Date;
|
||||
if (typeof options.until !== 'object') {
|
||||
options.until = new Date(options.until);
|
||||
}
|
||||
|
||||
// 'asc' or 'desc'
|
||||
options.order = options.order || 'desc';
|
||||
|
||||
// which fields to select
|
||||
options.fields = options.fields;
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function formatResults (results, options)
|
||||
// #### @results {Object|Array} Results returned from `.query`.
|
||||
// #### @options {Object} **Optional** Formatting options
|
||||
// Formats the specified `results` with the given `options` accordinging
|
||||
// to the implementation of this transport.
|
||||
//
|
||||
Transport.prototype.formatResults = function (results, options) {
|
||||
return results;
|
||||
};
|
||||
|
||||
//
|
||||
// ### function logException (msg, meta, callback)
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Logs the specified `msg`, `meta` and responds to the callback once the log
|
||||
// operation is complete to ensure that the event loop will not exit before
|
||||
// all logging has completed.
|
||||
//
|
||||
Transport.prototype.logException = function (msg, meta, callback) {
|
||||
var self = this;
|
||||
|
||||
function onLogged () {
|
||||
self.removeListener('error', onError);
|
||||
callback();
|
||||
}
|
||||
|
||||
function onError () {
|
||||
self.removeListener('logged', onLogged);
|
||||
callback();
|
||||
}
|
||||
|
||||
this.once('logged', onLogged);
|
||||
this.once('error', onError);
|
||||
this.log('error', msg, meta, function () { });
|
||||
};
|
||||
146
node_modules/winston/lib/winston/transports/webhook.js
generated
vendored
Normal file
146
node_modules/winston/lib/winston/transports/webhook.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* webhook.js: Transport for logging to remote http endpoints ( POST / RECEIVE webhooks )
|
||||
*
|
||||
* (C) 2011 Marak Squires
|
||||
* MIT LICENCE
|
||||
*
|
||||
*/
|
||||
|
||||
var events = require('events'),
|
||||
http = require('http'),
|
||||
https = require('https'),
|
||||
util = require('util'),
|
||||
cycle = require('cycle'),
|
||||
common = require('../common'),
|
||||
Transport = require('./transport').Transport;
|
||||
|
||||
//
|
||||
// ### function WebHook (options)
|
||||
// #### @options {Object} Options for this instance.
|
||||
// Constructor function for the Console transport object responsible
|
||||
// for making arbitrary HTTP requests whenever log messages and metadata
|
||||
// are received.
|
||||
//
|
||||
var Webhook = exports.Webhook = function (options) {
|
||||
Transport.call(this, options);
|
||||
|
||||
this.name = 'webhook';
|
||||
this.host = options.host || 'localhost';
|
||||
this.port = options.port || 8080;
|
||||
this.method = options.method || 'POST';
|
||||
this.path = options.path || '/winston-log';
|
||||
|
||||
if (options.auth) {
|
||||
this.auth = {};
|
||||
this.auth.username = options.auth.username || '';
|
||||
this.auth.password = options.auth.password || '';
|
||||
}
|
||||
|
||||
if (options.ssl) {
|
||||
this.port = options.port || 443;
|
||||
this.ssl = {
|
||||
key: options.ssl.key || null,
|
||||
cert: options.ssl.cert || null,
|
||||
ca: options.ssl.ca
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Inherit from `winston.Transport`.
|
||||
//
|
||||
util.inherits(Webhook, Transport);
|
||||
|
||||
//
|
||||
// Expose the name of this Transport on the prototype
|
||||
//
|
||||
Webhook.prototype.name = 'webhook';
|
||||
|
||||
//
|
||||
// ### function log (level, msg, [meta], callback)
|
||||
// #### @level {string} Level at which to log the message.
|
||||
// #### @msg {string} Message to log
|
||||
// #### @meta {Object} **Optional** Additional metadata to attach
|
||||
// #### @callback {function} Continuation to respond to when complete.
|
||||
// Core logging method exposed to Winston. Metadata is optional.
|
||||
//
|
||||
Webhook.prototype.log = function (level, msg, meta, callback) {
|
||||
if (this.silent) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
var self = this,
|
||||
meta = cycle.decycle(meta),
|
||||
message = common.clone(meta),
|
||||
options,
|
||||
req;
|
||||
|
||||
// Prepare options for outgoing HTTP request
|
||||
options = {
|
||||
host: this.host,
|
||||
port: this.port,
|
||||
path: this.path,
|
||||
method: this.method,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
};
|
||||
|
||||
if (this.ssl) {
|
||||
options.ca = this.ssl.ca;
|
||||
options.key = this.ssl.key;
|
||||
options.cert = this.ssl.cert;
|
||||
|
||||
// Required for the test fixture SSL certificate to be considered valid.
|
||||
options.rejectUnauthorized = false;
|
||||
}
|
||||
|
||||
if (this.auth) {
|
||||
// Encode `Authorization` header used by Basic Auth
|
||||
options.headers['Authorization'] = 'Basic ' + new Buffer(
|
||||
this.auth.username + ':' + this.auth.password, 'utf8'
|
||||
).toString('base64');
|
||||
}
|
||||
|
||||
// Perform HTTP logging request
|
||||
req = (self.ssl ? https : http).request(options, function (res) {
|
||||
// TODO: emit 'logged' correctly,
|
||||
// keep track of pending logs.
|
||||
res.on('data', function(data) {
|
||||
// Do nothing. We need to read the response, or we run into maxSockets
|
||||
// after 5 requests.
|
||||
});
|
||||
|
||||
self.emit('logged');
|
||||
if (callback) callback(null, true);
|
||||
callback = null;
|
||||
});
|
||||
|
||||
req.on('error', function (err) {
|
||||
//
|
||||
// Propagate the `error` back up to the `Logger` that this
|
||||
// instance belongs to.
|
||||
//
|
||||
self.emit('error', err);
|
||||
if (callback) callback(err, false);
|
||||
callback = null;
|
||||
});
|
||||
|
||||
//
|
||||
// Write logging event to the outgoing request body
|
||||
//
|
||||
// jsonMessage is currently conforming to JSON-RPC v1.0,
|
||||
// but without the unique id since there is no anticipated response
|
||||
// see: http://en.wikipedia.org/wiki/JSON-RPC
|
||||
//
|
||||
|
||||
var params = common.clone(meta) || {};
|
||||
params.timestamp = new Date();
|
||||
params.message = msg;
|
||||
params.level = level;
|
||||
|
||||
req.write(JSON.stringify({
|
||||
method: 'log',
|
||||
params: params
|
||||
}));
|
||||
|
||||
req.end();
|
||||
};
|
||||
Reference in New Issue
Block a user