michael@0: /*** michael@0: michael@0: MochiKit.Logging 1.4.2 michael@0: michael@0: See for documentation, downloads, license, etc. michael@0: michael@0: (c) 2005 Bob Ippolito. All rights Reserved. michael@0: michael@0: ***/ michael@0: michael@0: MochiKit.Base._deps('Logging', ['Base']); michael@0: michael@0: MochiKit.Logging.NAME = "MochiKit.Logging"; michael@0: MochiKit.Logging.VERSION = "1.4.2"; michael@0: MochiKit.Logging.__repr__ = function () { michael@0: return "[" + this.NAME + " " + this.VERSION + "]"; michael@0: }; michael@0: michael@0: MochiKit.Logging.toString = function () { michael@0: return this.__repr__(); michael@0: }; michael@0: michael@0: michael@0: MochiKit.Logging.EXPORT = [ michael@0: "LogLevel", michael@0: "LogMessage", michael@0: "Logger", michael@0: "alertListener", michael@0: "logger", michael@0: "log", michael@0: "logError", michael@0: "logDebug", michael@0: "logFatal", michael@0: "logWarning" michael@0: ]; michael@0: michael@0: michael@0: MochiKit.Logging.EXPORT_OK = [ michael@0: "logLevelAtLeast", michael@0: "isLogMessage", michael@0: "compareLogMessage" michael@0: ]; michael@0: michael@0: michael@0: /** @id MochiKit.Logging.LogMessage */ michael@0: MochiKit.Logging.LogMessage = function (num, level, info) { michael@0: this.num = num; michael@0: this.level = level; michael@0: this.info = info; michael@0: this.timestamp = new Date(); michael@0: }; michael@0: michael@0: MochiKit.Logging.LogMessage.prototype = { michael@0: /** @id MochiKit.Logging.LogMessage.prototype.repr */ michael@0: repr: function () { michael@0: var m = MochiKit.Base; michael@0: return 'LogMessage(' + michael@0: m.map( michael@0: m.repr, michael@0: [this.num, this.level, this.info] michael@0: ).join(', ') + ')'; michael@0: }, michael@0: /** @id MochiKit.Logging.LogMessage.prototype.toString */ michael@0: toString: MochiKit.Base.forwardCall("repr") michael@0: }; michael@0: michael@0: MochiKit.Base.update(MochiKit.Logging, { michael@0: /** @id MochiKit.Logging.logLevelAtLeast */ michael@0: logLevelAtLeast: function (minLevel) { michael@0: var self = MochiKit.Logging; michael@0: if (typeof(minLevel) == 'string') { michael@0: minLevel = self.LogLevel[minLevel]; michael@0: } michael@0: return function (msg) { michael@0: var msgLevel = msg.level; michael@0: if (typeof(msgLevel) == 'string') { michael@0: msgLevel = self.LogLevel[msgLevel]; michael@0: } michael@0: return msgLevel >= minLevel; michael@0: }; michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.isLogMessage */ michael@0: isLogMessage: function (/* ... */) { michael@0: var LogMessage = MochiKit.Logging.LogMessage; michael@0: for (var i = 0; i < arguments.length; i++) { michael@0: if (!(arguments[i] instanceof LogMessage)) { michael@0: return false; michael@0: } michael@0: } michael@0: return true; michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.compareLogMessage */ michael@0: compareLogMessage: function (a, b) { michael@0: return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]); michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.alertListener */ michael@0: alertListener: function (msg) { michael@0: alert( michael@0: "num: " + msg.num + michael@0: "\nlevel: " + msg.level + michael@0: "\ninfo: " + msg.info.join(" ") michael@0: ); michael@0: } michael@0: michael@0: }); michael@0: michael@0: /** @id MochiKit.Logging.Logger */ michael@0: MochiKit.Logging.Logger = function (/* optional */maxSize) { michael@0: this.counter = 0; michael@0: if (typeof(maxSize) == 'undefined' || maxSize === null) { michael@0: maxSize = -1; michael@0: } michael@0: this.maxSize = maxSize; michael@0: this._messages = []; michael@0: this.listeners = {}; michael@0: this.useNativeConsole = false; michael@0: }; michael@0: michael@0: MochiKit.Logging.Logger.prototype = { michael@0: /** @id MochiKit.Logging.Logger.prototype.clear */ michael@0: clear: function () { michael@0: this._messages.splice(0, this._messages.length); michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.logToConsole */ michael@0: logToConsole: function (msg) { michael@0: if (typeof(window) != "undefined" && window.console michael@0: && window.console.log) { michael@0: // Safari and FireBug 0.4 michael@0: // Percent replacement is a workaround for cute Safari crashing bug michael@0: window.console.log(msg.replace(/%/g, '\uFF05')); michael@0: } else if (typeof(opera) != "undefined" && opera.postError) { michael@0: // Opera michael@0: opera.postError(msg); michael@0: } else if (typeof(printfire) == "function") { michael@0: // FireBug 0.3 and earlier michael@0: printfire(msg); michael@0: } else if (typeof(Debug) != "undefined" && Debug.writeln) { michael@0: // IE Web Development Helper (?) michael@0: // http://www.nikhilk.net/Entry.aspx?id=93 michael@0: Debug.writeln(msg); michael@0: } else if (typeof(debug) != "undefined" && debug.trace) { michael@0: // Atlas framework (?) michael@0: // http://www.nikhilk.net/Entry.aspx?id=93 michael@0: debug.trace(msg); michael@0: } michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.dispatchListeners */ michael@0: dispatchListeners: function (msg) { michael@0: for (var k in this.listeners) { michael@0: var pair = this.listeners[k]; michael@0: if (pair.ident != k || (pair[0] && !pair[0](msg))) { michael@0: continue; michael@0: } michael@0: pair[1](msg); michael@0: } michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.addListener */ michael@0: addListener: function (ident, filter, listener) { michael@0: if (typeof(filter) == 'string') { michael@0: filter = MochiKit.Logging.logLevelAtLeast(filter); michael@0: } michael@0: var entry = [filter, listener]; michael@0: entry.ident = ident; michael@0: this.listeners[ident] = entry; michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.removeListener */ michael@0: removeListener: function (ident) { michael@0: delete this.listeners[ident]; michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.baseLog */ michael@0: baseLog: function (level, message/*, ...*/) { michael@0: if (typeof(level) == "number") { michael@0: if (level >= MochiKit.Logging.LogLevel.FATAL) { michael@0: level = 'FATAL'; michael@0: } else if (level >= MochiKit.Logging.LogLevel.ERROR) { michael@0: level = 'ERROR'; michael@0: } else if (level >= MochiKit.Logging.LogLevel.WARNING) { michael@0: level = 'WARNING'; michael@0: } else if (level >= MochiKit.Logging.LogLevel.INFO) { michael@0: level = 'INFO'; michael@0: } else { michael@0: level = 'DEBUG'; michael@0: } michael@0: } michael@0: var msg = new MochiKit.Logging.LogMessage( michael@0: this.counter, michael@0: level, michael@0: MochiKit.Base.extend(null, arguments, 1) michael@0: ); michael@0: this._messages.push(msg); michael@0: this.dispatchListeners(msg); michael@0: if (this.useNativeConsole) { michael@0: this.logToConsole(msg.level + ": " + msg.info.join(" ")); michael@0: } michael@0: this.counter += 1; michael@0: while (this.maxSize >= 0 && this._messages.length > this.maxSize) { michael@0: this._messages.shift(); michael@0: } michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.getMessages */ michael@0: getMessages: function (howMany) { michael@0: var firstMsg = 0; michael@0: if (!(typeof(howMany) == 'undefined' || howMany === null)) { michael@0: firstMsg = Math.max(0, this._messages.length - howMany); michael@0: } michael@0: return this._messages.slice(firstMsg); michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.getMessageText */ michael@0: getMessageText: function (howMany) { michael@0: if (typeof(howMany) == 'undefined' || howMany === null) { michael@0: howMany = 30; michael@0: } michael@0: var messages = this.getMessages(howMany); michael@0: if (messages.length) { michael@0: var lst = map(function (m) { michael@0: return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' '); michael@0: }, messages); michael@0: lst.unshift('LAST ' + messages.length + ' MESSAGES:'); michael@0: return lst.join(''); michael@0: } michael@0: return ''; michael@0: }, michael@0: michael@0: /** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */ michael@0: debuggingBookmarklet: function (inline) { michael@0: if (typeof(MochiKit.LoggingPane) == "undefined") { michael@0: alert(this.getMessageText()); michael@0: } else { michael@0: MochiKit.LoggingPane.createLoggingPane(inline || false); michael@0: } michael@0: } michael@0: }; michael@0: michael@0: MochiKit.Logging.__new__ = function () { michael@0: this.LogLevel = { michael@0: ERROR: 40, michael@0: FATAL: 50, michael@0: WARNING: 30, michael@0: INFO: 20, michael@0: DEBUG: 10 michael@0: }; michael@0: michael@0: var m = MochiKit.Base; michael@0: m.registerComparator("LogMessage", michael@0: this.isLogMessage, michael@0: this.compareLogMessage michael@0: ); michael@0: michael@0: var partial = m.partial; michael@0: michael@0: var Logger = this.Logger; michael@0: var baseLog = Logger.prototype.baseLog; michael@0: m.update(this.Logger.prototype, { michael@0: debug: partial(baseLog, 'DEBUG'), michael@0: log: partial(baseLog, 'INFO'), michael@0: error: partial(baseLog, 'ERROR'), michael@0: fatal: partial(baseLog, 'FATAL'), michael@0: warning: partial(baseLog, 'WARNING') michael@0: }); michael@0: michael@0: // indirectly find logger so it can be replaced michael@0: var self = this; michael@0: var connectLog = function (name) { michael@0: return function () { michael@0: self.logger[name].apply(self.logger, arguments); michael@0: }; michael@0: }; michael@0: michael@0: /** @id MochiKit.Logging.log */ michael@0: this.log = connectLog('log'); michael@0: /** @id MochiKit.Logging.logError */ michael@0: this.logError = connectLog('error'); michael@0: /** @id MochiKit.Logging.logDebug */ michael@0: this.logDebug = connectLog('debug'); michael@0: /** @id MochiKit.Logging.logFatal */ michael@0: this.logFatal = connectLog('fatal'); michael@0: /** @id MochiKit.Logging.logWarning */ michael@0: this.logWarning = connectLog('warning'); michael@0: this.logger = new Logger(); michael@0: this.logger.useNativeConsole = true; michael@0: michael@0: this.EXPORT_TAGS = { michael@0: ":common": this.EXPORT, michael@0: ":all": m.concat(this.EXPORT, this.EXPORT_OK) michael@0: }; michael@0: michael@0: m.nameFunctions(this); michael@0: michael@0: }; michael@0: michael@0: if (typeof(printfire) == "undefined" && michael@0: typeof(document) != "undefined" && document.createEvent && michael@0: typeof(dispatchEvent) != "undefined") { michael@0: // FireBug really should be less lame about this global function michael@0: printfire = function () { michael@0: printfire.args = arguments; michael@0: var ev = document.createEvent("Events"); michael@0: ev.initEvent("printfire", false, true); michael@0: dispatchEvent(ev); michael@0: }; michael@0: } michael@0: michael@0: MochiKit.Logging.__new__(); michael@0: michael@0: MochiKit.Base._exportSymbols(this, MochiKit.Logging);