DevTools: Add timestamp support in the console

Add a setting which when enabled will append a time stamp to each
message in the console.

BUG=131714

Review URL: https://codereview.chromium.org/185713007

git-svn-id: svn://svn.chromium.org/blink/trunk@170055 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent ff5885c6
Tests the console timestamp setting.
Console messages with timestamps disabled:
3<Before>
Console messages with timestamps enabled:
32014-05-13 16:53:20.456<Before>
2014-05-13 16:53:20.123<After>
2014-05-13 16:53:20.123<After>
2014-05-13 16:53:20.456<After>
<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/console-test.js"></script>
<script>
function test()
{
var tzOffset = new Date(Date.now()).getTimezoneOffset() * 60 * 1000;
var baseTimestamp = 1400000000000 + tzOffset;
function addMessageWithFixedTimestamp(messageText, timestamp)
{
var message = new WebInspector.ConsoleMessage(
WebInspector.ConsoleMessage.MessageSource.Other, // source
WebInspector.ConsoleMessage.MessageLevel.Log, // level
messageText,
undefined, // type
undefined, // url
undefined, // line
undefined, // column
undefined, // requestId
undefined, // parameters
undefined, // stackTrace
timestamp || baseTimestamp + 123, // timestamp: 2014-05-13T16:53:20.123Z
false); // isOutdated
WebInspector.console.addMessage(message, true); // allowGrouping
}
InspectorTest.addResult("Console messages with timestamps disabled:");
addMessageWithFixedTimestamp("<Before>");
addMessageWithFixedTimestamp("<Before>");
addMessageWithFixedTimestamp("<Before>", baseTimestamp + 456);
InspectorTest.dumpConsoleMessages();
InspectorTest.addResult("Console messages with timestamps enabled:");
WebInspector.settings.consoleTimestampsEnabled.set(true);
addMessageWithFixedTimestamp("<After>");
addMessageWithFixedTimestamp("<After>");
addMessageWithFixedTimestamp("<After>", baseTimestamp + 456);
InspectorTest.dumpConsoleMessages();
InspectorTest.completeTest();
}
</script>
</head>
<body onload="runTest()">
<p>
Tests the console timestamp setting.
</p>
</body>
</html>
...@@ -205,9 +205,11 @@ WebInspector.ConsoleModel.prototype = { ...@@ -205,9 +205,11 @@ WebInspector.ConsoleModel.prototype = {
* @param {!NetworkAgent.RequestId=} requestId * @param {!NetworkAgent.RequestId=} requestId
* @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
* @param {!Array.<!ConsoleAgent.CallFrame>=} stackTrace * @param {!Array.<!ConsoleAgent.CallFrame>=} stackTrace
* @param {number=} timestamp
* @param {boolean=} isOutdated * @param {boolean=} isOutdated
*/ */
WebInspector.ConsoleMessage = function(source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, isOutdated)
WebInspector.ConsoleMessage = function(source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, isOutdated)
{ {
this.source = source; this.source = source;
this.level = level; this.level = level;
...@@ -218,7 +220,9 @@ WebInspector.ConsoleMessage = function(source, level, messageText, type, url, li ...@@ -218,7 +220,9 @@ WebInspector.ConsoleMessage = function(source, level, messageText, type, url, li
this.column = column || 0; this.column = column || 0;
this.parameters = parameters; this.parameters = parameters;
this.stackTrace = stackTrace; this.stackTrace = stackTrace;
this.timestamp = timestamp || Date.now();
this.isOutdated = isOutdated; this.isOutdated = isOutdated;
this.request = requestId ? WebInspector.networkLog.requestForId(requestId) : null; this.request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
} }
...@@ -258,6 +262,7 @@ WebInspector.ConsoleMessage.prototype = { ...@@ -258,6 +262,7 @@ WebInspector.ConsoleMessage.prototype = {
this.request ? this.request.requestId : undefined, this.request ? this.request.requestId : undefined,
this.parameters, this.parameters,
this.stackTrace, this.stackTrace,
this.timestamp,
this.isOutdated); this.isOutdated);
}, },
...@@ -267,21 +272,18 @@ WebInspector.ConsoleMessage.prototype = { ...@@ -267,21 +272,18 @@ WebInspector.ConsoleMessage.prototype = {
*/ */
isEqual: function(msg) isEqual: function(msg)
{ {
if (!msg) if (!msg || WebInspector.settings.consoleTimestampsEnabled.get())
return false; return false;
if (this.stackTrace) { if (this.stackTrace) {
if (!msg.stackTrace) if (!msg.stackTrace || this.stackTrace.length !== msg.stackTrace.length)
return false; return false;
var l = this.stackTrace;
var r = msg.stackTrace; for (var i = 0; i < msg.stackTrace.length; ++i) {
if (l.length !== r.length) if (this.stackTrace[i].url !== msg.stackTrace[i].url ||
return false; this.stackTrace[i].functionName !== msg.stackTrace[i].functionName ||
for (var i = 0; i < l.length; i++) { this.stackTrace[i].lineNumber !== msg.stackTrace[i].lineNumber ||
if (l[i].url !== r[i].url || this.stackTrace[i].columnNumber !== msg.stackTrace[i].columnNumber)
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
l[i].columnNumber !== r[i].columnNumber)
return false; return false;
} }
} }
...@@ -383,6 +385,7 @@ WebInspector.ConsoleDispatcher.prototype = { ...@@ -383,6 +385,7 @@ WebInspector.ConsoleDispatcher.prototype = {
payload.networkRequestId, payload.networkRequestId,
payload.parameters, payload.parameters,
payload.stackTrace, payload.stackTrace,
payload.timestamp * 1000, // Convert to ms.
this._console._enablingConsole); this._console._enablingConsole);
this._console.addMessage(consoleMessage, true); this._console.addMessage(consoleMessage, true);
}, },
......
...@@ -103,7 +103,6 @@ WebInspector.ConsoleView = function(hideContextSelector) ...@@ -103,7 +103,6 @@ WebInspector.ConsoleView = function(hideContextSelector)
this._messageToViewMessage = new Map(); this._messageToViewMessage = new Map();
/** @type {!Array.<!WebInspector.ConsoleMessage>} */ /** @type {!Array.<!WebInspector.ConsoleMessage>} */
this._consoleMessages = []; this._consoleMessages = [];
this._previousMessage = null;
this.prompt = new WebInspector.TextPromptWithHistory(this._completionsForTextPrompt.bind(this)); this.prompt = new WebInspector.TextPromptWithHistory(this._completionsForTextPrompt.bind(this));
this.prompt.setSuggestBoxEnabled("generic-suggest"); this.prompt.setSuggestBoxEnabled("generic-suggest");
...@@ -421,13 +420,14 @@ WebInspector.ConsoleView.prototype = { ...@@ -421,13 +420,14 @@ WebInspector.ConsoleView.prototype = {
else else
this._urlToMessageCount[message.url] = 1; this._urlToMessageCount[message.url] = 1;
if (this._previousMessage && !message.isGroupMessage() && message.isEqual(this._previousMessage)) { var previousMessage = this._consoleMessages.peekLast();
this._messageToViewMessage.get(this._previousMessage).incrementRepeatCount(); if (previousMessage && !message.isGroupMessage() && message.isEqual(previousMessage)) {
previousMessage.timestamp = message.timestamp;
this._messageToViewMessage.get(previousMessage).incrementRepeatCount();
return; return;
} }
this._consoleMessages.push(message); this._consoleMessages.push(message);
this._previousMessage = message;
var viewMessage = this._createViewMessage(target, message); var viewMessage = this._createViewMessage(target, message);
if (this._filter.shouldBeVisible(viewMessage)) if (this._filter.shouldBeVisible(viewMessage))
...@@ -507,7 +507,6 @@ WebInspector.ConsoleView.prototype = { ...@@ -507,7 +507,6 @@ WebInspector.ConsoleView.prototype = {
this._visibleViewMessages = []; this._visibleViewMessages = [];
this._searchResults = []; this._searchResults = [];
this._previousMessage = null;
this._messageToViewMessage.clear(); this._messageToViewMessage.clear();
this._consoleMessages = []; this._consoleMessages = [];
......
...@@ -52,6 +52,8 @@ WebInspector.ConsoleViewMessage = function(target, consoleMessage, linkifier) ...@@ -52,6 +52,8 @@ WebInspector.ConsoleViewMessage = function(target, consoleMessage, linkifier)
"node": this._formatParameterAsNode, "node": this._formatParameterAsNode,
"string": this._formatParameterAsString "string": this._formatParameterAsString
}; };
WebInspector.settings.consoleTimestampsEnabled.addChangeListener(this._consoleTimestampsSettingChanged, this);
} }
WebInspector.ConsoleViewMessage.prototype = { WebInspector.ConsoleViewMessage.prototype = {
...@@ -845,6 +847,29 @@ WebInspector.ConsoleViewMessage.prototype = { ...@@ -845,6 +847,29 @@ WebInspector.ConsoleViewMessage.prototype = {
return regexObject.test(this._formattedMessageText()) || (!!this._anchorElement && regexObject.test(this._anchorElement.textContent)); return regexObject.test(this._formattedMessageText()) || (!!this._anchorElement && regexObject.test(this._anchorElement.textContent));
}, },
_updateTimestamp: function(show)
{
if (!this._element)
return;
if (show && !this.timestampElement) {
this.timestampElement = this._element.createChild("span", "console-timestamp");
this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime();
var afterRepeatCountChild = this.repeatCountElement && this.repeatCountElement.nextSibling;
this._element.insertBefore(this.timestampElement, afterRepeatCountChild || this._element.firstChild);
return;
}
if (!show && this.timestampElement)
this.timestampElement.remove();
},
_consoleTimestampsSettingChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
this._updateTimestamp(enabled);
},
/** /**
* @return {!Element} * @return {!Element}
*/ */
...@@ -885,6 +910,8 @@ WebInspector.ConsoleViewMessage.prototype = { ...@@ -885,6 +910,8 @@ WebInspector.ConsoleViewMessage.prototype = {
if (this._repeatCount > 1) if (this._repeatCount > 1)
this._showRepeatCountElement(); this._showRepeatCountElement();
this._updateTimestamp(WebInspector.settings.consoleTimestampsEnabled.get());
return element; return element;
}, },
......
...@@ -56,6 +56,7 @@ WebInspector.Settings = function() ...@@ -56,6 +56,7 @@ WebInspector.Settings = function()
this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application"); this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false); this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false); this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
this.consoleTimestampsEnabled = this.createSetting("consoleTimestampsEnabled", false);
this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true); this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"}); this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.resourceViewTab = this.createSetting("resourceViewTab", "preview"); this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
......
...@@ -341,6 +341,7 @@ WebInspector.GenericSettingsTab = function() ...@@ -341,6 +341,7 @@ WebInspector.GenericSettingsTab = function()
p = this._appendSection(WebInspector.UIString("Console")); p = this._appendSection(WebInspector.UIString("Console"));
p.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Log XMLHttpRequests"), WebInspector.settings.monitoringXHREnabled)); p.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Log XMLHttpRequests"), WebInspector.settings.monitoringXHREnabled));
p.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Preserve log upon navigation"), WebInspector.settings.preserveConsoleLog)); p.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Preserve log upon navigation"), WebInspector.settings.preserveConsoleLog));
p.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show timestamps"), WebInspector.settings.consoleTimestampsEnabled));
if (WebInspector.openAnchorLocationRegistry.handlerNames.length > 0) { if (WebInspector.openAnchorLocationRegistry.handlerNames.length > 0) {
var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry); var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
......
...@@ -870,6 +870,12 @@ body.platform-linux .source-code { ...@@ -870,6 +870,12 @@ body.platform-linux .source-code {
background-image: none; background-image: none;
} }
.console-timestamp {
color: gray;
margin-right: 10px;
-webkit-user-select: none;
}
.console-message::before, .console-message::before,
.console-user-command::before, .console-user-command::before,
#console-prompt::before, #console-prompt::before,
......
...@@ -370,6 +370,38 @@ Date.prototype.toISO8601Compact = function() ...@@ -370,6 +370,38 @@ Date.prototype.toISO8601Compact = function()
leadZero(this.getSeconds()); leadZero(this.getSeconds());
} }
/**
* @return {string}
*/
Date.prototype.toConsoleTime = function()
{
/**
* @param {number} x
* @return {string}
*/
function leadZero2(x)
{
return (x > 9 ? "" : "0") + x;
}
/**
* @param {number} x
* @return {string}
*/
function leadZero3(x)
{
return (Array(4 - x.toString().length)).join('0') + x;
}
return this.getFullYear() + "-" +
leadZero2(this.getMonth() + 1) + "-" +
leadZero2(this.getDate()) + " " +
leadZero2(this.getHours()) + ":" +
leadZero2(this.getMinutes()) + ":" +
leadZero2(this.getSeconds()) + "." +
leadZero3(this.getMilliseconds());
}
Object.defineProperty(Array.prototype, "remove", Object.defineProperty(Array.prototype, "remove",
{ {
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment