1 /* 2 * Copyright (C) 2012-2015 DFKI GmbH 3 * Deutsches Forschungszentrum fuer Kuenstliche Intelligenz 4 * German Research Center for Artificial Intelligence 5 * http://www.dfki.de 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sublicense, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28 29 define(['dictionary', 'stacktrace', 'module'], 30 /** 31 * A Logger factory.<br> 32 * 33 * @example 34 * //use logger 35 * var Logger = require('logger'); 36 * var log = Logger.create('example'); 37 * 38 * if(log.isVerbose()) log.debug('test');//will write the message to debug-console) 39 * log.error(new Error());//will write the error (including its stack) to error console) 40 * 41 * //example for setting up a logger in a requirejs-module: 42 * define(['logger', 'module'], function(Logger, module){ 43 * 44 * var logger = Logger.create(module); 45 * //this would create the same logger-object: 46 * // Logger.create(module.id, module.config().logLevel); 47 * 48 * //use the logger instance... 49 * 50 * //create / retrieve the same logger 51 * var sameLogger = Logger.create(module.id); 52 * 53 * }); 54 * 55 * @class 56 * @name Logging 57 * @memberOf mmir 58 * @static 59 * 60 * @see Logger 61 * 62 */ 63 function(Dictionary, stacktrace, module){ 64 65 66 var _loggers = new Dictionary(); 67 //var logLevels = new Dictionary(); 68 69 /** 70 * the (global) logging level 71 * 72 * 0: verbose 73 * 1: debug 74 * 2: info 75 * 3: warn 76 * 4: error 77 * 5: critical 78 * 6: disabled 79 * 80 * @memberOf mmir.Logging# 81 */ 82 var _level = 1; 83 84 /** 85 * @private 86 * @type String 87 * @memberOf mmir.Logging# 88 */ 89 var tmpLogLevel = module.config().logLevel; 90 if(typeof tmpLogLevel !== 'undefined'){ 91 if(typeof tmpLogLevel !== 'number'){ 92 tmpLogLevel = getAsLevel(tmpLogLevel); 93 } 94 _level = tmpLogLevel; 95 } 96 97 98 // //TODO extend / implement helpers for writing CSV file data 99 // var csvHeader = [ 100 // 'User name', 'Time', 'Modality', 'Recognized speech', 'Event name', 'Event data', 'Dialog state' 101 // ]; 102 // 103 // function getCsvLine(){ 104 // return new Array(csvHeader.length); 105 // } 106 107 /** 108 * Get the log-level as number. 109 * 110 * @param {String} strLogLevel 111 * the string representation for the log-level 112 * @returns {Number} 113 * the log-level as number 114 * @private 115 * @memberOf Logger.prototype 116 * 117 * @see #getLevel 118 */ 119 function getAsLevel(strLogLevel){ 120 if(typeof strLogLevel === 'string'){ 121 var str = strLogLevel.toLowerCase(); 122 if(str === 'verbose'){ 123 return 0; 124 } else if(str === 'debug'){ 125 return 1; 126 } else if(str === 'info'){ 127 return 2; 128 } else if(str === 'warn'){ 129 return 3; 130 } else if(str === 'error'){ 131 return 4; 132 } else if(str === 'critical'){ 133 return 5; 134 } else if(str === 'disabled'){ 135 return 6; 136 } else 137 throw new Error('Logger.getAsLevel: unknown parameter value "'+strLogLevel+'"'); 138 } 139 140 throw new TypeError('Logger.getAsLevel: parameter must be number or string, but "'+strLogLevel+'" is '+typeof strLogLevel); 141 } 142 143 /** 144 * print log message with error information. 145 * 146 * @private 147 * @memberOf Logger.prototype 148 */ 149 function printe(loggerName, logLevel, className, funcName, msg, error){ 150 151 if( isErr(className)){ 152 error = className; 153 className = ''; 154 } else if( isErr(funcName) ){ 155 error = funcName; 156 funcName = void(0); 157 if(typeof className === 'undefined'){ 158 className = ''; 159 } 160 } else if( isErr(msg) ){ 161 error = msg; 162 msg = void(0); 163 if(typeof className === 'undefined'){ 164 if(typeof funcName === 'undefined'){ 165 className = ''; 166 } 167 else { 168 className = funcName; 169 funcName = void(0); 170 } 171 } 172 } 173 174 print(loggerName, logLevel, createErr(createMsg(className, funcName, msg), error), true); 175 } 176 177 /** 178 * creates the message text. 179 * 180 * @returns {string} the message text 181 * 182 * @private 183 * @memberOf Logger.prototype 184 */ 185 function createMsg(className, funcName, msg){ 186 187 var out; 188 189 if(className){ 190 if(funcName){ 191 if(msg){ 192 out = className+'.'+funcName+': '+msg; 193 } else { 194 195 // if(arguments.callee !== 'undefined'){ 196 // out('callee: '+arguments.callee()); 197 // } 198 199 out = className+': '+funcName; 200 } 201 } else { 202 203 // if(arguments.callee !== 'undefined'){ 204 // out('callee: '+arguments.callee()); 205 // } 206 207 out = className; 208 } 209 } else { 210 211 // if(arguments.callee !== 'undefined'){ 212 // out('callee: '+arguments.callee()); 213 // } 214 215 if(typeof className === 'undefined'){ 216 out = 'UNDEFINED'; 217 } else if(typeof className !== 'string'){ 218 out = Object.prototype.toString.call(null, className); 219 } else { 220 out = className; 221 } 222 } 223 224 return out; 225 } 226 227 /** 228 * HELPER: check if errObj is an Error 229 * 230 * @returns {Boolean} 231 * 232 * @private 233 * @memberOf Logger.prototype 234 */ 235 function isErr(errObj){ 236 237 //TODO also do feature detection for error-like objects? 238 return errObj instanceof Error; 239 } 240 241 /** 242 * Creates error message (with stack trace, if possible). 243 * 244 * @returns {string} the error message 245 * 246 * @private 247 * @memberOf Logger.prototype 248 */ 249 function createErr(msg, error){ 250 251 var err =''; 252 var errMsg = ''; 253 var re; 254 if(error){ 255 256 if(error.name){ 257 err = '<'+error.name+'> '; 258 } 259 260 if(error.number){ 261 err += '#'+error.number+' '; 262 } 263 264 if(error.stack){ 265 266 errMsg = error.stack; 267 268 if(error.name && (re = new RegExp('^'+error.name)).test(errMsg)){ 269 errMsg = errMsg.replace(re, ''); 270 } 271 272 } else { 273 274 if(error.message){ 275 errMsg = ' - ' + error.message; 276 } 277 278 if(error.description){ 279 errMsg = ' - ' + error.description; 280 } 281 282 if(error.fileName){ 283 284 var lineNo = ''; 285 286 if(error.lineNumber){ 287 lineNo = ', line ' + error.lineNumber; 288 } 289 290 errorMsg += ' ('+error.fileName+lineNo+')'; 291 } 292 } 293 294 } 295 296 return err+msg+errMsg; 297 } 298 /** 299 * @private 300 * @memberOf Logger.prototype 301 */ 302 function print(loggerName, logLevel, msg){ 303 var prefix, func; 304 switch(logLevel){ 305 case 0: 306 prefix = '[VERBOSE] '; 307 func = 'log'; 308 break; 309 case 1: 310 prefix = '[DEBUG] '; 311 func = 'debug'; 312 break; 313 case 2: 314 prefix = '[INFO] '; 315 func = 'info'; 316 break; 317 case 3: 318 prefix = '[WARN] '; 319 func = 'warn'; 320 break; 321 case 4: 322 prefix = '[ERROR] '; 323 func = 'error'; 324 break; 325 case 5: 326 prefix = '[CRITICAL] '; 327 func = 'error'; 328 break; 329 case 6: //debug-level "disabled" -> do nothing 330 return; /////////////////// EARLY EXIT ////////// 331 default: 332 prefix = '[UNDEF_LOG_LEVEL_'+logLevel+'] '; 333 func = 'log'; 334 break; 335 } 336 console[func](prefix + loggerName + msg); 337 } 338 339 340 //enable tracing? 341 /** 342 * configuration value for enabling/disabling tracing in log-output 343 * @private 344 * @type Object 345 * @memberOf Logger.prototype 346 */ 347 var tmpTraceConfig = module.config().trace; 348 if(tmpTraceConfig !== false || (tmpTraceConfig !== null && typeof tmpTraceConfig === 'object' && tmpTraceConfig.trace === true)){ 349 350 /** 351 * options object for tracing 352 * @private 353 * @type Object 354 * @memberOf Logger.prototype 355 */ 356 var pnTraceOptions = tmpTraceConfig === true? void(0) : tmpTraceConfig; 357 /** 358 * setting for trace-depth (i.e. stack-depth) 359 * @private 360 * @type Boolean 361 * @memberOf Logger.prototype 362 */ 363 var isFullStackDepth = pnTraceOptions && pnTraceOptions.depth === "full"; 364 365 /** 366 * proxy object for storing the original implementation 367 * of {@link Logger.prototype#print} function. 368 * 369 * (only used, if tracing is enabled!) 370 * 371 * @private 372 * @type Function 373 * @memberOf Logger.prototype 374 */ 375 var pnOriginal = print; 376 377 //do enable tracing: append stacktrace to messages in print-function 378 if(isFullStackDepth){ 379 380 //NOTE code duplication for the sake of a more efficient print function 381 382 /** 383 * Extension for {@link Logger.prototype#print} function with tracing. 384 * 385 * This extension prints the full stack trace in log-output. 386 * 387 * (only used, if tracing is enabled!) 388 * 389 * @private 390 * @name printFullStack 391 * @function 392 * @memberOf Logger.prototype 393 */ 394 print = function printFullStack(loggerName, logLevel, msg, isErrInvoked){ 395 if(typeof msg === 'undefined' || msg === null){ 396 msg = ''; 397 } 398 //if isErrInvoked is TRUE: this function was invoked via additional printe()-call 399 // => need to take 1 more step down the stack 400 msg += '\n ' + stacktrace(pnTraceOptions).slice(isErrInvoked? 6 : 5).join('\n '); 401 pnOriginal.call(this, loggerName, logLevel, msg); 402 }; 403 } 404 else { 405 406 //NOTE code duplication for the sake of a more efficient print function 407 408 /** 409 * Extension for {@link Logger.prototype#print} function with tracing. 410 * 411 * This extension prints only the first entry of the stack trace in log-output. 412 * 413 * (only used, if tracing is enabled!) 414 * 415 * @private 416 * @name printStack 417 * @function 418 * @memberOf Logger.prototype 419 */ 420 print = function printStack(loggerName, logLevel, msg, isErrInvoked){ 421 if(typeof msg === 'undefined' || msg === null){ 422 msg = ''; 423 } 424 //if isErrInvoked is TRUE: this function was invoked via additional printe()-call 425 // => need to take 1 more step down the stack 426 msg += '\n ' + stacktrace(pnTraceOptions)[isErrInvoked? 6 : 5]; 427 pnOriginal.call(this, loggerName, logLevel, msg); 428 }; 429 } 430 431 } 432 433 /** 434 * Constructor-Method of Class Logger<br> 435 * @constructor 436 * @class Logger 437 * @name Logger 438 * 439 * @param {String} theName 440 * the name / ID for the logger 441 * @param {String|Number} [theLevel] OPTIONAL 442 * the log-level. 443 * If omitted, the logger will use 444 * the default log-level 445 * 446 * @see #getAsLevel 447 * @see #getLevel 448 */ 449 function Logger(theName, theLevel){ 450 451 //the name (/key) for the logger instance 452 this.name = ''; 453 if(typeof theName !== 'undefined'){ 454 this.name = '['+theName+'] '; 455 } 456 457 if(typeof theLevel !== 'undefined'){ 458 if(typeof theLevel !== 'number'){ 459 theLevel = getAsLevel(theLevel); 460 } 461 462 this.level = theLevel; 463 } 464 } 465 466 Logger.prototype = 467 /** @lends Logger# */ 468 {//public instance members 469 470 /** 471 * Get the current log-level: 472 * if a specific log-level for this Logger instance is set, 473 * this value is returned. 474 * Otherwise, the default log-level as returned by {@link mmir.Logging#getDefaultLogLevel} 475 * is used. 476 * 477 * Log-levels: 478 * <ul> 479 * <li>0: verbose</li> 480 * <li>1: debug</li> 481 * <li>2: info</li> 482 * <li>3: warn</li> 483 * <li>4: error</li> 484 * <li>5: critical</li> 485 * <li>6: disabled</li> 486 * <ul> 487 * 488 * @returns {Number} the logging level 489 * 490 * @see #setLevel 491 */ 492 getLevel : function(){ 493 494 if(typeof this.level !== 'undefined'){ 495 return this.level; 496 } 497 498 //return default/global logging-level: 499 return _level; 500 }, 501 /** 502 * Set the logging level. 503 * 504 * @param {String|Number} loggingLevel 505 * if {Number} the logging level as a number 506 * if {String} the logging level as a string (see {@link #getLevel}) 507 * 508 * @see #getLevel 509 */ 510 setLevel : function(loggingLevel){ 511 512 if(typeof loggingLevel !== 'number'){ 513 loggingLevel = getAsLevel(loggingLevel); 514 } 515 516 this.level = loggingLevel; 517 }, 518 /** 519 * 520 * Print a log message, if at least <code>debug</code> log-level is set. 521 * 522 * @param {String} [className] OPTIONAL 523 * the name of the class/object from which the logging is invoked from 524 * @param {String} [funcName] OPTIONAL 525 * the name of the function (within the class) from which the logging is invoked from 526 * @param {String} msg 527 * the log message 528 * @param {Error} [error] OPTIONAL 529 * an error object: if available, its message and error-stack will be print to the output 530 * @public 531 */ 532 log: function(className, funcName, msg, error){ 533 if(this.isDebug()){ 534 printe(this.name, 1 /*getAsLevel('debug')*/, className, funcName, msg, error); 535 } 536 }, 537 538 /** 539 * 540 * Print a <em>verbose</em> log message, if at least <code>verbose</code> (0) log-level is set. 541 * 542 * @param {String} [className] OPTIONAL 543 * the name of the class/object from which the logging is invoked from 544 * @param {String} [funcName] OPTIONAL 545 * the name of the function (within the class) from which the logging is invoked from 546 * @param {String} msg 547 * the log message 548 * @public 549 */ 550 //TODO implement/add helpers for file-logging (+ CSV data helpers etc) 551 verbose : function(className, funcName, msg){ 552 if(this.isVerbose()){ 553 print( this.name, 0 /*getAsLevel('verbose')*/, createMsg(className, funcName, msg)); 554 } 555 }, 556 557 /** 558 * 559 * Print a <em>debug</em> log message, if at least <code>debug</code> (1) log-level is set. 560 * 561 * @param {String} [className] OPTIONAL 562 * the name of the class/object from which the logging is invoked from 563 * @param {String} [funcName] OPTIONAL 564 * the name of the function (within the class) from which the logging is invoked from 565 * @param {String} msg 566 * the log message 567 * @public 568 */ 569 debug : function(className, funcName, msg){ 570 if(this.isDebug()){ 571 print( this.name, 1 /*getAsLevel('debug')*/, createMsg(className, funcName, msg)); 572 } 573 }, 574 575 /** 576 * 577 * Print an <em>information</em> log message, if at least <code>info</code> (2) log-level is set. 578 * 579 * @param {String} [className] OPTIONAL 580 * the name of the class/object from which the logging is invoked from 581 * @param {String} [funcName] OPTIONAL 582 * the name of the function (within the class) from which the logging is invoked from 583 * @param {String} msg 584 * the log message 585 * @public 586 */ 587 info : function(className, funcName, msg){ 588 if(this.isInfo()){ 589 print( this.name, 2 /*getAsLevel('info')*/, createMsg(className, funcName, msg)); 590 } 591 }, 592 593 /** 594 * 595 * Print a <em>warning</em> log message, if at least <code>warn</code> (3) log-level is set. 596 * 597 * @param {String} [className] OPTIONAL 598 * the name of the class/object from which the logging is invoked from 599 * @param {String} [funcName] OPTIONAL 600 * the name of the function (within the class) from which the logging is invoked from 601 * @param {String} msg 602 * the log message 603 * @public 604 */ 605 warn : function(className, funcName, msg){ 606 if(this.isWarn()){ 607 print( this.name, 3 /*getAsLevel('warn')*/, createMsg(className, funcName, msg)); 608 } 609 }, 610 611 /** 612 * 613 * Print an <em>error</em> log message, if at least <code>error</code> (4) log-level is set. 614 * 615 * @param {String} [className] OPTIONAL 616 * the name of the class/object from which the logging is invoked from 617 * @param {String} [funcName] OPTIONAL 618 * the name of the function (within the class) from which the logging is invoked from 619 * @param {String} msg 620 * the log message 621 * @param {Error} [error] OPTIONAL 622 * an error object: if available, its message and error-stack will be print to the output 623 * @public 624 */ 625 error : function(className, funcName, msg, error){ 626 if(this.isError()){ 627 printe(this.name, 4 /*getAsLevel('error')*/, className, funcName, msg, error); 628 } 629 }, 630 631 /** 632 * 633 * Print a <em>critical</em> (exception) log message, if at least <code>critical</code> (5) log-level is set. 634 * 635 * @param {String} [className] OPTIONAL 636 * the name of the class/object from which the logging is invoked from 637 * @param {String} [funcName] OPTIONAL 638 * the name of the function (within the class) from which the logging is invoked from 639 * @param {String} msg 640 * the log message 641 * @param {Error} [error] OPTIONAL 642 * an error object: if available, its message and error-stack will be print to the output 643 * @public 644 */ 645 critical : function(className, funcName, msg, error){ 646 if(this.isCritical()){ 647 printe(this.name, 5 /*getAsLevel('critical')*/, className, funcName, msg, error); 648 } 649 }, 650 651 /** 652 * 653 * Check if the current log-level is at least <code>verbose</code>. 654 * 655 * @returns {Boolean} 656 * <code>true</code> if at least log-level <code>verbose</code> (0) 657 * @public 658 * 659 * @see #verbose 660 */ 661 isVerbose : function(loggerName){ 662 return this.getLevel() <= 0;// getAsLevel('verbose'); 663 }, 664 665 /** 666 * 667 * Check if the current log-level is at least <code>debug</code>. 668 * 669 * @returns {Boolean} 670 * <code>true</code> if at least log-level <code>debug</code> (1) 671 * @public 672 * 673 * @see #debug 674 */ 675 isDebug : function(loggerName){ 676 return this.getLevel() <= 1;//getAsLevel('debug'); 677 }, 678 679 /** 680 * 681 * Check if the current log-level is at least <code>info</code>. 682 * 683 * @returns {Boolean} 684 * <code>true</code> if at least log-level <code>info</code> (2) 685 * @public 686 * 687 * @see #info 688 */ 689 isInfo : function(loggerName){ 690 return this.getLevel() <= 2;//getAsLevel('info'); 691 }, 692 693 /** 694 * 695 * Check if the current log-level is at least <code>warn</code>. 696 * 697 * @returns {Boolean} 698 * <code>true</code> if at least log-level <code>warn</code> (3) 699 * @public 700 * 701 * @see #warn 702 */ 703 isWarn : function(loggerName){ 704 return this.getLevel() <= 3;//getAsLevel('warn'); 705 }, 706 707 /** 708 * 709 * Check if the current log-level is at least <code>error</code>. 710 * 711 * @returns {Boolean} 712 * <code>true</code> if at least log-level <code>error</code> (4) 713 * @public 714 * 715 * @see #error 716 */ 717 isError : function(loggerName){ 718 return this.getLevel() <= 4;//getAsLevel('error'); 719 }, 720 721 /** 722 * 723 * Check if the current log-level is at least <code>critical</code>. 724 * 725 * @returns {Boolean} 726 * <code>true</code> if at least log-level <code>critical</code> (5) 727 * @public 728 * 729 * @see #critical 730 */ 731 isCritical : function(loggerName){ 732 return this.getLevel() <= 5;//getAsLevel('critical'); 733 }, 734 735 /** 736 * 737 * Check if the current log-level is at least <code>disabled</code>. 738 * 739 * @returns {Boolean} 740 * <code>true</code> if at least log-level <code>disable</code> (6) 741 * @public 742 * 743 * @see #getLevel 744 */ 745 isDisabled : function(loggerName){ 746 return this.getLevel() <= 6;//getAsLevel('disabled'); 747 } 748 }; 749 750 //define alias' 751 752 /** 753 * Alias for {@link #log}. 754 * 755 * @public 756 * @var {Function} Logger#l 757 */ 758 Logger.prototype.l = function(){ 759 return this.log.apply(this, arguments); 760 }; 761 762 /** 763 * Alias for {@link #verbose}. 764 * 765 * @public 766 * @var {Function} Logger#v 767 */ 768 Logger.prototype.v = function(){ 769 return this.verbose.apply(this, arguments); 770 }; 771 772 /** 773 * Alias for {@link #debug}. 774 * 775 * @public 776 * @var {Function} Logger#d 777 */ 778 Logger.prototype.d = function(){ 779 return this.debug.apply(this, arguments); 780 }; 781 782 /** 783 * Alias for {@link #info}. 784 * 785 * @public 786 * @var {Function} Logger#i 787 */ 788 Logger.prototype.i = function(){ 789 return this.info.apply(this, arguments); 790 }; 791 792 /** 793 * Alias for {@link #warn}. 794 * 795 * @public 796 * @var {Function} Logger#w 797 */ 798 Logger.prototype.w = function(){ 799 return this.warn.apply(this, arguments); 800 }; 801 802 /** 803 * Alias for {@link #error}. 804 * 805 * @public 806 * @var {Function} Logger#e 807 */ 808 Logger.prototype.e = function(){ 809 return this.error.apply(this, arguments); 810 }; 811 812 /** 813 * Alias for {@link #critical}. 814 * 815 * @public 816 * @var {Function} Logger#c 817 */ 818 Logger.prototype.c = function(){ 819 return this.critical.apply(this, arguments); 820 }; 821 822 /** 823 * @scope Logger# 824 */ 825 826 /** 827 * Alias for {@link #isVerbose}. 828 * 829 * @public 830 * @var {Function} Logger#isv 831 */ 832 Logger.prototype.isv = function(){ 833 return this.isVerbose.apply(this, arguments); 834 }; 835 836 /** 837 * Alias for {@link #isDebug}. 838 * 839 * @public 840 * @var {Function} Logger#isd 841 */ 842 Logger.prototype.isd = function(){ 843 return this.isDebug.apply(this, arguments); 844 }; 845 846 /** 847 * Alias for {@link #isInfo}. 848 * 849 * @public 850 * @var {Function} Logger#isi 851 */ 852 Logger.prototype.isi = function(){ 853 return this.isInfo.apply(this, arguments); 854 }; 855 856 /** 857 * Alias for {@link #isWarn}. 858 * 859 * @public 860 * @var {Function} Logger#isw 861 */ 862 Logger.prototype.isw = function(){ 863 return this.isWarn.apply(this, arguments); 864 }; 865 866 /** 867 * Alias for {@link #isError}. 868 * 869 * @public 870 * @var {Function} Logger#ise 871 */ 872 Logger.prototype.ise = function(){ 873 return this.isError.apply(this, arguments); 874 }; 875 876 /** 877 * Alias for {@link #isCritical}. 878 * 879 * @public 880 * @var {Function} Logger#isc 881 */ 882 Logger.prototype.isc = function(){ 883 return this.isCrictial.apply(this, arguments); 884 }; 885 886 887 /** 888 * @private 889 * @type Logger 890 * @memberOf mmir.Logging# 891 */ 892 var _defaultLogger = new Logger(); 893 //default logger always has default/global log-level: 894 /** 895 * @inheritdoc 896 */ 897 _defaultLogger.getLevel = function(){ 898 return _level; 899 }; 900 901 //the instance for the Logging factory: 902 var instance = 903 /** @lends mmir.Logging.prototype */ 904 {//public API 905 906 /** 907 * Creates a {@link Logger} instance. 908 * 909 * If a logger for <code>loggerName</code> already exists, 910 * the existing logger is returned (instead of creating a new one). 911 * 912 * @param {String|Object} [loggerName] 913 * If String: a name / ID for the logger that should be created / retrieved.<br> 914 * If Object: an requirejs <code>module</code> object, i.e. should contain properties 915 * <code>id</code> (String) which will set the <code>loggerName</code>, and a property/function 916 * <code>config</code> (Function) that returns an object with property 917 * <code>logLevel</code> (i.e. <code>config().logLevel</code> should be valid).<br> 918 * If omitted, the default logger will be returned. 919 * @param {String} [logLevel] 920 * a name / ID for the logger that should be created / retrieved. 921 * If omitted, the default logger will be returned. 922 * 923 * @returns {Logger} the created (or retrieved) logger 924 * 925 * @memberOf mmir.Logging.prototype 926 * @public 927 * 928 * @see Logger 929 * @see Logger#setLevel 930 */ 931 create: function(loggerName, logLevel){ 932 933 //special argument: is first argument is a (requirejs) module? 934 if(typeof loggerName === 'object' && loggerName && loggerName.id && typeof loggerName.config === 'function'){ 935 //extract parameters from module object: 936 logLevel = loggerName.config().logLevel;//<- may be undefined 937 loggerName = loggerName.id; 938 } 939 940 //no logger specified: return default logger 941 if(! loggerName){ 942 return _defaultLogger; 943 } 944 945 if(typeof loggerName !== 'string'){ 946 loggerName = loggerName.toString(); 947 } 948 949 //return specified logger 950 var theLogger = _loggers.get(loggerName); 951 if(typeof theLogger === 'undefined'){ 952 //create, if not existing 953 var theNewLogger = new Logger(loggerName, logLevel); 954 _loggers.put(loggerName, theNewLogger); 955 956 return theNewLogger; 957 } 958 959 if(typeof logLevel !== 'undefined'){ 960 theLogger.setLevel(logLevel); 961 } 962 963 return theLogger; 964 }, 965 /** 966 * Sets the default log-level. 967 * 968 * This setting is used by loggers, that do not have 969 * a specific log-level set. 970 * 971 * @param {Number} theLevel 972 * the log level: a number between 0 (verbose) and 6 (disabled) 973 * 974 * @public 975 * 976 * @see #getDefaultLogLevel 977 * @see Logger#getLevel 978 */ 979 setDefaultLogLevel: function(theLevel){ 980 _level = theLevel; 981 }, 982 /** 983 * Sets the default log-level. 984 * 985 * @returns {Number} 986 * the log level: a number between 0 (verbose) and 6 (disabled) 987 * 988 * @public 989 * @see #setDefaultLogLevel 990 * @see Logger#getLevel 991 */ 992 getDefaultLogLevel: function(){ 993 return _level; 994 }, 995 /** 996 * Print log output with default logger. 997 * @public 998 * @see Logger#log 999 */ 1000 log: function(){ 1001 _defaultLogger.log.apply(_defaultLogger, arguments); 1002 }, 1003 /** 1004 * Print verbose output with default logger. 1005 * @public 1006 * @see Logger#verbose 1007 */ 1008 verbose: function(){ 1009 _defaultLogger.verbose.apply(_defaultLogger, arguments); 1010 }, 1011 /** 1012 * Print debug message with default logger. 1013 * @public 1014 * @see Logger#debug 1015 */ 1016 debug: function(){ 1017 _defaultLogger.debug.apply(_defaultLogger, arguments); 1018 }, 1019 /** 1020 * Print information message with default logger. 1021 * @public 1022 * @see Logger#info 1023 */ 1024 info: function(){ 1025 _defaultLogger.info.apply(_defaultLogger, arguments); 1026 }, 1027 /** 1028 * Print warning message with default logger. 1029 * @public 1030 * @see Logger#warn 1031 */ 1032 warn: function(){ 1033 _defaultLogger.warn.apply(_defaultLogger, arguments); 1034 }, 1035 /** 1036 * Print error with default logger. 1037 * @public 1038 * @see Logger#error 1039 */ 1040 error: function(){ 1041 _defaultLogger.error.apply(_defaultLogger, arguments); 1042 }//, 1043 // isDebug : function(loggerName){ 1044 // return _level <= getAsLevel('debug'); 1045 // }, 1046 // isInfo : function(loggerName){ 1047 // return _level <= getAsLevel('info'); 1048 // }, 1049 // isWarn : function(loggerName){ 1050 // return _level <= getAsLevel('warn'); 1051 // }, 1052 // isError : function(loggerName){ 1053 // return _level <= getAsLevel('error'); 1054 // } 1055 }; 1056 1057 //define alias' 1058 instance.get = instance.create; 1059 1060 1061 return instance; 1062 1063 }); 1064