change approach again

This commit is contained in:
2018-05-09 14:31:22 +02:00
parent 54a933c83a
commit 0686e02b75
2252 changed files with 864743 additions and 270 deletions

155
node_modules/simple-node-logger/lib/AbstractAppender.js generated vendored Normal file
View File

@ -0,0 +1,155 @@
/**
* @class AbstractAppender
*
* @author: darryl.west@raincitysoftware.com
* @created: 7/7/14 5:58 PM
*/
const util = require( 'util' );
const moment = require( 'moment' );
const dash = require( 'lodash' );
const AbstractAppender = function(options) {
'use strict';
const appender = this;
const typeName = options.typeName;
const timestampFormat = options.timestampFormat || 'HH:mm:ss.SSS';
this.separator = options.separator || ' ';
/**
* format the entry and return the field list
*
* @param entry the log entry
* @param thisArg - use this to override the base object
*
* @returns field array
*/
this.formatEntry = function(entry, thisArg) {
const apdr = thisArg || appender;
const fields = [];
if (entry.domain) {
fields.push( entry.domain );
}
fields.push( apdr.formatTimestamp( entry.ts ) );
fields.push( apdr.formatLevel( entry.level ) );
if (entry.category) {
fields.push( entry.category );
}
fields.push( apdr.formatMessage( entry.msg ) );
return fields;
};
/**
* format the message
*
* @param msg the log message
* @param thisArg - use this to override the base object
*
* @returns field array
*/
this.formatMessage = function(msg, thisArg) {
const apdr = thisArg || appender;
if (!msg) {
return '';
}
if (util.isArray( msg )) {
const list = msg.map(function(item) {
if (util.isDate( item )) {
return apdr.formatDate( item );
} else {
return apdr.formatObject( item );
}
});
return list.join('');
} else {
return msg;
}
};
this.formatDate = function(value) {
return value.toJSON();
};
this.formatObject = function(value) {
if (!value) {
return '';
}
if (dash.isObject( value )) {
if (value instanceof Error) {
return [ value.message, value.stack ].join('\n');
}
try {
return JSON.stringify( value );
} catch (ignore) {
return 'json error: ' + value.toString();
}
} else {
var s = value.toString();
if (s === '[object Object]') {
return util.inspect( value );
} else {
return s;
}
}
};
/**
* format the level string by forcing to upper case and padding to 5 chars
*
* @param level
* @returns {string}
*/
this.formatLevel = function(level) {
let str = level.toUpperCase();
if (str.length < 5) {
str += ' ';
}
return str;
};
/**
* format the timestamp to HH:mm:ss.SSS
*
* @param ts the unix milliseconds
* @returns formatted string
*/
this.formatTimestamp = function(ts) {
return moment( ts ).format( timestampFormat );
};
/**
* return the type name of this appender (ConsoleAppender)
*/
this.getTypeName = function() {
return typeName;
};
// constructor tests
if (!typeName) {
throw new Error('appender must be constructed with a type name');
}
};
module.exports = AbstractAppender;
AbstractAppender.extend = function(child, options) {
'use strict';
const parent = new AbstractAppender( options );
dash.extend( child, parent );
return parent;
};

57
node_modules/simple-node-logger/lib/ConsoleAppender.js generated vendored Normal file
View File

@ -0,0 +1,57 @@
/**
* @class ConsoleAppender
* @classdesc ConsoleAppender writes to the console all entries at or above the specified level.
*
* @author: darryl.west@raincitysoftware.com
* @created: 7/6/14 12:02 PM
*/
const Logger = require('./Logger' );
const AbstractAppender = require('./AbstractAppender' );
/*eslint no-console: "off"*/
const ConsoleAppender = function(opts) {
'use strict';
// get a copy of the opts
const options = Object.assign({}, opts);
const appender = this;
const typeName = options.typeName || 'ConsoleAppender';
const writer = options.writer || console.log;
let level = options.level || Logger.STANDARD_LEVELS[0];
let levels = options.levels || Logger.STANDARD_LEVELS;
let currentLevel = levels.indexOf( level );
options.typeName = typeName;
AbstractAppender.extend( this, options );
/**
* default formatter for this appender;
* @param entry
*/
this.formatter = function(entry) {
const fields = appender.formatEntry( entry );
return fields.join( appender.separator );
};
/**
* call formatter then write the entry to the console output
* @param entry - the log entry
*/
this.write = function(entry) {
if (levels.indexOf( entry.level ) >= currentLevel) {
writer( appender.formatter( entry ));
}
};
this.setLevel = function(level) {
const idx = levels.indexOf( level );
if (idx >= 0) {
currentLevel = idx;
}
};
};
module.exports = ConsoleAppender;

91
node_modules/simple-node-logger/lib/FileAppender.js generated vendored Normal file
View File

@ -0,0 +1,91 @@
/**
* @class FileAppender
*
* @author: darryl.west@raincitysoftware.com
* @created: 7/7/14 5:15 PM
*/
const Logger = require('./Logger' );
const AbstractAppender = require('./AbstractAppender' );
const dash = require( 'lodash' );
const path = require( 'path' );
const FileAppender = function(options) {
'use strict';
const appender = this;
const fs = options.fs || require( 'fs' );
const newline = /^win/.test(process.platform) ? '\r\n' : '\n';
const typeName = options.typeName || 'FileAppender';
const autoOpen = dash.isBoolean( options.autoOpen ) ? options.autoOpen : true;
const levels = options.levels || Logger.STANDARD_LEVELS;
let level = options.level || Logger.DEFAULT_LEVEL;
let currentLevel = levels.indexOf( level );
let logFilePath = options.logFilePath;
let writer = options.writer;
options.typeName = typeName;
AbstractAppender.extend( this, options );
/**
* default formatter for this appender;
* @param entry
*/
this.formatter = function(entry) {
const fields = appender.formatEntry( entry );
// add new line (for linux and windows)
fields.push( newline );
return fields.join( appender.separator );
};
/**
* call formatter then write the entry to the console output
* @param entry - the log entry
*/
this.write = function(entry) {
if (levels.indexOf( entry.level ) >= currentLevel) {
writer.write( appender.formatter( entry ) );
}
};
this.setLevel = function(level) {
const idx = levels.indexOf( level );
if (idx >= 0) {
currentLevel = idx;
}
};
// writer is opened on construction
const openWriter = function() {
if (!writer) {
const file = path.normalize( logFilePath );
const opts = {
flags:'a',
encoding:'utf8'
};
writer = fs.createWriteStream( file, opts );
}
};
this.closeWriter = function() {
if (writer) {
writer.end('\n');
}
};
// constructor tests
(function() {
if (!logFilePath) {
throw new Error('appender must be constructed with a log file path');
}
}());
if (autoOpen) {
openWriter();
}
};
module.exports = FileAppender;

184
node_modules/simple-node-logger/lib/Logger.js generated vendored Normal file
View File

@ -0,0 +1,184 @@
/**
* @class Logger
*
* @author: darryl.west@raincitysoftware.com
* @created: 7/5/14 6:28 PM
*/
const Logger = function(options) {
'use strict';
const logger = this,
pid = options.pid || process.pid,
errorEventName = options.errorEventName,
stats = new Map();
let domain = options.domain,
category = options.category,
level = options.level || Logger.DEFAULT_LEVEL,
levels = options.levels || Logger.STANDARD_LEVELS,
currentLevel = levels.indexOf( level ),
appenders = options.appenders || [];
// helper method
const isLevelAt = function(lvl) {
const idx = levels.indexOf( lvl );
return idx >= currentLevel;
};
/**
* log the statement message
*
* @param level the level of this message (label, i.e, info, warn, etc)
* @param msg
*/
this.log = function(level, msg) {
const entry = logger.createEntry( level, msg );
process.nextTick(function() {
// write the message to the appenders...
appenders.forEach(function(appender) {
appender.write( entry );
});
if (level === 'error' && typeof(errorEventName) === 'string') {
process.emit(errorEventName, entry);
}
});
return entry;
};
/**
* create the entry object used to log messages
*
* @param level - info, debug, etc.
* @param messageList - a list of message objects
* @returns then entry object
*/
this.createEntry = function(level, messageList) {
const entry = {};
entry.ts = Date.now();
entry.pid = pid;
if (domain) {
entry.domain = domain;
}
if (category) {
entry.category = category;
}
entry.level = level;
entry.msg = messageList;
return entry;
};
/**
* set the level
*
* @param lvl one of the recognized logger levels
*/
this.setLevel = function(lvl) {
currentLevel = levels.indexOf(lvl);
level = lvl;
appenders.forEach(app => {
app.setLevel( lvl );
});
};
/**
* return the current level string
*/
this.getLevel = function() {
return level;
};
/**
* set the list of appenders
* @param app
*/
this.setAppenders = function(appenderList) {
appenders = appenderList;
};
/**
* add an appender to the list
*
* @param appender - implements write method
*/
this.addAppender = function(appender) {
appenders.push( appender );
};
/**
* remove the appender using the type name
*/
this.removeAppender = function(typeName) {
throw new Error(`remove appender ${typeName} is not implemented yet...`);
};
this.getAppenders = function() {
return appenders;
};
this.isDebug = function() {
return isLevelAt( 'debug' );
};
this.isInfo = function() {
return isLevelAt( 'info' );
};
/**
* return the status map with log counts for each level
*/
this.getStats = function() {
return stats;
};
/**
* return the category name
*/
this.getCategory = function() {
return category;
};
/**
* return the domain name
*/
this.getDomain = function() {
return domain;
};
// now initialize the methods for the standard levels
const init = function() {
levels.forEach(function(lvl) {
stats.set(lvl, 0);
logger[ lvl ] = function() {
stats.set(lvl, stats.get(lvl) + 1);
if (levels.indexOf( lvl ) >= currentLevel) {
const args = Array.prototype.slice.call( arguments );
logger.log( lvl, args );
}
};
});
};
this.__protected = function() {
return {
pid:pid,
domain:domain,
category:category
};
};
init();
};
Logger.STANDARD_LEVELS = [ 'all', 'trace', 'debug', 'info', 'warn', 'error', 'fatal' ];
Logger.DEFAULT_LEVEL = 'info';
module.exports = Logger;

View File

@ -0,0 +1,161 @@
/**
* @class RollingFileAppender
*
* roll on size and/or date/time;
*
* @author: darryl.west@raincitysoftware.com
* @created: 7/27/14 9:52 AM
*/
const Logger = require( './Logger' );
const AbstractAppender = require( './AbstractAppender' );
const dash = require( 'lodash' );
const moment = require( 'moment' );
const path = require( 'path' );
const RollingFileAppender = function(options) {
'use strict';
const appender = this;
const fs = options.fs || require( 'fs' );
const newline = /^win/.test(process.platform) ? '\r\n' : '\n';
let typeName = options.typeName,
autoOpen = dash.isBoolean( options.autoOpen ) ? options.autoOpen : true,
logDirectory = options.logDirectory,
fileNamePattern = options.fileNamePattern,
dateFormat = options.dateFormat || 'YYYY.MM.DD',
level = options.level || Logger.DEFAULT_LEVEL,
levels = options.levels || Logger.STANDARD_LEVELS,
currentLevel = levels.indexOf( level ),
currentFile = options.currentFile,
rollTimer,
createInterval = options.createInterval || setInterval,
writers = [];
if (!typeName) {
typeName = options.typeName = 'RollingFileAppender';
}
AbstractAppender.extend( this, options );
const getWriter = function() {
return writers[0];
};
const openWriter = function(fname) {
const filename = fname || appender.createFileName();
const file = path.join( logDirectory, filename );
const opts = {
flags:'a',
encoding:'utf8'
};
let writer = fs.createWriteStream( file, opts );
// make this the current writer...
writers.unshift( writer );
currentFile = file;
// now close the current logger and remove from the writers list
while (writers.length > 1) {
// close the old writer
writer = writers.pop();
writer.removeAllListeners();
writer.end('\n');
}
};
// check once per minute to see if we need to roll
const startRollTimer = function() {
rollTimer = createInterval(function() {
if (appender.checkForRoll()) {
openWriter();
}
}, 60 * 1000);
};
/**
* default formatter for this appender;
* @param entry
*/
this.formatter = function(entry) {
const fields = appender.formatEntry( entry );
fields.push( newline );
return fields.join( appender.separator );
};
/**
* call formatter then write the entry to the console output
* @param entry - the log entry
*/
this.write = function(entry) {
if (levels.indexOf( entry.level ) >= currentLevel) {
const writer = getWriter();
if (writer) {
writer.write( appender.formatter( entry ) );
} else {
/*eslint no-console: "off"*/
console.log( 'no writer...' );
}
}
};
this.checkForRoll = function(now) {
// check to see if the
const fn = appender.createFileName( now );
const current = path.basename( currentFile );
return fn !== current;
};
this.createFileName = function(now) {
let dt;
if (now || now instanceof moment) {
dt = now.format( dateFormat );
} else {
dt = moment().format( dateFormat );
}
return fileNamePattern.replace( /<DATE>/i, dt );
};
this.setLevel = function(level) {
const idx = levels.indexOf( level );
if (idx >= 0) {
currentLevel = idx;
}
};
this.__protected = function() {
return {
openWriter:openWriter,
currentFile:currentFile,
rollTimer:rollTimer,
writers:writers
};
};
// constructor tests
(function() {
if (!logDirectory) {
throw new Error('appender must be constructed with a log directory');
}
if (!fileNamePattern) {
throw new Error('appender must be constructed with a file name pattern');
}
}());
// now validate the date pattern and file format
// date may only contain YMDHAa-.
if (autoOpen) {
openWriter();
startRollTimer();
}
};
module.exports = RollingFileAppender;

325
node_modules/simple-node-logger/lib/SimpleLogger.js generated vendored Normal file
View File

@ -0,0 +1,325 @@
/**
* @class SimpleLogger
*
* @author: darryl.west@raincitysoftware.com
* @created: 2014-07-06
*/
const dash = require( 'lodash' );
const Logger = require('./Logger' );
const ConsoleAppender = require('./ConsoleAppender' );
const FileAppender = require( './FileAppender' );
const RollingFileAppender = require( './RollingFileAppender' );
const SimpleLogger = function(opts) {
'use strict';
const options = Object.assign({}, opts);
const manager = this;
const domain = options.domain;
const appenders = options.appenders || [];
const loggers = options.loggers || [];
let dfltLevel = options.level || Logger.DEFAULT_LEVEL,
loggerConfigFile = options.loggerConfigFile,
refresh = options.refresh,
fs = options.fs || require('fs' ),
createInterval = options.createInterval || setInterval,
minRefresh = options.minRefresh || 10 * 1000,
errorEventName = options.errorEventName;
/**
* create a logger with optional category and level
*
* @param category
* @param level
*/
this.createLogger = function(category, level) {
const opts = Object.prototype.toString.call(category) === '[object String]' ? options : dash.merge({}, options, category);
opts.category = dash.isString(category) ? category : opts.category;
opts.level = level ? level : opts.level || dfltLevel;
opts.appenders = appenders;
if (errorEventName) {
opts.errorEventName = errorEventName;
}
const logger = new Logger( opts );
loggers.push( logger );
return logger;
};
/**
* create the console appender and add it to the appenders list
*
* @param opts - appender settings
* @returns ConsoleAppender -
*/
this.createConsoleAppender = function(opts) {
return manager.addAppender( new ConsoleAppender( Object.assign({}, opts ) ));
};
/**
* create a file appender and add it to the appenders list
*
* @param opts
* @returns a FileAppender object
*/
this.createFileAppender = function(opts) {
if (!opts) {
throw new Error('file appender must be created with log file path set in options');
}
return manager.addAppender( new FileAppender( opts ) );
};
/**
* create a rolling file appender and add it to the appender list
*
* @param opts
* @returns the appender
*/
this.createRollingFileAppender = function( opts ) {
return manager.addAppender( new RollingFileAppender( opts ) );
};
/**
* add the appender to list
*
* @param appender
* @returns the new appender
*/
this.addAppender = function(appender) {
appenders.push( appender );
return appender;
};
this.getAppenders = function() {
return appenders;
};
this.getLoggers = function() {
return loggers;
};
/**
* start the refresh thread; minimum cycle time = 10 seconds...
*/
this.startRefreshThread = function() {
// TODO replace with watcher thread
if (fs.existsSync( loggerConfigFile ) && dash.isNumber( refresh )) {
const t = Math.max( minRefresh, refresh );
createInterval( manager.readConfig, t);
}
};
/**
* set the level of all loggers to the specified level
*
* @param level - one of the know levels
*/
this.setAllLoggerLevels = function(level) {
loggers.forEach(function(logger) {
logger.setLevel( level );
});
};
/**
* read and parse the config file; change settings if required
*/
this.readConfig = function(completeCallback) {
// TODO refactor into configuration delegate to read stats and then process file only if stats change
const callback = (err, buf) => {
if (err) {
/*eslint no-console: "off"*/
console.log( err );
} else {
const conf = JSON.parse( buf.toString() );
if (conf.appenders && conf.appenders.length > 0) {
// find each appender and set the level
conf.appenders.forEach(function(app) {
const level = app.level;
const appender = dash.find( appenders, (item) => {
if (item.getTypeName() === app.typeName && app.level) {
return item;
}
});
if (appender && typeof appender.setLevel === 'function') {
appender.setLevel( level );
}
});
}
if (conf.loggers && conf.loggers.length > 0) {
conf.loggers.forEach(item => {
if (item.category === 'all') {
manager.setAllLoggerLevels( item.level );
}
});
}
}
if (completeCallback) {
return completeCallback( err );
}
};
fs.readFile( loggerConfigFile, callback );
};
this.__protected = function() {
return {
domain:domain,
dfltLevel:dfltLevel,
refresh:refresh,
loggerConfigFile:loggerConfigFile
};
};
};
module.exports = SimpleLogger;
/**
* static convenience method to create a simple console logger; see options for details
*
* @param options - optional, if present then it could be 1) a string or 2) and object. if it's a string it's assumed
* to be the logFilePath; if it's a string or an object with logFilePath property, then a file appender is created.
*
* Valid options:
* - logFilePath : a path to the file appender
* - domain : the logger domain, e.g., machine or site id
* - dfltLevel : the default log level (overrides info level)
* - timestampFormat : the format used for log entries (see moment date formats for all possibilities)
*
* @returns logger
*/
SimpleLogger.createSimpleLogger = function(options) {
'use strict';
let opts;
// if options is a string then it must be the
if (typeof options === 'string') {
opts = {
logFilePath: options
};
} else {
opts = Object.assign( {}, options );
}
const manager = new SimpleLogger(opts);
// pass options in to change date formats, etc
manager.createConsoleAppender( opts );
if (opts.logFilePath) {
manager.createFileAppender( opts );
}
return manager.createLogger();
};
/**
* static convenience method to create a file logger (no console logging);
*
* @param options - if string then it's the logFilePath, else options with the logFilePath
* @returns logger
*/
SimpleLogger.createSimpleFileLogger = function(options) {
'use strict';
if (!options) {
throw new Error('must create file logger with a logFilePath');
}
let opts;
// if options is a string then it must be the
if (typeof options === 'string') {
opts = {
logFilePath: options
};
} else {
opts = Object.assign({}, options );
}
const manager = new SimpleLogger( opts );
manager.createFileAppender( opts );
return manager.createLogger();
};
/**
* create a rolling file logger by passing options to SimpleLogger and Logger. this enables setting
* of domain, category, etc.
*
* @param options
* @returns rolling logger
*/
SimpleLogger.createRollingFileLogger = function(options) {
'use strict';
if (!options) {
throw new Error('createRollingFileLogger requires configuration options for this constructor');
}
var opts;
// read a dynamic config file if available
if (typeof options.readLoggerConfig === 'function') {
opts = options.readLoggerConfig();
opts.readLoggerConfig = options.readLoggerConfig;
} else {
opts = options;
}
var manager = new SimpleLogger( opts );
manager.createRollingFileAppender( opts );
if (opts.refresh && opts.loggerConfigFile) {
process.nextTick( manager.startRefreshThread );
}
return manager.createLogger( opts );
};
/**
* create a log manager
*
* @param options - file or rolling file specs;
*/
SimpleLogger.createLogManager = function(options) {
'use strict';
let opts;
// read a dynamic config file if available
if (options && typeof options.readLoggerConfig === 'function') {
opts = options.readLoggerConfig();
opts.readLoggerConfig = options.readLoggerConfig;
} else {
opts = Object.assign({}, options);
}
var manager = new SimpleLogger( opts );
if (opts.logDirectory && opts.fileNamePattern) {
manager.createRollingFileAppender( opts );
}
// create at least one appender
if (manager.getAppenders().length === 0) {
manager.createConsoleAppender( opts );
}
return manager;
};