Zapatec Utils Overview

Overview | File | Class | Tree | Index | Help

Zapatec Utils

PREV NEXT | FRAMES NO FRAMES

## log4js.js

#### Summary

Javascript Logger (in the spirit of log4j) This library is designed to make the writing and debugging of javascript code easier, by allowing the programmer to perform debug or log output at any place in their code. This supports the concept of different levels of logging (debug < info < warn < error < fatal << none) as well as different log outputs. Three log outputs are included, but you can add your own. The included log outputs are Log.writeLogger(), Log.alertLogger(), and Log.popupLogger(). For debugging on Safari, the log ouput Log.consoleLogger() is also included. To turn off debugging but still leave the logger calls in your script, use the log level Log.NONE. Example usage:

     <html>
      <head>
          <script src="log4js.js" type="text/javascript"></script>
      </head>
      <body>
         Log4JS test...<hr/>
         <script>
            // Setup log objects
            //
            //  log object of priority debug and the popup logger
            var log = new Log(Log.DEBUG, Log.popupLogger);
            //  log object of priority warn and the alert logger
            var log2 = new Log(Log.WARN, Log.alertLogger);
            //  log object of priority debug and the console logger (Safari)
            var log3 = new Log(Log.DEBUG, Log.consoleLogger);

            log.debug('foo1');     // will popup a new window and log 'foo'
            log.warn('bar1');      // will add a new 'bar' message to the popup
            log2.debug('foo2');    // will do nothing (Log object's priority threshold is WARN)
            log2.warn('bar2');     // will display a javascript alert with the string 'bar'
            log3.debug('foo3');    // will log message to Safari console or existing popup
            log3.warn('bar3');     // same

     	      log.info(Log.dumpObject(new Array('apple','pear','orange','banana')));
         </script>
      </body>
     </html>

Version: 0.3

    *************************************************************

     Copyright 2005 Fourspaces Consulting, LLC

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License

    *************************************************************

     Changelog:
     0.2 	- Added consoleLogger for Safari
     		- Changed popupLogger so that it only notifies once (or twice)
    		  that a popup blocker is active.
    		- Added Log.NONE level for silencing all logging

Author: Marcus R Breese mailto:mbreese@fourspaces.com

Class Summary
Log | The main Log class.

    // $Id: log4js.js 7554 2007-07-15 17:54:14Z alex $
    /*
     * <pre>
     * Copyright (c) 2004-2006 by Zapatec, Inc.
     * http://www.zapatec.com
     * 1700 MLK Way, Berkeley, California,
     * 94709, U.S.A.
     * All rights reserved.
     * </pre>
     */

    /**
     * @fileoverview Javascript Logger (in the spirit of log4j)
     * This library is designed to make the writing and debugging
     * of javascript code easier, by allowing the programmer to perform
     * debug or log output at any place in their code.  This supports
     * the concept of different levels of logging (debug < info < warn < error < fatal << none)
     * as well as different log outputs.  Three log outputs are included, but you can
     * add your own.  The included log outputs are {@link Log#writeLogger},
     * {@link Log#alertLogger}, and {@link Log#popupLogger}.  For debugging on Safari,
     * the log ouput {@link Log#consoleLogger} is also included.  To turn off debugging
     * but still leave the logger calls in your script, use the log level {@link Log#NONE}.
     *
     * Example usage:
     * <pre>
     * &lt;html&gt;
     *  &lt;head&gt;
     *      &lt;script src="log4js.js" type="text/javascript"&gt;&lt;/script&gt;
     *  &lt;/head&gt;
     *  &lt;body&gt;
     *     Log4JS test...&lt;hr/&gt;
     *     &lt;script&gt;
     *        // Setup log objects
     *        //
     *        //  log object of priority debug and the popup logger
     *        var log = new Log(Log.DEBUG, Log.popupLogger);
     *        //  log object of priority warn and the alert logger
     *        var log2 = new Log(Log.WARN, Log.alertLogger);
     *        //  log object of priority debug and the console logger (Safari)
     *        var log3 = new Log(Log.DEBUG, Log.consoleLogger);
     *
     *        log.debug('foo1');     // will popup a new window and log 'foo'
     *        log.warn('bar1');      // will add a new 'bar' message to the popup
     *        log2.debug('foo2');    // will do nothing (Log object's priority threshold is WARN)
     *        log2.warn('bar2');     // will display a javascript alert with the string 'bar'
     *        log3.debug('foo3');    // will log message to Safari console or existing popup
     *        log3.warn('bar3');     // same
     *
     * 	      log.info(Log.dumpObject(new Array('apple','pear','orange','banana')));
     *     &lt;/script&gt;
     *  &lt;/body&gt;
     * &lt;/html&gt;
     * </pre>
     *
     * @author Marcus R Breese mailto:mbreese@fourspaces.com
     * @license Apache License 2.0
     * @version 0.3
     *<pre>
     **************************************************************
     *
     * Copyright 2005 Fourspaces Consulting, LLC
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License
     *
     **************************************************************
     *
     * Changelog:
     * 0.2 	- Added consoleLogger for Safari
     * 		- Changed popupLogger so that it only notifies once (or twice)
     *		  that a popup blocker is active.
     *		- Added Log.NONE level for silencing all logging
     * </pre>
     */

    /**
     * Create a new logger
     * @constructor
     * @class The main Log class.  Create a new instance of this class to send all logging events.
     * @param level The cut-off logger level.  You can adjust this level in the constructor and leave all other logging events in place.  Defaults to {@link Log#WARN}.
     * @param logger The logger to use.  The logger is a function that accepts the logging events and informs the user or developer. Defaults to {@link Log#writeLogger}.
     */
    function Log(level,logger,prefix) {
    			 var _currentLevel = Log.WARN;
    			 var _logger = Log.writeLogger; // default to write Logger
    			 var _prefix = false;
    			 /**
    				* Sets the current logger prefix
    				* @param {String} prefix This prefix will be prepended to all messages.
    				*/
    			 this.setPrefix = function(pre) {
    					 if (pre!='undefined') { _prefix = pre; }
    		 else { _prefix = false; }
    			 }
    			 /**
    				* Sets the current logger function
    				* @param logger The function that will be called when a log event needs to be displayed
    				*/
    			 this.setLogger = function(logger) {
    					 if (logger!='undefined') { _logger = logger; }
    			 }

    			 /**
    				* Sets the current threshold log level for this Log instance.  Only events that have a priority of this level or greater are logged.
    				* @param level The new threshold priority level for logging events.  This can be one of the static members {@link Log#DEBUG},  {@link Log#INFO}, {@link Log#WARN}, {@link Log#ERROR}, {@link Log#FATAL}, {@link Log#NONE}, or it can be one of the strings ["debug", "info", "warn", "error", "fatal", "none"].
    				*/
    			 this.setLevel = function(level) {
    					 if (level!='undefined' && typeof level =='number') {
    									 _currentLevel = level;
    					 } else if (level!='undefined') {
    									 if (level=='debug') { _currentLevel = Log.DEBUG; }
    									 else if (level=='info') { _currentLevel = Log.INFO; }
    									 else if (level=='error') { _currentLevel = Log.ERROR; }
    									 else if (level=='fatal') { _currentLevel = Log.FATAL; }
    									 else if (level=='warn') { _currentLevel = Log.WARN; }
    									 else { _currentLevel = Log.NONE; }
    					 }
    			 }

    			 /**
    				* Gets the current prefix
    	* @return current prefix
    	*/

    			 this.getPrefix = function() { return _prefix; }

    			 /**
    				* Gets the current event logger function
    	* @return current logger
    	*/

    			 this.getLogger = function() { return _logger; }

    			 /**
    				* Gets the current threshold priority level
    	* @return current level
    	*/

    			 this.getLevel = function() { return _currentLevel; }

    			 if (level!='undefined') { this.setLevel(level); }
    			 if (logger!='undefined') { this.setLogger(logger); }
    			 if (prefix!='undefined') { this.setPrefix(prefix); }
    }
    /**
     * Log an event with priority of "debug"
     * @param s the log message
     */
    Log.prototype.debug     = function(s) { if (this.getLevel()<=Log.DEBUG) { this._log(s,"DEBUG",this); } }

    Log.prototype.json = function(s) {
    	if (Zapatec && Zapatec.Transport) {
    		this.debug(Zapatec.Transport.serializeJsonObj(s));
    	}
    }

    /**
     * Log an event with priority of "info"
     * @param s the log message
     */
    Log.prototype.info      = function(s) { if (this.getLevel()<=Log.INFO ) { this._log(s,"INFO",this); } }
    /**
     * Log an event with priority of "warn"
     * @param s the log message
     */
    Log.prototype.warn      = function(s) { if (this.getLevel()<=Log.WARN ) { this._log(s,"WARN",this); } }
    /**
     * Log an event with priority of "error"
     * @param s the log message
     */
    Log.prototype.error     = function(s) { if (this.getLevel()<=Log.ERROR) { this._log(s,"ERROR",this); } }
    /**
     * Log an event with priority of "fatal"
     * @param s the log message
     */
    Log.prototype.fatal     = function(s) { if (this.getLevel()<=Log.FATAL) { this._log(s,"FATAL",this); } }

    /**
     * _log is the function that actually calling the configured logger function.
     * It is possible that this function could be extended to allow for more
     * than one logger.
     *
     * This method is used by {@link Log#debug}, {@link Log#info}, {@link Log#warn}, {@link Log#error}, and {@link Log#fatal}
     * @private
     * @param {String} msg The message to display
     * @param level The priority level of this log event
     * @param {Log} obj The originating {@link Log} object.
     */
    Log.prototype._log = function(msg,level,obj) {
    	if (this.getPrefix()) {
    		this.getLogger()(this.getPrefix()+" - "+msg,level,obj);
    	} else {
    		this.getLogger()(msg,level,obj);
    	}

    }

    Log.DEBUG       = 1;
    Log.INFO        = 2;
    Log.WARN        = 3;
    Log.ERROR       = 4;
    Log.FATAL       = 5;
    Log.NONE		= 6;

    /**
     * Static alert logger method.  This logger will display a javascript alert (messagebox) with the message.
     * @param {String} msg The message to display
     * @param level The priority level of this log event
     */
    Log.alertLogger = function(msg,level) { alert(level+" - "+msg); }
    /**
     * Static write logger method.  This logger will print the message out to the web page using document.writeln.
     * @param {String} msg The message to display
     * @param level The priority level of this log event
     */
    Log.writeLogger = function(msg,level) { document.writeln(level+"&nbsp;-&nbsp;"+msg+"<br/>"); }

    /**
     * Static Safari WebKit console logger method. This logger will write messages to the Safari javascript console, if available.
     * If this browser doesn't have a javascript console (IE/Moz), then it degrades gracefully to {@link Log#popupLogger}
     * @param {String} msg The message to display
     * @param level The priority level of this log event
     * @param {Log} obj The originating {@link Log} object.
     */
    Log.consoleLogger = function(msg,level,obj) {
    	if (window.console) {
    		window.console.log(level+" - "+msg);
    	} else {
    		Log.popupLogger(msg,level,obj);
    	}
    }

    /**
     * Static popup logger method.  This logger will popup a new window (if necessary), and add the log message to the top of a list.
     * @param {String} msg The message to display
     * @param level The priority level of this log event
     * @param {Log} obj The originating {@link Log} object.
     */
    Log.popupLogger = function(msg,level,obj) {
    			 if (obj.popupBlocker) {
    	return;
    			 }
    			 if (!obj._window || !obj._window.document) {
    							 obj._window = window.open("",'logger_popup_window');
    							 if (!obj._window) { obj.popupBlocker=true; alert("You have a popup window manager blocking the log4js log popup display.\n\nThis must be disabled to properly see logged events."); return; }
    				 if (!obj._window.document.getElementById('loggerTable')) {
    											 obj._window.document.writeln("<table width='100%' id='loggerTable'><tr><th align='left'>Time</th><th width='100%' colspan='2' align='left'>Message</th></tr></table>");
    											 obj._window.document.close();
    							 }
    			 }
    			 var tbl = obj._window.document.getElementById("loggerTable");
    			 var row = tbl.insertRow(1);

    			 var cell_1 = row.insertCell(-1);
    			 var cell_2 = row.insertCell(-1);
    			 var cell_3 = row.insertCell(-1);

    			 var d = new Date();
    			 var h = d.getHours();
    			 if (h<10) { h="0"+h; }
    			 var m = d.getMinutes();
    			 if (m<10) { m="0"+m; }
    			 var s = d.getSeconds();
    			 if (s<10) { s="0"+s; }
    			 var date = (d.getMonth()+1)+"/"+d.getDate()+"/"+d.getFullYear()+"&nbsp;-&nbsp;"+h+":"+m+":"+s;

    			 cell_1.style.fontSize="8pt";
    			 cell_1.style.fontWeight="bold";
    			 cell_1.style.paddingRight="6px";

    			 cell_2.style.fontSize="8pt";

    			 cell_3.style.fontSize="8pt";
    			 cell_3.style.whiteSpace="nowrap";
    			 cell_3.style.width="100%";

    			 if (tbl.rows.length % 2 == 0) {
    				cell_1.style.backgroundColor="#eeeeee";
    				cell_2.style.backgroundColor="#eeeeee";
    				cell_3.style.backgroundColor="#eeeeee";
    			 }

    			 cell_1.innerHTML=date
    			 cell_2.innerHTML=level;
    			 cell_3.innerHTML=msg;
    }

    /**
     * This method is a utility function that takes an object and creates a string representation of it's members.
     * @param {Object} the Object that you'd like to see
     * @return {String} a String representation of the object passed
     */
    Log.dumpObject=function (obj,indent) {
    	if (!indent) { indent="";}
    	if (indent.length>20) { return ; } // don't go too far...
    	var s="{\n";
    		for (var p in obj) {
    			s+=indent+p+":";
    			var type=typeof(obj[p]);
    			type=type.toLowerCase();
    			if (type=='object') {
    				s+= Log.dumpObject(obj[p],indent+"----");
    			} else {
    				s+= obj[p];
    			}
    			s+="\n";
    		}
    		s+=indent+"}";
    		return s;
    }

    /**
     * This method will set the properties for the zpdumpObject config
     * @param {Object} the Object to tune the dump of an object
     */
    Log.zpdumpObject_config=function(objArgs) {

    config={}
    config.indent="&nbsp;&nbsp;&nbsp;"
    config.depth=1;
    config.maxdepth=10;
    config.objSkip={}
    config.objSkip['function']=true
    // Show the value of the variable?
    config.bShowValues=true
    // Show the type of the variable
    config.bShowType=true
    // Skip empty values, empty string,
    config.bSkipEmpty=true
    // Skip undefined
    config.bSkipUndefined=true
    config.bHtml=true
    if (objArgs)
    	for (var i in objArgs)
    		if (config[i] == 'undefined')
    			alert(i + ' is not a valid option')
    		else
    			config[i]=objArgs[i]

    return config
    }

    /*
     * Recursive function to dump the object
     * @param {obj}   - object to dump
     * @param {name}  - name of object
     * @param {configIn} - object to tune the dump of this object
    */
    Log.zpdumpObject=function(obj, name, configIn) {

    var config=Log.zpdumpObject_config(configIn)

    var self=this
    var strEOL=config.bHtml ? "<br>" : '\n'
    var strIndent=config.bHtml ? "&nbsp;&nbsp;&nbsp;" : '\t'

    //----------------------------------------------------------------------------
    //--- RECURSIVE FUNCTION ---
    var funcRecurse=function(obj, name, depth, indent) {

    var strName, strVal, strType, strOut
    if (depth > config.maxdepth)
    	return indent + name + ": <Maximum Depth Reached>" + strEOL;

    if (typeof obj == "object") {
    	var child = null;
    	var output = (indent + name)
    	if (config.bShowType)
    		output+=' (' + typeof obj + ')'
    	output+=strEOL

    	indent += strIndent
    	for (var item in obj) {

    	try {
    		child = obj[item];
    	} catch (e) {
    		child = "<Unable to Evaluate>";
    	}

    	strName=name+'.'+item
    	strType=typeof child
    	strOut = indent + strName
    	if (config.bShowType)
    		strOut += ' ('+strType+')'

    	if (strType=='object')
    		output += funcRecurse(child, strName, depth + 1, indent);
    	else
    	if (config.objSkip[strType] != true)
    	{
    		if (config.bShowValues)
    		{
    			if (config.bSkipEmpty && !child)
    				// Skip properties that has 'empty' values
    				;
    			else
    			if (config.bSkipUndefined && strType == 'undefined')
    				// Skip properties that has undefined values
    				;
    			else
    				output += strOut + "=" + child + strEOL;
    		}
    		else
    				output += strOut + strEOL;
    	} // end not objSkip

    } // end for

    return output;
    }
    else // NOT object, just return the value
    {
    	return obj;
    }
    } // end recurse
    //--- END RECURSIVE FUNCTION ---
    //----------------------------------------------------------------------------

    return funcRecurse(obj, name, 1, '')
    }

    // Makes your life easier
    var log = new Log(Log.DEBUG, Log.popupLogger);

Overview | File | Class | Tree | Index | Help

Zapatec Utils

PREV NEXT | FRAMES NO FRAMES

Documentation generated by JSDoc on Thu Aug 16 12:18:39 2007