326 lines
9.0 KiB
JavaScript
326 lines
9.0 KiB
JavaScript
/**
|
|
* @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;
|
|
};
|