NOTE: This code was refactored a bit and exists in MochiKit 1.0+ as MochiKit.LoggingPane?!
Here's code to create an inline or popup-window log viewer for the default logger. Current dependencies are MochiKit.Base and MochiKit.Logging.
Allows regex-based filtering of the message level and info, and can view all logged messages or only new ones as they come.
function createDebugPane(inline) { /* Use a div if inline, pop up a window if not */ if(logger) { /* Create the elements */ var doc = document; if(!inline) { var win = window.open("", "", "dependent,resizable,height=200"); doc = win.document; } var debugPane = doc.createElement("div"); var levelFilterField = doc.createElement("input"); var infoFilterField = doc.createElement("input"); var filterButton = doc.createElement("button"); var loadButton = doc.createElement("button"); var clearButton = doc.createElement("button"); var closeButton = doc.createElement("button"); var logPane = doc.createElement("div"); /* Set up the functions */ var listenerId = "_debugPaneListener"; var colorTable = {"ERROR": "orange","FATAL": "red","WARNING": "blue","INFO": "green","DEBUG": "silver"}; var messages = []; var messageFilter = null; var messageLevel = function(msg) { var level = msg.level; if(typeof(level) == "number") level = LogLevel[level]; return level; }; var messageText = function(msg) { var text = ""; for(var i = 0; i < msg.info.length; i++) text += msg.info[i]; return text; }; var addMessageText = function(msg) { var level = messageLevel(msg); var text = messageText(msg); var c = colorTable[level]; var p = doc.createElement("p"); p.style.color = c; p.style.margin = "0"; p.appendChild(doc.createTextNode(level + ": " + text)); logPane.appendChild(p); p.scrollIntoView(); }; var addMessage = function(msg) { messages[messages.length] = msg; addMessageText(msg); }; var buildMessageFilter = function() { var levelre, infore; try { /* Catch any exceptions that might arise due to invalid regexes */ var levelre = new RegExp(levelFilterField.value); var infore = new RegExp(infoFilterField.value); } catch(e) { /* If there was an error with the regexes, do no filtering */ logDebug("Error in filter regex: " + e.message); return null; } return function(msg) { return (levelre.test(messageLevel(msg)) && infore.test(messageText(msg))); }; } var clearMessagePane = function() { while(logPane.firstChild) logPane.removeChild(logPane.firstChild); }; var clearMessages = function() { messages = []; clearMessagePane(); } var closePane = function() { logger.removeListener(listenerId); if(inline) debugPane.parentNode.removeChild(debugPane); else win.close(); }; var filterMessages = function() { clearMessagePane(); for(var i = 0; i < messages.length; i++) { var msg = messages[i]; if(messageFilter == null || messageFilter(msg)) addMessageText(msg); } }; var buildAndApplyFilter = function() { messageFilter = buildMessageFilter(); filterMessages(); logger.removeListener(listenerId); logger.addListener(listenerId, messageFilter, addMessage); }; var loadMessages = function() { messages = logger.getMessages(); filterMessages(); }; var filterOnEnter = function(event) { event = event || window.event; key = event.which || event.keyCode; if(key == 13) buildAndApplyFilter(); }; /* Create the debug pane */ debugPane.style.display = "block"; debugPane.style.position = "fixed"; debugPane.style.left = "0px"; debugPane.style.bottom = "0px"; debugPane.style.font = "8pt Verdana,sans-serif"; debugPane.style.width = "100%"; if(inline) { debugPane.style.height = "10em"; debugPane.style.borderTop = "2px solid black"; } else { debugPane.style.height = "100%"; } debugPane.style.backgroundColor = "white"; doc.body.appendChild(debugPane); /* Create the filter fields */ levelFilterField.value = "FATAL|ERROR|WARNING|INFO|DEBUG"; levelFilterField.style.width = "33%"; levelFilterField.style.display = "inline"; levelFilterField.style.font = "8pt Verdana,sans-serif"; levelFilterField.onkeypress = filterOnEnter; debugPane.appendChild(levelFilterField); infoFilterField.value = ".*"; infoFilterField.style.width = "33%"; infoFilterField.style.display = "inline"; infoFilterField.style.font = "8pt Verdana,sans-serif"; infoFilterField.onkeypress = filterOnEnter; debugPane.appendChild(infoFilterField); /* Create the buttons */ filterButton.appendChild(doc.createTextNode("Filter")); filterButton.style.width = "8%"; filterButton.style.display = "inline"; filterButton.onclick = buildAndApplyFilter; filterButton.style.font = "8pt Verdana,sans-serif"; debugPane.appendChild(filterButton); loadButton.appendChild(doc.createTextNode("Load")); loadButton.style.width = "8%"; loadButton.style.display = "inline"; loadButton.onclick = loadMessages; loadButton.style.font = "8pt Verdana,sans-serif"; debugPane.appendChild(loadButton); clearButton.appendChild(doc.createTextNode("Clear")); clearButton.style.width = "8%"; clearButton.style.display = "inline"; clearButton.onclick = clearMessages; clearButton.style.font = "8pt Verdana,sans-serif"; debugPane.appendChild(clearButton); closeButton.appendChild(doc.createTextNode("Close")); closeButton.style.width = "8%"; closeButton.style.display = "inline"; closeButton.onclick = closePane; closeButton.style.font = "8pt Verdana,sans-serif"; debugPane.appendChild(closeButton); /* Create the logging pane */ debugPane.style.display = "block"; logPane.style.whitespace = "preserve"; logPane.style.overflow = "auto"; logPane.style.width = "100%"; logPane.style.height = "8em"; debugPane.appendChild(logPane); buildAndApplyFilter(); } else { alert("logger not found!"); } }
