UNPKG

mmir-lib

Version:

MMIR (Mobile Multimodal Interaction and Relay) library

1,283 lines (1,166 loc) 35 kB
define(['mmirf/stacktrace', 'mmirf/util/toArray', 'module'], /** * A Logger factory.<br> * * @example * //use logger * var Logger = mmir.require('mmirf/logger'); * var log = Logger.create('example'); * * if(log.isVerbose()) log.debug('test');//will write the message to debug-console) * log.error(new Error());//will write the error (including its stack) to error console) * * //example for setting up a logger in a requirejs-module: * define(['mmirf/logger', 'module'], function(Logger, module){ * * var logger = Logger.create(module); * //this would create the same logger-object: * // Logger.create(module.id, module.config(module).logLevel); * * //use the logger instance... * * //create / retrieve the same logger * var sameLogger = Logger.create(module.id); * * }); * * @class * @name Logging * @memberOf mmir * @static * @hideconstructor * * @see mmir.tools.Logger * */ function(stacktrace, toArray, module){ /** * created loggers: * loggerId (string) -> Logger * @type {Map<string, mmir.tools.Logger>} * @private */ var _loggers = new Map(); /** * pre-configured/"default" log-levels when creating loggers: * number -> loggerId (string) * @type {Map<number, string>} * @private */ var _logLevels = new Map(); /** * the (global) logging level * * 0: verbose * 1: debug * 2: info * 3: warn * 4: error * 5: critical * 6: disabled * * @memberOf mmir.Logging# */ var _level = 1; /** * @private * @type String * @memberOf mmir.Logging# */ var tmpLogLevel = module.config(module).logLevel; if(typeof tmpLogLevel !== 'undefined'){ if(tmpLogLevel && typeof tmpLogLevel === 'object'){ if(tmpLogLevel.levels){ parseLogLevels(tmpLogLevel.levels, 'levels'); } if(tmpLogLevel.modules){ parseLogLevels(tmpLogLevel.modules, 'modules'); } tmpLogLevel = typeof tmpLogLevel.level !== 'undefined'? tmpLogLevel.level : 'debug'; } if(typeof tmpLogLevel !== 'number'){ tmpLogLevel = getAsLevel(tmpLogLevel); } _level = tmpLogLevel; } function parseLogLevels(opt, mode){ if(mode === 'levels'){ // [field]: Array<moduleId> var list, level; for(var l in opt){ if(opt.hasOwnProperty(l)){ list = opt[l]; level = parseLogLevel(l); for(var i=0, size=list.length; i < size; ++i){ setLogLevel(list[i], level); } } } } else if(mode === 'modules'){ // [moduleId]: logLevel for(var modId in opt){ if(opt.hasOwnProperty(modId)){ setLogLevel(modId, opt[modId]); } } } else { print('logger', getAsLevel('error'), 'parseLogLevels(): invalid mode '+mode); } } function parseLogLevel(logLevel){ if(typeof logLevel === 'string'){ var num = parseFloat(logLevel); if(isFinite(num)){ return num; } } if(typeof logLevel !== 'number'){ return getAsLevel(logLevel); } return logLevel; } /** * Get the log-level as number. * * @param {String} strLogLevel * the string representation for the log-level * @returns {Number} * the log-level as number * @private * @memberOf mmir.tools.Logger.prototype * * @see #getLevel */ function getAsLevel(strLogLevel){ if(typeof strLogLevel === 'string'){ var str = strLogLevel.toLowerCase(); if(str === 'verbose'){ return 0; } else if(str === 'debug'){ return 1; } else if(str === 'info'){ return 2; } else if(str === 'warn'){ return 3; } else if(str === 'error'){ return 4; } else if(str === 'critical'){ return 5; } else if(str === 'disabled'){ return 6; } else throw new Error('Logger.getAsLevel: unknown parameter value "'+strLogLevel+'"'); } throw new TypeError('Logger.getAsLevel: parameter must be number or string, but "'+strLogLevel+'" is '+typeof strLogLevel); } /** * configure default log-level for a logger: * in case the logger is created without specifying a log-level, this pre-configured * log-level will be used. * * @param {String} loggerId * the ID for the logger * @param {Number|String} logLevel * the log-level for the logger * @private * @memberOf mmir.tools.Logger.prototype */ function setLogLevel(loggerId, logLevel){ if(typeof loggerId !== 'string'){ loggerId = loggerId + ''; } if(typeof logLevel !== 'number'){ logLevel = getAsLevel(logLevel); } _logLevels.set(loggerId, logLevel); } /** * print log message with error information. * * @private * @memberOf mmir.tools.Logger.prototype */ function printe(loggerName, logLevel, className, funcName, msg, error, reverseCallStack){ if( isErr(className)){ error = className; className = ''; } else if( isErr(funcName) ){ error = funcName; funcName = void(0); if(typeof className === 'undefined'){ className = ''; } } else if( isErr(msg) ){ error = msg; msg = void(0); if(typeof className === 'undefined'){ if(typeof funcName === 'undefined'){ className = ''; } else { className = funcName; funcName = void(0); } } } print(loggerName, logLevel, createErr(createMsg(className, funcName, msg), error), reverseCallStack); } /** * creates the message text. * * @returns {string} the message text * * @private * @memberOf mmir.tools.Logger.prototype */ function createMsg(className, funcName, msg){ var out; if(className){ if(funcName && typeof funcName !== 'number'){ if(msg && typeof funcName !== 'number'){ out = className+'.'+funcName+': '+msg; } else { // if(arguments.callee !== 'undefined'){ // out('callee: '+arguments.callee()); // } out = className+': '+funcName; } } else { // if(arguments.callee !== 'undefined'){ // out('callee: '+arguments.callee()); // } out = className; } } else { // if(arguments.callee !== 'undefined'){ // out('callee: '+arguments.callee()); // } if(typeof className === 'undefined'){ out = 'UNDEFINED'; } else if(typeof className !== 'string'){ out = Object.prototype.toString.call(null, className); } else { out = className; } } return out; } /** * HELPER: check if errObj is an Error * * @returns {Boolean} * * @private * @memberOf mmir.tools.Logger.prototype */ function isErr(errObj){ //TODO also do feature detection for error-like objects? return errObj instanceof Error; } /** * Creates error message (with stack trace, if possible). * * @returns {string} the error message * * @private * @memberOf mmir.tools.Logger.prototype */ function createErr(msg, error){ var err =''; var errMsg = ''; var re; if(error){ if(error.name){ err = '<'+error.name+'> '; } if(error.number){ err += '#'+error.number+' '; } if(error.stack){ errMsg = error.stack; if(error.name && (re = new RegExp('^'+error.name)).test(errMsg)){ errMsg = errMsg.replace(re, ''); } } else { if(error.message){ errMsg = ' - ' + error.message; } if(error.description){ errMsg = ' - ' + error.description; } if(error.fileName){ var lineNo = ''; if(error.lineNumber){ lineNo = ', line ' + error.lineNumber; } errorMsg += ' ('+error.fileName+lineNo+')'; } } } return err+msg+errMsg; } //in some environments console.debug may not exits -> use console.log instead var DEBUG_FUNC_NAME = console.debug? 'debug' : 'log'; /** * @private * @memberOf mmir.tools.Logger.prototype */ function print(loggerName, logLevel, msg){ var prefix, func; switch(logLevel){ case 0: prefix = '[VERBOSE] '; func = 'log'; break; case 1: prefix = '[DEBUG] '; func = DEBUG_FUNC_NAME; break; case 2: prefix = '[INFO] '; func = 'info'; break; case 3: prefix = '[WARN] '; func = 'warn'; break; case 4: prefix = '[ERROR] '; func = 'error'; break; case 5: prefix = '[CRITICAL] '; func = 'error'; break; case 6: //debug-level "disabled" -> do nothing return; /////////////////// EARLY EXIT ////////// default: prefix = '[UNDEF_LOG_LEVEL_'+logLevel+'] '; func = 'log'; break; } console[func](prefix + loggerName + msg); } /** * quasi constant: * is updated once, if stacktrace is enabled -- otherwise readonly! * * @private * @type boolean * @memberOf mmir.tools.Logger.prototype */ var IS_TRACE = false; /** * if stacktrace is enabled: * number of stack-levels that should be omitted (to hide logger-internal function-call-stack) * * @private * @type number * @const * @memberOf mmir.tools.Logger.prototype */ var STACK_LEVEL = 2; /** * if stacktrace is enabled: * number of stack-levels that should be omitted when printing an error via {@link #printe} * (to hide logger-internal function-call-stack) * * NOTE: if isErrInvoked is TRUE: this function was invoked via additional printe()-call * => need to take 1 more step down the stack * * @private * @type number * @const * @memberOf mmir.tools.Logger.prototype */ var ERROR_STACK_LEVEL = STACK_LEVEL + 1; /** * HELPER for getting the stack-level/-line from which on the trace should be printed * in order to suppress showing internal function calls when generating the log output * * @returns {number} the stack-level/-line from which on the trace should be printed * * @private * @memberOf mmir.tools.Logger.prototype */ function getStackLevel(_className, _funcName, _msg, _error, _reverseCallStack, isPrinte){ if(!IS_TRACE){ return 0; } var level = isPrinte? ERROR_STACK_LEVEL : STACK_LEVEL; for(var arg, i = 0, size = arguments.length; i < size; ++i){ arg = arguments[i]; if(typeof arg === 'number'){ return arg + level; } } return level; } /** * HELPER for modifying the reverseCallStack argument in arguments * * @returns {number} the stack-level/-line from which on the trace should be printed * * @param {Arguments} args the function's original arguments object * @param {number} offset the offset for the call-stack, value 0 would mean no change to the callstack (i.e. "go further back by [offset]") * @return {Array} the converted arguments object with applied (or modified) reverseCallStack argument * * @private * @memberOf mmir.tools.Logger.prototype */ function applyReverseCallStackWith(args, offset){ var list = toArray(args); if(offset === 0){ return list; } var len = list.length; if(typeof list[len-1] === 'number'){ list[len-1] += offset; } else { list[len] = offset; } return list; } //enable tracing? /** * configuration value for enabling/disabling tracing in log-output * @private * @type Object * @memberOf mmir.tools.Logger.prototype */ var tmpTraceConfig = module.config(module).trace; if(tmpTraceConfig !== false || (tmpTraceConfig !== null && typeof tmpTraceConfig === 'object' && tmpTraceConfig.trace !== false)){ IS_TRACE = true; /** * options object for tracing * @private * @type Object * @memberOf mmir.tools.Logger.prototype */ var pnTraceOptions = tmpTraceConfig === true? void(0) : tmpTraceConfig; /** * setting for trace-depth (i.e. stack-depth) * @private * @type Boolean * @memberOf mmir.tools.Logger.prototype */ var isFullStackDepth = pnTraceOptions && pnTraceOptions.depth === "full"; /** * proxy object for storing the original implementation * of {@link mmir.tools.Logger#print} function. * * (only used, if tracing is enabled!) * * @private * @type Function * @memberOf mmir.tools.Logger.prototype */ var pnOriginal = print; //do enable tracing: append stacktrace to messages in print-function if(isFullStackDepth){ //NOTE code duplication for the sake of a more efficient print function /** * Extension for {@link mmir.tools.Logger#print} function with tracing. * * This extension prints the full stack trace in log-output. * * (only used, if tracing is enabled!) * * @private * @name printFullStack * @function * @memberOf mmir.tools.Logger.prototype */ print = function printFullStack(loggerName, logLevel, msg, stackLevel){ if(typeof msg === 'undefined' || msg === null){ msg = ''; } //if isErrInvoked is TRUE: this function was invoked via additional printe()-call // => need to take 1 more step down the stack //if isErrInvoked is a number: use msg += '\n ' + stacktrace.getSync(pnTraceOptions).slice(stackLevel).join('\n '); pnOriginal.call(this, loggerName, logLevel, msg); }; } else { //NOTE code duplication for the sake of a more efficient print function /** * Extension for {@link mmir.tools.Logger#print} function with tracing. * * This extension prints only the first entry of the stack trace in log-output. * * (only used, if tracing is enabled!) * * @private * @name printStack * @function * @memberOf mmir.tools.Logger.prototype */ print = function printStack(loggerName, logLevel, msg, stackLevel){ if(typeof msg === 'undefined' || msg === null){ msg = ''; } //if isErrInvoked is TRUE: this function was invoked via additional printe()-call // => need to take 1 more step down the stack msg += '\n ' + stacktrace.getSync(pnTraceOptions)[stackLevel]; pnOriginal.call(this, loggerName, logLevel, msg); }; } } /** * Constructor-Method of Class Logger<br> * @constructor * @class * @name Logger * @memberOf mmir.tools * * @param {String} theName * the name / ID for the logger * @param {String|Number} [theLevel] OPTIONAL * the log-level. * If omitted, the logger will use * the default log-level * * @see #getAsLevel * @see #getLevel */ function Logger(theName, theLevel){ //the name (/key) for the logger instance this.name = ''; if(typeof theName !== 'undefined'){ this.name = '<'+theName+'> '; } if(typeof theLevel !== 'undefined'){ if(typeof theLevel !== 'number'){ theLevel = getAsLevel(theLevel); } this.level = theLevel; } } Logger.prototype = /** @lends mmir.tools.Logger# */ {//public instance members /** * Get the current log-level: * if a specific log-level for this Logger instance is set, * this value is returned. * Otherwise, the default log-level as returned by {@link mmir.Logging#getDefaultLogLevel} * is used. * * Log-levels: * <ul> * <li>0: verbose</li> * <li>1: debug</li> * <li>2: info</li> * <li>3: warn</li> * <li>4: error</li> * <li>5: critical</li> * <li>6: disabled</li> * <ul> * * @returns {Number} the logging level * * @see #setLevel */ getLevel : function(){ if(typeof this.level !== 'undefined'){ return this.level; } //return default/global logging-level: return _level; }, /** * Set the logging level. * * @param {String|Number} loggingLevel * if {Number} the logging level as a number * if {String} the logging level as a string (see {@link #getLevel}) * * @see #getLevel */ setLevel : function(loggingLevel){ if(typeof loggingLevel !== 'number'){ loggingLevel = getAsLevel(loggingLevel); } this.level = loggingLevel; }, /** * * Print a log message, if at least <code>debug</code> log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {Error} [error] OPTIONAL * an error object: if available, its message and error-stack will be print to the output * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ log: function(className, funcName, msg, error, reverseCallStack){ if(this.isDebug()){ printe(this.name, 1 /*getAsLevel('debug')*/, className, funcName, msg, error, getStackLevel(className, funcName, msg, error, reverseCallStack, true)); } }, /** * * Print a <em>verbose</em> log message, if at least <code>verbose</code> (0) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ //TODO implement/add helpers for file-logging (+ CSV data helpers etc) verbose : function(className, funcName, msg, reverseCallStack){ if(this.isVerbose()){ print( this.name, 0 /*getAsLevel('verbose')*/, createMsg(className, funcName, msg), getStackLevel(className, funcName, msg, null, reverseCallStack, false)); } }, /** * * Print a <em>debug</em> log message, if at least <code>debug</code> (1) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ debug : function(className, funcName, msg, reverseCallStack){ if(this.isDebug()){ print( this.name, 1 /*getAsLevel('debug')*/, createMsg(className, funcName, msg), getStackLevel(className, funcName, msg, null, reverseCallStack, false)); } }, /** * * Print an <em>information</em> log message, if at least <code>info</code> (2) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ info : function(className, funcName, msg, reverseCallStack){ if(this.isInfo()){ print( this.name, 2 /*getAsLevel('info')*/, createMsg(className, funcName, msg), getStackLevel(className, funcName, msg, null, reverseCallStack, false)); } }, /** * * Print a <em>warning</em> log message, if at least <code>warn</code> (3) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ warn : function(className, funcName, msg, reverseCallStack){ if(this.isWarn()){ print( this.name, 3 /*getAsLevel('warn')*/, createMsg(className, funcName, msg), getStackLevel(className, funcName, msg, null, reverseCallStack, false)); } }, /** * * Print an <em>error</em> log message, if at least <code>error</code> (4) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {Error} [error] OPTIONAL * an error object: if available, its message and error-stack will be print to the output * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ error : function(className, funcName, msg, error, reverseCallStack){ if(this.isError()){ printe(this.name, 4 /*getAsLevel('error')*/, className, funcName, msg, error, getStackLevel(className, funcName, msg, error, reverseCallStack, true)); } }, /** * * Print a <em>critical</em> (exception) log message, if at least <code>critical</code> (5) log-level is set. * * @param {String} [className] OPTIONAL * the name of the class/object from which the logging is invoked from * @param {String} [funcName] OPTIONAL * the name of the function (within the class) from which the logging is invoked from * @param {String} msg * the log message * @param {Error} [error] OPTIONAL * an error object: if available, its message and error-stack will be print to the output * @param {number} [reverseCallStack] OPTIONAL * offset when printing the callstack position/information: a positive number will go further back/up the callstack. * This can be used in logging-helper functions to select the invoking function's position from the callstack instead of * printing the information of the logging-helper function itself. * @public */ critical : function(className, funcName, msg, error, reverseCallStack){ if(this.isCritical()){ printe(this.name, 5 /*getAsLevel('critical')*/, className, funcName, msg, error, getStackLevel(className, funcName, msg, error, reverseCallStack, true)); } }, /** * * Check if the current log-level is at least <code>verbose</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>verbose</code> (0) * @public * * @see #verbose */ isVerbose : function(loggerName){ return this.getLevel() <= 0;// getAsLevel('verbose'); }, /** * * Check if the current log-level is at least <code>debug</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>debug</code> (1) * @public * * @see #debug */ isDebug : function(loggerName){ return this.getLevel() <= 1;//getAsLevel('debug'); }, /** * * Check if the current log-level is at least <code>info</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>info</code> (2) * @public * * @see #info */ isInfo : function(loggerName){ return this.getLevel() <= 2;//getAsLevel('info'); }, /** * * Check if the current log-level is at least <code>warn</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>warn</code> (3) * @public * * @see #warn */ isWarn : function(loggerName){ return this.getLevel() <= 3;//getAsLevel('warn'); }, /** * * Check if the current log-level is at least <code>error</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>error</code> (4) * @public * * @see #error */ isError : function(loggerName){ return this.getLevel() <= 4;//getAsLevel('error'); }, /** * * Check if the current log-level is at least <code>critical</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>critical</code> (5) * @public * * @see #critical */ isCritical : function(loggerName){ return this.getLevel() <= 5;//getAsLevel('critical'); }, /** * * Check if the current log-level is at least <code>disabled</code>. * * @returns {Boolean} * <code>true</code> if at least log-level <code>disable</code> (6) * @public * * @see #getLevel */ isDisabled : function(loggerName){ return this.getLevel() <= 6;//getAsLevel('disabled'); } }; //define alias' /** * Alias for {@link #log}. * * @public * @function l * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#log */ Logger.prototype.l = function(){ return this.log.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #verbose}. * * @public * @function v * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#verbose */ Logger.prototype.v = function(){ return this.verbose.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #debug}. * * @public * @function d * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#debug */ Logger.prototype.d = function(){ return this.debug.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #info}. * * @public * @function i * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#info */ Logger.prototype.i = function(){ return this.info.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #warn}. * * @public * @function w * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#warn */ Logger.prototype.w = function(){ return this.warn.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #error}. * * @public * @function e * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#error */ Logger.prototype.e = function(){ return this.error.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * Alias for {@link #critical}. * * @public * @function c * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#critical */ Logger.prototype.c = function(){ return this.critical.apply(this, applyReverseCallStackWith(arguments, 1)); }; /** * @scope Logger# */ /** * Alias for {@link #isVerbose}. * * @public * @function isv * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isVerbose */ Logger.prototype.isv = function(){ return this.isVerbose.apply(this, arguments); }; /** * Alias for {@link #isDebug}. * * @public * @function isd * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isDebug */ Logger.prototype.isd = function(){ return this.isDebug.apply(this, arguments); }; /** * Alias for {@link #isInfo}. * * @public * @function isi * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isInfo */ Logger.prototype.isi = function(){ return this.isInfo.apply(this, arguments); }; /** * Alias for {@link #isWarn}. * * @public * @function isw * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isWarn */ Logger.prototype.isw = function(){ return this.isWarn.apply(this, arguments); }; /** * Alias for {@link #isError}. * * @public * @function ise * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isError */ Logger.prototype.ise = function(){ return this.isError.apply(this, arguments); }; /** * Alias for {@link #isCritical}. * * @public * @function isc * @memberOf mmir.tools.Logger# * @copydoc mmir.tools.Logger#isCritical */ Logger.prototype.isc = function(){ return this.isCrictial.apply(this, arguments); }; /** * The default logger: * access by invoking {@link mmir.Logging#create} without arguments * @private * @type mmir.tools.Logger * @memberOf mmir.Logging * @member _defaultLogger * @inner * @example * var defaultLogger = mmir.require('mmirf/logger').create(); */ var _defaultLogger = new Logger(); //default logger always has default/global log-level: /** * @copydoc mmir.tools.Logger#getLevel * @memberOf mmir.Logging~_defaultLogger */ _defaultLogger.getLevel = function(){ return _level; }; //the instance for the Logging factory: var instance = /** @lends mmir.Logging.prototype */ {//public API /** * Creates a {@link mmir.tools.Logger} instance. * * If a logger for <code>loggerName</code> already exists, * the existing logger is returned (instead of creating a new one). * * @param {String|Object} [loggerName] * If String: a name / ID for the logger that should be created / retrieved.<br> * If Object: an requirejs <code>module</code> object, i.e. should contain properties * <code>id</code> (String) which will set the <code>loggerName</code>, and a property/function * <code>config</code> (Function) that returns an object with property * <code>logLevel</code> (i.e. <code>config().logLevel</code> should be valid).<br> * If omitted, the default logger will be returned. * @param {String|LogLevel} [logLevel] * a name / ID for the logger that should be created / retrieved. * If omitted, the default logger will be returned. * * @returns {mmir.tools.Logger} the created (or retrieved) logger * * @memberOf mmir.Logging.prototype * @public * * @see mmir.tools.Logger * @see mmir.tools.Logger#setLevel */ create: function(loggerName, logLevel){ //special argument: is first argument is a (requirejs) module? if(typeof loggerName === 'object' && loggerName && loggerName.id){ //extract parameters from module object: if(typeof loggerName.config === 'function'){ logLevel = loggerName.config(loggerName).logLevel;//<- may be undefined } else if(typeof WEBPACK_BUILD !== 'undefined' && WEBPACK_BUILD){ //NOTE automatic injection by webpack of config-function (into module) does not work here, because loggerName is generic & webpack cannot statically inter its type as Module // -> explicitly use module.config() helper module: logLevel = require('build-tool/module-config-helper').config(loggerName).logLevel;//<- may be undefined } loggerName = loggerName.id; } //no logger specified: return default logger if(! loggerName){ return _defaultLogger; } if(typeof loggerName !== 'string'){ loggerName = loggerName.toString(); } //return specified logger var theLogger = _loggers.get(loggerName); if(typeof theLogger === 'undefined'){ if(typeof logLevel === 'undefined'){ logLevel = _logLevels.get(loggerName); // if(typeof logLevel === 'number'){ // console.log('using predefined log level ', logLevel, ' for ', loggerName); // } } //create, if not existing var theNewLogger = new Logger(loggerName, logLevel); _loggers.set(loggerName, theNewLogger); return theNewLogger; } if(typeof logLevel !== 'undefined'){ theLogger.setLevel(logLevel); } return theLogger; }, /** * Sets the default log-level. * * This setting is used by loggers, that do not have * a specific log-level set. * * @param {String|Number} theLevel * if NUMBER, the log level as a number between 0 (verbose) and 6 (disabled) * if STRING, the logging level as a string (see {@link #getLevel}) * * @public * * @see #getDefaultLogLevel * @see mmir.tools.Logger#getLevel */ setDefaultLogLevel: function(theLevel){ if(typeof theLevel !== 'number'){ theLevel = getAsLevel(theLevel); } _level = theLevel; }, /** * Sets the default log-level. * * @returns {Number} * the log level: a number between 0 (verbose) and 6 (disabled) * * @public * @see #setDefaultLogLevel * @see mmir.tools.Logger#getLevel */ getDefaultLogLevel: function(){ return _level; }, /** * Print log output with default logger. * @public * @see mmir.tools.Logger#log */ log: function(){ _defaultLogger.log.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }, /** * Print verbose output with default logger. * @public * @see mmir.tools.Logger#verbose */ verbose: function(){ _defaultLogger.verbose.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }, /** * Print debug message with default logger. * @public * @see mmir.tools.Logger#debug */ debug: function(){ _defaultLogger.debug.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }, /** * Print information message with default logger. * @public * @see mmir.tools.Logger#info */ info: function(){ _defaultLogger.info.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }, /** * Print warning message with default logger. * @public * @see mmir.tools.Logger#warn */ warn: function(){ _defaultLogger.warn.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }, /** * Print error with default logger. * @public * @see mmir.tools.Logger#error */ error: function(){ _defaultLogger.error.apply(_defaultLogger, applyReverseCallStackWith(arguments, 1)); }//, // isDebug : function(loggerName){ // return _level <= getAsLevel('debug'); // }, // isInfo : function(loggerName){ // return _level <= getAsLevel('info'); // }, // isWarn : function(loggerName){ // return _level <= getAsLevel('warn'); // }, // isError : function(loggerName){ // return _level <= getAsLevel('error'); // } }; //define alias' instance.get = instance.create; return instance; });