Logging.js (9231B)
1 /*** 2 3 MochiKit.Logging 1.4 4 5 See <http://mochikit.com/> for documentation, downloads, license, etc. 6 7 (c) 2005 Bob Ippolito. All rights Reserved. 8 9 ***/ 10 11 if (typeof(dojo) != 'undefined') { 12 dojo.provide('MochiKit.Logging'); 13 dojo.require('MochiKit.Base'); 14 } 15 16 if (typeof(JSAN) != 'undefined') { 17 JSAN.use("MochiKit.Base", []); 18 } 19 20 try { 21 if (typeof(MochiKit.Base) == 'undefined') { 22 throw ""; 23 } 24 } catch (e) { 25 throw "MochiKit.Logging depends on MochiKit.Base!"; 26 } 27 28 if (typeof(MochiKit.Logging) == 'undefined') { 29 MochiKit.Logging = {}; 30 } 31 32 MochiKit.Logging.NAME = "MochiKit.Logging"; 33 MochiKit.Logging.VERSION = "1.4"; 34 MochiKit.Logging.__repr__ = function () { 35 return "[" + this.NAME + " " + this.VERSION + "]"; 36 }; 37 38 MochiKit.Logging.toString = function () { 39 return this.__repr__(); 40 }; 41 42 43 MochiKit.Logging.EXPORT = [ 44 "LogLevel", 45 "LogMessage", 46 "Logger", 47 "alertListener", 48 "logger", 49 "log", 50 "logError", 51 "logDebug", 52 "logFatal", 53 "logWarning" 54 ]; 55 56 57 MochiKit.Logging.EXPORT_OK = [ 58 "logLevelAtLeast", 59 "isLogMessage", 60 "compareLogMessage" 61 ]; 62 63 64 /** @id MochiKit.Logging.LogMessage */ 65 MochiKit.Logging.LogMessage = function (num, level, info) { 66 this.num = num; 67 this.level = level; 68 this.info = info; 69 this.timestamp = new Date(); 70 }; 71 72 MochiKit.Logging.LogMessage.prototype = { 73 /** @id MochiKit.Logging.LogMessage.prototype.repr */ 74 repr: function () { 75 var m = MochiKit.Base; 76 return 'LogMessage(' + 77 m.map( 78 m.repr, 79 [this.num, this.level, this.info] 80 ).join(', ') + ')'; 81 }, 82 /** @id MochiKit.Logging.LogMessage.prototype.toString */ 83 toString: MochiKit.Base.forwardCall("repr") 84 }; 85 86 MochiKit.Base.update(MochiKit.Logging, { 87 /** @id MochiKit.Logging.logLevelAtLeast */ 88 logLevelAtLeast: function (minLevel) { 89 var self = MochiKit.Logging; 90 if (typeof(minLevel) == 'string') { 91 minLevel = self.LogLevel[minLevel]; 92 } 93 return function (msg) { 94 var msgLevel = msg.level; 95 if (typeof(msgLevel) == 'string') { 96 msgLevel = self.LogLevel[msgLevel]; 97 } 98 return msgLevel >= minLevel; 99 }; 100 }, 101 102 /** @id MochiKit.Logging.isLogMessage */ 103 isLogMessage: function (/* ... */) { 104 var LogMessage = MochiKit.Logging.LogMessage; 105 for (var i = 0; i < arguments.length; i++) { 106 if (!(arguments[i] instanceof LogMessage)) { 107 return false; 108 } 109 } 110 return true; 111 }, 112 113 /** @id MochiKit.Logging.compareLogMessage */ 114 compareLogMessage: function (a, b) { 115 return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]); 116 }, 117 118 /** @id MochiKit.Logging.alertListener */ 119 alertListener: function (msg) { 120 alert( 121 "num: " + msg.num + 122 "\nlevel: " + msg.level + 123 "\ninfo: " + msg.info.join(" ") 124 ); 125 } 126 127 }); 128 129 /** @id MochiKit.Logging.Logger */ 130 MochiKit.Logging.Logger = function (/* optional */maxSize) { 131 this.counter = 0; 132 if (typeof(maxSize) == 'undefined' || maxSize === null) { 133 maxSize = -1; 134 } 135 this.maxSize = maxSize; 136 this._messages = []; 137 this.listeners = {}; 138 this.useNativeConsole = false; 139 }; 140 141 MochiKit.Logging.Logger.prototype = { 142 /** @id MochiKit.Logging.Logger.prototype.clear */ 143 clear: function () { 144 this._messages.splice(0, this._messages.length); 145 }, 146 147 /** @id MochiKit.Logging.Logger.prototype.logToConsole */ 148 logToConsole: function (msg) { 149 if (typeof(window) != "undefined" && window.console 150 && window.console.log) { 151 // Safari and FireBug 0.4 152 // Percent replacement is a workaround for cute Safari crashing bug 153 window.console.log(msg.replace(/%/g, '\uFF05')); 154 } else if (typeof(opera) != "undefined" && opera.postError) { 155 // Opera 156 opera.postError(msg); 157 } else if (typeof(printfire) == "function") { 158 // FireBug 0.3 and earlier 159 printfire(msg); 160 } else if (typeof(Debug) != "undefined" && Debug.writeln) { 161 // IE Web Development Helper (?) 162 // http://www.nikhilk.net/Entry.aspx?id=93 163 Debug.writeln(msg); 164 } else if (typeof(debug) != "undefined" && debug.trace) { 165 // Atlas framework (?) 166 // http://www.nikhilk.net/Entry.aspx?id=93 167 debug.trace(msg); 168 } 169 }, 170 171 /** @id MochiKit.Logging.Logger.prototype.dispatchListeners */ 172 dispatchListeners: function (msg) { 173 for (var k in this.listeners) { 174 var pair = this.listeners[k]; 175 if (pair.ident != k || (pair[0] && !pair[0](msg))) { 176 continue; 177 } 178 pair[1](msg); 179 } 180 }, 181 182 /** @id MochiKit.Logging.Logger.prototype.addListener */ 183 addListener: function (ident, filter, listener) { 184 if (typeof(filter) == 'string') { 185 filter = MochiKit.Logging.logLevelAtLeast(filter); 186 } 187 var entry = [filter, listener]; 188 entry.ident = ident; 189 this.listeners[ident] = entry; 190 }, 191 192 /** @id MochiKit.Logging.Logger.prototype.removeListener */ 193 removeListener: function (ident) { 194 delete this.listeners[ident]; 195 }, 196 197 /** @id MochiKit.Logging.Logger.prototype.baseLog */ 198 baseLog: function (level, message/*, ...*/) { 199 var msg = new MochiKit.Logging.LogMessage( 200 this.counter, 201 level, 202 MochiKit.Base.extend(null, arguments, 1) 203 ); 204 this._messages.push(msg); 205 this.dispatchListeners(msg); 206 if (this.useNativeConsole) { 207 this.logToConsole(msg.level + ": " + msg.info.join(" ")); 208 } 209 this.counter += 1; 210 while (this.maxSize >= 0 && this._messages.length > this.maxSize) { 211 this._messages.shift(); 212 } 213 }, 214 215 /** @id MochiKit.Logging.Logger.prototype.getMessages */ 216 getMessages: function (howMany) { 217 var firstMsg = 0; 218 if (!(typeof(howMany) == 'undefined' || howMany === null)) { 219 firstMsg = Math.max(0, this._messages.length - howMany); 220 } 221 return this._messages.slice(firstMsg); 222 }, 223 224 /** @id MochiKit.Logging.Logger.prototype.getMessageText */ 225 getMessageText: function (howMany) { 226 if (typeof(howMany) == 'undefined' || howMany === null) { 227 howMany = 30; 228 } 229 var messages = this.getMessages(howMany); 230 if (messages.length) { 231 var lst = map(function (m) { 232 return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' '); 233 }, messages); 234 lst.unshift('LAST ' + messages.length + ' MESSAGES:'); 235 return lst.join(''); 236 } 237 return ''; 238 }, 239 240 /** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */ 241 debuggingBookmarklet: function (inline) { 242 if (typeof(MochiKit.LoggingPane) == "undefined") { 243 alert(this.getMessageText()); 244 } else { 245 MochiKit.LoggingPane.createLoggingPane(inline || false); 246 } 247 } 248 }; 249 250 MochiKit.Logging.__new__ = function () { 251 this.LogLevel = { 252 ERROR: 40, 253 FATAL: 50, 254 WARNING: 30, 255 INFO: 20, 256 DEBUG: 10 257 }; 258 259 var m = MochiKit.Base; 260 m.registerComparator("LogMessage", 261 this.isLogMessage, 262 this.compareLogMessage 263 ); 264 265 var partial = m.partial; 266 267 var Logger = this.Logger; 268 var baseLog = Logger.prototype.baseLog; 269 m.update(this.Logger.prototype, { 270 debug: partial(baseLog, 'DEBUG'), 271 log: partial(baseLog, 'INFO'), 272 error: partial(baseLog, 'ERROR'), 273 fatal: partial(baseLog, 'FATAL'), 274 warning: partial(baseLog, 'WARNING') 275 }); 276 277 // indirectly find logger so it can be replaced 278 var self = this; 279 var connectLog = function (name) { 280 return function () { 281 self.logger[name].apply(self.logger, arguments); 282 }; 283 }; 284 285 /** @id MochiKit.Logging.log */ 286 this.log = connectLog('log'); 287 /** @id MochiKit.Logging.logError */ 288 this.logError = connectLog('error'); 289 /** @id MochiKit.Logging.logDebug */ 290 this.logDebug = connectLog('debug'); 291 /** @id MochiKit.Logging.logFatal */ 292 this.logFatal = connectLog('fatal'); 293 /** @id MochiKit.Logging.logWarning */ 294 this.logWarning = connectLog('warning'); 295 this.logger = new Logger(); 296 this.logger.useNativeConsole = true; 297 298 this.EXPORT_TAGS = { 299 ":common": this.EXPORT, 300 ":all": m.concat(this.EXPORT, this.EXPORT_OK) 301 }; 302 303 m.nameFunctions(this); 304 305 }; 306 307 if (typeof(printfire) == "undefined" && 308 typeof(document) != "undefined" && document.createEvent && 309 typeof(dispatchEvent) != "undefined") { 310 // FireBug really should be less stupid about this global function 311 printfire = function () { 312 printfire.args = arguments; 313 var ev = document.createEvent("Events"); 314 ev.initEvent("printfire", false, true); 315 dispatchEvent(ev); 316 }; 317 } 318 319 MochiKit.Logging.__new__(); 320 321 MochiKit.Base._exportSymbols(this, MochiKit.Logging);