/* * Copyright © 2012, 2013 Pedro Agullo Soliveres. * * This file is part of Log4js-ext. * * Log4js-ext is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License. * * Commercial use is permitted to the extent that the code/component(s) * do NOT become part of another Open Source or Commercially developed * licensed development library or toolkit without explicit permission. * * Log4js-ext is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Log4js-ext. If not, see <http://www.gnu.org/licenses/>. * * This software uses the ExtJs library (http://extjs.com), which is * distributed under the GPL v3 license (see http://extjs.com/license). */ (function() { "use strict"; //$NON-NLS-1$ /** * A logger performs logging using the error, info, debug and other * functions. * * Logged data is handled by the logger appenders * (see {@link Sm.log.AppenderBase}), * or its parent's appenders, * that send it somewhere: the console, a window, etc. * * An appender will need to format data, and it will use its * layout (see {@link Sm.log.LayoutBase}) for that purpose. */ Ext.define('Sm.log.Logger', { //$NON-NLS-1$ uses : ['Ext.Array', 'Sm.log.Level', 'Sm.log.LoggingEvent', 'Sm.log.ExtLogAppender', 'Sm.log.util.Assert'], config : { /** * @cfg {String} [=assigned in constructor] (required) * @accessor * * The logger's category. * * This can be considered the logger name, too. * * @readonly */ category : '', // Method automatically generated for config.category /** * @method setCategory * @private */ /** * @cfg {Sm.log.Level} * @accessor * * The level for this logger, or null. * * Logs with a level lesser than this level will be ignored. * See {@link #getEffectiveLevel} for additional information. */ level : null, /** * @cfg * @accessor * * If set to false, disables all logging. */ enabled : true, /** * @cfg {Array} * @accessor * * The appenders to which this logger outputs directly. * * See {@link #getEffectiveAppenders} for additional information. * */ appenders : [], // Method automatically generated for config.appender /** * @method setAppenders * @private */ /** * @cfg * @accessor * * If true, this logger will log to its appenders plus its parent * appenders. */ additivity : true }, statics : { /** * If false, no logger will output to its appenders, independently * of the logger enabled state. * * @static * @property */ enabled : true, /** * Returns the root logger, the logger that is the parent of all * other loggers in the application. * * By default, the root logger uses the {@link Sm.log.ExtLogAppender} * to output logs. * * @returns {Sm.log.Logger} The root logger. * * @static */ getRoot : function() { if( this.PRIVATE_root === undefined ) { this.PRIVATE_root = Ext.create('Sm.log.Logger', {category:'', level: Sm.log.Level.TRACE}); this.PRIVATE_root.addAppender(Sm.log.ExtLogAppender); } return this.PRIVATE_root; }, /* loggerExists : function( category ) { var parts, logger, found; if( category === '') { return true; } parts = category.split("."); logger = this.getRoot(); found = true; Ext.Array.forEach( parts, function(part) { Sm.log.util.Assert.assert( part ); if( !logger[part] ) { found = false; return false; } logger = logger[part]; }); return found; }, */ /** * @static * * Returns a logger for the specified category. * * If there is no such logger, it is created. You should never * instantiate loggers with the logger constructor, but rather you * should use this function for that purpose. * * @param {String} category The category for which to get the logger. * * @returns {Sm.log.Logger} * */ getLogger : function( category ) { Sm.log.util.Assert.assert( category !== undefined ); if( !Ext.isString(category) ) { if( category.$isClass ) { category = category.getName(); } else if( category.self ) { category = category.self.geName(); } else { category = category.toString(); } } if( category === '') { return this.getRoot(); } // We take the 'easy' route: we create all the hierachy // of logger: for 'a.b.c' we create a, a.b and a.b.c logger // We could optimize this, but we'll wait until/if it is needed var parts = category.split("."), cat = "", logger = this.getRoot(), loggerProperty; Ext.Array.forEach( parts, function(part) { Sm.log.util.Assert.assert( part ); cat = cat + part; loggerProperty = part + "$SmLgr"; if( !logger[loggerProperty] ) { logger[loggerProperty] = new Sm.log.Logger( {category:cat}); logger[loggerProperty].parentLogger = logger; } logger = logger[loggerProperty]; Sm.log.util.Assert.assert( !Ext.isFunction(logger)); cat = cat + "."; }); return logger; } }, /** * Returns the effective enabled state, taking into account * both this logger enabled property and the static enabled property. * * @returns {Boolean} */ getEffectiveEnabled : function() { return this.getEnabled() && this.self.enabled; }, /** * Returns all appenders to which this logger should log. * * This includes its own appenders, and, if additivity is true, * its parent logger appenders -which in turn might contribute * its own parent appenders if its additivity is set to true. * * @returns {Array} */ getEffectiveAppenders : function() { var result = [], appenders = this.getAppenders(); if( appenders && appenders.length > 0 ) { result = result.concat( appenders); } if( this.parentLogger && this.getAdditivity() ) { result = result.concat( this.parentLogger.getEffectiveAppenders()); } return result; }, /** * Adds a new appender to this logger. * * @param {Sm.log.AppenderBase} appender * The appender to add to this logger. * * @returns {void} */ addAppender : function(appender) { this.getAppenders().push(appender); }, /** * Removes an appender from this logger. * * @param {Sm.log.AppenderBase} appender The appender to remove. * * @returns {void} */ removeAppender : function(appender) { Ext.Array.remove( this.getAppenders(), appender ); }, /** * Removes all appenders from this logger * * @returns {void} */ removeAllAppenders : function() { this.setAppenders( [] ); }, /** * Returns the effective level for this logger. * * If a level has been set by calling {@link #setLevel}, then that will * be the effective level. Else, the parent effective level will be used. * * @returns {Sm.log.Level} The effective level. */ getEffectiveLevel : function() { if( !this.getLevel() ) { return this.parentLogger.getEffectiveLevel(); } return this.getLevel(); }, /** * Logs data with the specified level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param level The log level. * @param messageArgs The arguments for the logging operation. * * @returns {void} */ log : function(level, messageArgs) { var args = [], i; for( i = 1; i < arguments.length; i = i + 1 ) { args.push(arguments[i]); } this.doLog(level, args); }, /** * Logs data with a FATAL level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ fatal : function(messageArgs) { this.doLog(Sm.log.Level.FATAL, arguments); }, /** * Logs data with an ERROR level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ error : function(messageArgs) { this.doLog(Sm.log.Level.ERROR, arguments); }, /** * Logs data with a WARN level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ warn : function(messageArgs) { this.doLog(Sm.log.Level.WARN, arguments); }, /** * Logs data with an INFO level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ info : function() { this.doLog(Sm.log.Level.INFO, arguments); }, /** * Logs data with a DEBUG level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ debug : function(messageArgs) { this.doLog(Sm.log.Level.DEBUG, arguments); }, /** * Logs data with a TRACE level. * * Arguments for this function are variable, and it is possible to * log a simple message, perform advanced formatting or even log objects. * Check this * [link](http://http://code.google.com/p/log4js-ext/wiki/LoggingFormatting) * for examples on how to use this function. * * @param messageArgs The arguments for the logging operation. * * @returns {void} */ trace : function(messageArgs) { this.doLog(Sm.log.Level.TRACE, arguments); }, /** * Returns true if this logger will perform logs with the specified level. * * @param {Sm.log.Level} level The log level. * @returns {Boolean} * true if this logger will perform logs with the specified level. */ isLevelEnabled : function(level) { return this.getEffectiveLevel().le(level); }, /** * Returns true if this logger will perform logs with the FATAL level. * * @returns {Boolean} * true if this logger will perform logs with the FATAL level. */ isFatalEnabled: function() { return this.isLevelEnabled( Sm.log.Level.FATAL); }, /** * Returns true if this logger will perform logs with the ERROR level. * * @returns {Boolean} * true if this logger will perform logs with the ERROR level. */ isErrorEnabled: function() { return this.isLevelEnabled( Sm.log.Level.ERROR); }, /** * Returns true if this logger will perform logs with the WARN level. * * @returns {Boolean} * true if this logger will perform logs with the WARN level. */ isWarnEnabled: function() { return this.isLevelEnabled( Sm.log.Level.WARN); }, /** * Returns true if this logger will perform logs with the INFO level. * * @returns {Boolean} * true if this logger will perform logs with the INFO level. */ isInfoEnabled: function() { return this.isLevelEnabled( Sm.log.Level.INFO); }, /** * Returns true if this logger will perform logs with the DEBUG level. * * @returns {Boolean} * true if this logger will perform logs with the DEBUG level. */ isDebugEnabled: function() { return this.isLevelEnabled( Sm.log.Level.DEBUG); }, /** * Returns true if this logger will perform logs with the TRACE level. * * @returns {Boolean} * true if this logger will perform logs with the TRACE level. */ isTraceEnabled: function() { return this.isLevelEnabled( Sm.log.Level.TRACE); }, /** * @private * * Performs the real log. * * @param {Sm.log.Level} level The log level. * @param args The log arguments. * * @returns {void} */ doLog : function(level, args) { var logEvent, time, cfg, i; Sm.log.util.Assert.assert( level ); Sm.log.util.Assert.assert( args ); Sm.log.util.Assert.assert( args.length >= 1 ); if( !this.getEffectiveEnabled() ) { return; } if( this.isLevelEnabled(level)) { cfg = {}; cfg.level = level; cfg.message = args[0]; cfg.time = new Date(); cfg.category = this.getCategory(); if( args.length > 1 ) { cfg.formatParams = []; for( i = 1; i < args.length; i = i + 1 ) { cfg.formatParams.push( args[i] ); } } Ext.Array.forEach( this.getEffectiveAppenders(), function(appender) { // We create a copy for every appender to avoid appenders // tinkering with events and affecting other appenders logEvent = Ext.create( 'Sm.log.LoggingEvent', cfg ); appender.log( logEvent ); }); } }, /** * @private * * Do not use this: use {@link Sm.log.Logger#getLogger} instead. * */ constructor : function (cfg) { Sm.log.util.Assert.assert(cfg); Sm.log.util.Assert.assert(cfg.category === '' || cfg.category ); this.initConfig(cfg); this.setAppenders( [] ); } }); }());