- Revision
- 193870
- Author
- bb...@apple.com
- Date
- 2015-12-09 14:45:21 -0800 (Wed, 09 Dec 2015)
Log Message
Web Inspector: control whether to collect and dump protocol messages using a WebInspector.Setting
https://bugs.webkit.org/show_bug.cgi?id=151635
Reviewed by Timothy Hatcher.
When closing and reopening the inspector, the setting for whether
to dump protocol messages should be persisted. Otherwise, enabling
dumping from the debug-only UI will miss the initial flood of
messages that are processed when the Inspector loads initial data.
To support a persistent setting, and build some infrastructure for
more advanced uses of collected protocol messages, this patch adds
a new object to trace protocol events. It gets callbacks for each
and implements the console-dumping functionality previously baked in
to InspectorBackend.
In follow-up patches, other protocol tracers will be added to save
protocol data to disk, marshall it to a higher inspection level,
or provide more fine-grained control over what is logged.
This change moves Setting.js into the Base/ directory,
since it is used by Views, Models, and now Protocol classes.
* UserInterface/Base/Setting.js: Renamed from Source/WebInspectorUI/UserInterface/Models/Setting.js.
(WebInspector.Setting):
(WebInspector.Setting.prototype.get name):
(WebInspector.Setting.prototype.get value):
(WebInspector.Setting.prototype.set value):
* UserInterface/Main.html:
* UserInterface/Protocol/InspectorBackend.js:
(InspectorBackendClass):
(InspectorBackendClass.prototype.set dumpInspectorProtocolMessages):
(InspectorBackendClass.prototype.get dumpInspectorProtocolMessages):
We still want to support the legacy way to enable dumping:
`InspectorBackend.dumpInspectorProtocolMessages = true`. This
is because some tests always use it, and it's easier to set this
flag in a custom Bootstrap.js file than to configure the Setting.
(InspectorBackendClass.prototype.set dumpInspectorTimeStats):
(InspectorBackendClass.prototype.get dumpInspectorTimeStats):
We still want to support the legacy way to enable dumping:
`InspectorBackend.dumpInspectorTimeStats = true`. This is
because MessageDispatcher checks this flag for its logging.
(InspectorBackendClass.prototype.set activeTracer):
(InspectorBackendClass.prototype.get activeTracer):
Set the active tracer, finalizing and removing any active tracer
if one exists. If removing a custom tracer (setting to null), then
re-sync activeTracer with the automatic tracing Setting.
(InspectorBackendClass.prototype.dispatch):
(InspectorBackendClass.prototype._startOrStopAutomaticTracing):
Sync the Setting with activeTracer. If an custom tracer is active,
don't replace it with the automatic logging tracer.
(InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
(InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
(InspectorBackendClass.prototype._sendMessageToBackend):
(InspectorBackendClass.prototype._dispatchResponse):
(InspectorBackendClass.prototype._dispatchEvent):
(InspectorBackendClass.prototype._flushPendingScripts):
* UserInterface/Protocol/LoggingProtocolTracer.js: Added.
(WebInspector.LoggingProtocolTracer):
(WebInspector.LoggingProtocolTracer.prototype.set dumpMessagesToConsole):
(WebInspector.LoggingProtocolTracer.prototype.get dumpMessagesToConsole):
(WebInspector.LoggingProtocolTracer.prototype.set dumpTimingDataToConsole):
(WebInspector.LoggingProtocolTracer.prototype.get dumpTimingDataToConsole):
(WebInspector.LoggingProtocolTracer.prototype.logFrontendException):
(WebInspector.LoggingProtocolTracer.prototype.logProtocolError):
(WebInspector.LoggingProtocolTracer.prototype.logFrontendRequest):
(WebInspector.LoggingProtocolTracer.prototype.logWillHandleResponse):
(WebInspector.LoggingProtocolTracer.prototype.logDidHandleResponse):
(WebInspector.LoggingProtocolTracer.prototype.logWillHandleEvent):
(WebInspector.LoggingProtocolTracer.prototype.logDidHandleEvent):
(WebInspector.LoggingProtocolTracer.prototype._processEntry):
* UserInterface/Protocol/ProtocolTracer.js: Added.
(WebInspector.ProtocolTracer.prototype.logStarted):
(WebInspector.ProtocolTracer.prototype.logFrontendException):
(WebInspector.ProtocolTracer.prototype.logProtocolError):
(WebInspector.ProtocolTracer.prototype.logFrontendRequest):
(WebInspector.ProtocolTracer.prototype.logWillHandleResponse):
(WebInspector.ProtocolTracer.prototype.logDidHandleResponse):
(WebInspector.ProtocolTracer.prototype.logWillHandleEvent):
(WebInspector.ProtocolTracer.prototype.logDidHandleEvent): (WebInspector.ProtocolTracer.prototype.logFinished):
(WebInspector.ProtocolTracer):
* UserInterface/Test.html:
Modified Paths
Added Paths
Removed Paths
Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (193869 => 193870)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-12-09 22:45:21 UTC (rev 193870)
@@ -1,5 +1,98 @@
2015-12-09 Brian Burg <bb...@apple.com>
+ Web Inspector: control whether to collect and dump protocol messages using a WebInspector.Setting
+ https://bugs.webkit.org/show_bug.cgi?id=151635
+
+ Reviewed by Timothy Hatcher.
+
+ When closing and reopening the inspector, the setting for whether
+ to dump protocol messages should be persisted. Otherwise, enabling
+ dumping from the debug-only UI will miss the initial flood of
+ messages that are processed when the Inspector loads initial data.
+
+ To support a persistent setting, and build some infrastructure for
+ more advanced uses of collected protocol messages, this patch adds
+ a new object to trace protocol events. It gets callbacks for each
+ and implements the console-dumping functionality previously baked in
+ to InspectorBackend.
+
+ In follow-up patches, other protocol tracers will be added to save
+ protocol data to disk, marshall it to a higher inspection level,
+ or provide more fine-grained control over what is logged.
+
+ This change moves Setting.js into the Base/ directory,
+ since it is used by Views, Models, and now Protocol classes.
+
+ * UserInterface/Base/Setting.js: Renamed from Source/WebInspectorUI/UserInterface/Models/Setting.js.
+ (WebInspector.Setting):
+ (WebInspector.Setting.prototype.get name):
+ (WebInspector.Setting.prototype.get value):
+ (WebInspector.Setting.prototype.set value):
+ * UserInterface/Main.html:
+ * UserInterface/Protocol/InspectorBackend.js:
+ (InspectorBackendClass):
+ (InspectorBackendClass.prototype.set dumpInspectorProtocolMessages):
+ (InspectorBackendClass.prototype.get dumpInspectorProtocolMessages):
+
+ We still want to support the legacy way to enable dumping:
+ `InspectorBackend.dumpInspectorProtocolMessages = true`. This
+ is because some tests always use it, and it's easier to set this
+ flag in a custom Bootstrap.js file than to configure the Setting.
+
+ (InspectorBackendClass.prototype.set dumpInspectorTimeStats):
+ (InspectorBackendClass.prototype.get dumpInspectorTimeStats):
+
+ We still want to support the legacy way to enable dumping:
+ `InspectorBackend.dumpInspectorTimeStats = true`. This is
+ because MessageDispatcher checks this flag for its logging.
+
+ (InspectorBackendClass.prototype.set activeTracer):
+ (InspectorBackendClass.prototype.get activeTracer):
+
+ Set the active tracer, finalizing and removing any active tracer
+ if one exists. If removing a custom tracer (setting to null), then
+ re-sync activeTracer with the automatic tracing Setting.
+
+ (InspectorBackendClass.prototype.dispatch):
+ (InspectorBackendClass.prototype._startOrStopAutomaticTracing):
+
+ Sync the Setting with activeTracer. If an custom tracer is active,
+ don't replace it with the automatic logging tracer.
+
+ (InspectorBackendClass.prototype._sendCommandToBackendWithCallback):
+ (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise):
+ (InspectorBackendClass.prototype._sendMessageToBackend):
+ (InspectorBackendClass.prototype._dispatchResponse):
+ (InspectorBackendClass.prototype._dispatchEvent):
+ (InspectorBackendClass.prototype._flushPendingScripts):
+ * UserInterface/Protocol/LoggingProtocolTracer.js: Added.
+ (WebInspector.LoggingProtocolTracer):
+ (WebInspector.LoggingProtocolTracer.prototype.set dumpMessagesToConsole):
+ (WebInspector.LoggingProtocolTracer.prototype.get dumpMessagesToConsole):
+ (WebInspector.LoggingProtocolTracer.prototype.set dumpTimingDataToConsole):
+ (WebInspector.LoggingProtocolTracer.prototype.get dumpTimingDataToConsole):
+ (WebInspector.LoggingProtocolTracer.prototype.logFrontendException):
+ (WebInspector.LoggingProtocolTracer.prototype.logProtocolError):
+ (WebInspector.LoggingProtocolTracer.prototype.logFrontendRequest):
+ (WebInspector.LoggingProtocolTracer.prototype.logWillHandleResponse):
+ (WebInspector.LoggingProtocolTracer.prototype.logDidHandleResponse):
+ (WebInspector.LoggingProtocolTracer.prototype.logWillHandleEvent):
+ (WebInspector.LoggingProtocolTracer.prototype.logDidHandleEvent):
+ (WebInspector.LoggingProtocolTracer.prototype._processEntry):
+ * UserInterface/Protocol/ProtocolTracer.js: Added.
+ (WebInspector.ProtocolTracer.prototype.logStarted):
+ (WebInspector.ProtocolTracer.prototype.logFrontendException):
+ (WebInspector.ProtocolTracer.prototype.logProtocolError):
+ (WebInspector.ProtocolTracer.prototype.logFrontendRequest):
+ (WebInspector.ProtocolTracer.prototype.logWillHandleResponse):
+ (WebInspector.ProtocolTracer.prototype.logDidHandleResponse):
+ (WebInspector.ProtocolTracer.prototype.logWillHandleEvent):
+ (WebInspector.ProtocolTracer.prototype.logDidHandleEvent): (WebInspector.ProtocolTracer.prototype.logFinished):
+ (WebInspector.ProtocolTracer):
+ * UserInterface/Test.html:
+
+2015-12-09 Brian Burg <bb...@apple.com>
+
Web Inspector: zoom with Ctrl +/- doesn't work correctly when inspector is docked
https://bugs.webkit.org/show_bug.cgi?id=152076
Copied: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (from rev 193867, trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js) (0 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js 2015-12-09 22:45:21 UTC (rev 193870)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Setting = class Setting extends WebInspector.Object
+{
+ constructor(name, defaultValue)
+ {
+ super();
+
+ this._name = name;
+
+ let inspectionLevel = InspectorFrontendHost ? InspectorFrontendHost.inspectionLevel() : 1;
+ let levelString = inspectionLevel > 1 ? "-" + inspectionLevel : "";
+ this._localStorageKey = `com.apple.WebInspector${levelString}.${name}`;
+ this._defaultValue = defaultValue;
+ }
+
+ // Public
+
+ get name()
+ {
+ return this._name;
+ }
+
+ get value()
+ {
+ if ("_value" in this)
+ return this._value;
+
+ // Make a copy of the default value so changes to object values don't modify the default value.
+ this._value = JSON.parse(JSON.stringify(this._defaultValue));
+
+ if (!window.InspectorTest && window.localStorage && this._localStorageKey in window.localStorage) {
+ try {
+ this._value = JSON.parse(window.localStorage[this._localStorageKey]);
+ } catch(e) {
+ delete window.localStorage[this._localStorageKey];
+ }
+ }
+
+ return this._value;
+ }
+
+ set value(value)
+ {
+ this._value = value;
+
+ if (!window.InspectorTest && window.localStorage) {
+ try {
+ // Use Object.shallowEqual to properly compare objects.
+ if (Object.shallowEqual(this._value, this._defaultValue))
+ delete window.localStorage[this._localStorageKey];
+ else
+ window.localStorage[this._localStorageKey] = JSON.stringify(this._value);
+ } catch(e) {
+ console.error("Error saving setting with name: " + this._name);
+ }
+ }
+
+ this.dispatchEventToListeners(WebInspector.Setting.Event.Changed, this._value, {name: this._name});
+ }
+};
+
+WebInspector.Setting.Event = {
+ Changed: "setting-changed"
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (193869 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2015-12-09 22:45:21 UTC (rev 193870)
@@ -224,7 +224,11 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
+ <script src=""
+
<script src=""
<script src=""
<script src=""
@@ -328,7 +332,6 @@
<script src=""
<script src=""
<script src=""
- <script src=""
<script src=""
<script src=""
<script src=""
Deleted: trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js (193869 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js 2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Setting.js 2015-12-09 22:45:21 UTC (rev 193870)
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-WebInspector.Setting = class Setting extends WebInspector.Object
-{
- constructor(name, defaultValue)
- {
- super();
-
- this._name = name;
-
- let inspectionLevel = InspectorFrontendHost.inspectionLevel();
- let levelString = inspectionLevel > 1 ? "-" + inspectionLevel : "";
- this._localStorageKey = `com.apple.WebInspector${levelString}.${name}`;
- this._defaultValue = defaultValue;
- }
-
- // Public
-
- get name()
- {
- return this._name;
- }
-
- get value()
- {
- if ("_value" in this)
- return this._value;
-
- // Make a copy of the default value so changes to object values don't modify the default value.
- this._value = JSON.parse(JSON.stringify(this._defaultValue));
-
- if (!window.InspectorTest && window.localStorage && this._localStorageKey in window.localStorage) {
- try {
- this._value = JSON.parse(window.localStorage[this._localStorageKey]);
- } catch(e) {
- delete window.localStorage[this._localStorageKey];
- }
- }
-
- return this._value;
- }
-
- set value(value)
- {
- this._value = value;
-
- if (!window.InspectorTest && window.localStorage) {
- try {
- // Use Object.shallowEqual to properly compare objects.
- if (Object.shallowEqual(this._value, this._defaultValue))
- delete window.localStorage[this._localStorageKey];
- else
- window.localStorage[this._localStorageKey] = JSON.stringify(this._value);
- } catch(e) {
- console.error("Error saving setting with name: " + this._name);
- }
- }
-
- this.dispatchEventToListeners(WebInspector.Setting.Event.Changed, this._value, {name: this._name});
- }
-};
-
-WebInspector.Setting.Event = {
- Changed: "setting-changed"
-};
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js (193869 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js 2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorBackend.js 2015-12-09 22:45:21 UTC (rev 193870)
@@ -38,17 +38,92 @@
this._pendingResponses = new Map;
this._agents = {};
this._deferredScripts = [];
+ this._activeTracer = null;
+ this._automaticTracer = null;
- this.dumpInspectorTimeStats = false;
- this.dumpInspectorProtocolMessages = false;
- this.warnForLongMessageHandling = false;
- this.longMessageHandlingThreshold = 10; // milliseconds.
+ this._dumpInspectorTimeStats = false;
- this._log = window.InspectorTest ? InspectorFrontendHost.unbufferedLog.bind(InspectorFrontendHost) : console.log.bind(console);
+ let setting = WebInspector.autoLogProtocolMessagesSetting = new WebInspector.Setting("auto-collect-protocol-messages", false);
+ setting.addEventListener(WebInspector.Setting.Event.Changed, this._startOrStopAutomaticTracing.bind(this))
+ this._startOrStopAutomaticTracing();
}
// Public
+ // It's still possible to set this flag on InspectorBackend to just
+ // dump protocol traffic as it happens. For more complex uses of
+ // protocol data, install a subclass of WebInspector.ProtocolTracer.
+ set dumpInspectorProtocolMessages(value)
+ {
+ // Implicitly cause automatic logging to start if it's allowed.
+ let setting = WebInspector.autoLogProtocolMessagesSetting;
+ setting.value = value;
+
+ if (this.activeTracer !== this._automaticTracer)
+ return;
+
+ if (this.activeTracer)
+ this.activeTracer.dumpMessagesToConsole = value;
+ }
+
+ get dumpInspectorProtocolMessages()
+ {
+ return !!this._automaticTracer;
+ }
+
+ set dumpInspectorTimeStats(value)
+ {
+ if (!this.dumpInspectorProtocolMessages)
+ this.dumpInspectorProtocolMessages = true;
+
+ if (this.activeTracer !== this._automaticTracer)
+ return;
+
+ if (this.activeTracer)
+ this.activeTracer.dumpTimingDataToConsole = value;
+ }
+
+ get dumpInspectorTimeStats()
+ {
+ return this._dumpInspectorTimeStats;
+ }
+
+ set activeTracer(tracer)
+ {
+ console.assert(!tracer || tracer instanceof WebInspector.ProtocolTracer);
+
+ // Bail early if no state change is to be made.
+ if (!tracer && !this._activeTracer)
+ return;
+
+ if (tracer === this._activeTracer)
+ return;
+
+ // Don't allow an automatic tracer to dislodge a custom tracer.
+ if (this._activeTracer && tracer === this._automaticTracer)
+ return;
+
+ if (this.activeTracer)
+ this.activeTracer.logFinished();
+
+ if (this._activeTracer === this._automaticTracer)
+ this._automaticTracer = null;
+
+ this._activeTracer = tracer;
+ if (this.activeTracer)
+ this.activeTracer.logStarted();
+ else {
+ // If the custom tracer was removed and automatic tracing is enabled,
+ // then create a new automatic tracer and install it in its place.
+ this._startOrStopAutomaticTracing();
+ }
+ }
+
+ get activeTracer()
+ {
+ return this._activeTracer || null;
+ }
+
registerCommand(qualifiedName, callSignature, replySignature)
{
var [domainName, commandName] = qualifiedName.split(".");
@@ -78,11 +153,8 @@
dispatch(message)
{
- if (this.dumpInspectorProtocolMessages)
- this._log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
+ let messageObject = (typeof message === "string") ? JSON.parse(message) : message;
- var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
-
if ("id" in messageObject)
this._dispatchResponse(messageObject);
else
@@ -113,6 +185,28 @@
// Private
+ _startOrStopAutomaticTracing()
+ {
+ let setting = WebInspector.autoLogProtocolMessagesSetting;
+
+ // Bail if there is no state transition to be made.
+ if (!(setting.value ^ !!this.activeTracer))
+ return;
+
+ if (!setting.value) {
+ if (this.activeTracer === this._automaticTracer)
+ this.activeTracer = null;
+
+ this._automaticTracer = null;
+ } else {
+ this._automaticTracer = new WebInspector.LoggingProtocolTracer;
+ this._automaticTracer.dumpMessagesToConsole = this.dumpInspectorProtocolMessages;
+ this._automaticTracer.dumpTimingDataToConsole = this.dumpTimingDataToConsole;
+ // This will be ignored if a custom tracer is installed.
+ this.activeTracer = this._automaticTracer;
+ }
+ }
+
_agentForDomain(domainName)
{
if (this._agents[domainName])
@@ -137,7 +231,7 @@
let responseData = {command, callback};
- if (this.dumpInspectorTimeStats)
+ if (this.activeTracer)
responseData.sendRequestTimestamp = timestamp();
this._pendingResponses.set(sequenceId, responseData);
@@ -158,7 +252,7 @@
let responseData = {command};
- if (this.dumpInspectorTimeStats)
+ if (this.activeTracer)
responseData.sendRequestTimestamp = timestamp();
let responsePromise = new Promise(function(resolve, reject) {
@@ -174,8 +268,8 @@
_sendMessageToBackend(messageObject)
{
let stringifiedMessage = JSON.stringify(messageObject);
- if (this.dumpInspectorProtocolMessages)
- this._log("frontend: " + stringifiedMessage);
+ if (this.activeTracer)
+ this.activeTracer.logFrontendRequest(stringifiedMessage);
InspectorFrontendHost.sendMessageToBackend(stringifiedMessage);
}
@@ -195,9 +289,11 @@
let responseData = this._pendingResponses.take(sequenceId);
let {command, callback, promise} = responseData;
- var processingStartTimestamp;
- if (this.dumpInspectorTimeStats)
+ let processingStartTimestamp;
+ if (this.activeTracer) {
processingStartTimestamp = timestamp();
+ this.activeTracer.logWillHandleResponse(JSON.stringify(messageObject));
+ }
if (typeof callback === "function")
this._dispatchResponseToCallback(command, messageObject, callback);
@@ -206,13 +302,10 @@
else
console.error("Received a command response without a corresponding callback or promise.", messageObject, command);
- let processingDuration = (timestamp() - processingStartTimestamp).toFixed(3);
- if (this.warnForLongMessageHandling && processingDuration > this.longMessageHandlingThreshold)
- console.warn(`InspectorBackend: took ${processingDuration}ms to handle response for command: ${command.qualifiedName}`);
-
- if (this.dumpInspectorTimeStats) {
- let roundTripDuration = (processingStartTimestamp - responseData.sendRequestTimestamp).toFixed(3);
- console.log(`time-stats: Handling: ${processingDuration}ms; RTT: ${roundTripDuration}ms; (command ${command.qualifiedName})`);
+ if (this.activeTracer) {
+ let processingTime = (timestamp() - processingStartTimestamp).toFixed(3);
+ let roundTripTime = (processingStartTimestamp - responseData.sendRequestTimestamp).toFixed(3);
+ this.activeTracer.logDidHandleResponse(JSON.stringify(messageObject), {rtt: roundTripTime, dispatch: processingTime});
}
if (this._deferredScripts.length && !this._pendingResponses.size)
@@ -247,48 +340,47 @@
_dispatchEvent(messageObject)
{
- var qualifiedName = messageObject["method"];
- var [domainName, eventName] = qualifiedName.split(".");
+ let qualifiedName = messageObject["method"];
+ let [domainName, eventName] = qualifiedName.split(".");
if (!(domainName in this._agents)) {
console.error("Protocol Error: Attempted to dispatch method '" + eventName + "' for non-existing domain '" + domainName + "'");
return;
}
- var agent = this._agentForDomain(domainName);
+ let agent = this._agentForDomain(domainName);
if (!agent.active) {
console.error("Protocol Error: Attempted to dispatch method for domain '" + domainName + "' which exists but is not active.");
return;
}
- var event = agent.getEvent(eventName);
+ let event = agent.getEvent(eventName);
if (!event) {
console.error("Protocol Error: Attempted to dispatch an unspecified method '" + qualifiedName + "'");
return;
}
- var eventArguments = [];
- if (messageObject["params"]) {
- var parameterNames = event.parameterNames;
- for (var i = 0; i < parameterNames.length; ++i)
- eventArguments.push(messageObject["params"][parameterNames[i]]);
- }
+ let eventArguments = [];
+ if (messageObject["params"])
+ eventArguments = event.parameterNames.map((name) => messageObject["params"][name]);
- var processingStartTimestamp;
- if (this.dumpInspectorTimeStats)
+ let processingStartTimestamp;
+ if (this.activeTracer) {
processingStartTimestamp = timestamp();
+ this.activeTracer.logWillHandleEvent(JSON.stringify(messageObject));
+ }
try {
agent.dispatchEvent(eventName, eventArguments);
} catch (e) {
console.error("Uncaught exception in inspector page while handling event " + qualifiedName, e);
+ if (this.activeTracer)
+ this.activeTracer.logFrontendException(JSON.stringify(messageObject), e);
}
- let processingDuration = (timestamp() - processingStartTimestamp).toFixed(3);
- if (this.warnForLongMessageHandling && processingDuration > this.longMessageHandlingThreshold)
- console.warn(`InspectorBackend: took ${processingDuration}ms to handle event: ${messageObject.method}`);
-
- if (this.dumpInspectorTimeStats)
- console.log(`time-stats: Handling: ${processingDuration}ms (event ${messageObject.method})`);
+ if (this.activeTracer) {
+ let processingTime = (timestamp() - processingStartTimestamp).toFixed(3);
+ this.activeTracer.logDidHandleEvent(JSON.stringify(messageObject), {dispatch: processingTime});
+ }
}
_reportProtocolError(messageObject)
@@ -300,9 +392,9 @@
{
console.assert(this._pendingResponses.size === 0);
- var scriptsToRun = this._deferredScripts;
+ let scriptsToRun = this._deferredScripts;
this._deferredScripts = [];
- for (var script of scriptsToRun)
+ for (let script of scriptsToRun)
script.call(this);
}
};
Added: trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js (0 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/LoggingProtocolTracer.js 2015-12-09 22:45:21 UTC (rev 193870)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.LoggingProtocolTracer = class LoggingProtocolTracer extends WebInspector.ProtocolTracer
+{
+ constructor()
+ {
+ super();
+
+ this._dumpMessagesToConsole = false;
+ this._dumpTimingDataToConsole = false;
+ this._logToConsole = window.InspectorTest ? InspectorFrontendHost.unbufferedLog.bind(InspectorFrontendHost) : console.log.bind(console);
+ }
+
+ // Public
+
+ set dumpMessagesToConsole(value)
+ {
+ this._dumpMessagesToConsole = !!value;
+ }
+
+ get dumpMessagesToConsole()
+ {
+ return this._dumpMessagesToConsole;
+ }
+
+ set dumpTimingDataToConsole(value)
+ {
+ this._dumpTimingDataToConsole = !!value;
+ }
+
+ get dumpTimingDataToConsole()
+ {
+ return this._dumpTimingDataToConsole;
+ }
+
+ logFrontendException(message, exception)
+ {
+ this._processEntry({type: "exception", message, exception});
+ }
+
+ logProtocolError(message, error)
+ {
+ this._processEntry({type: "error", message, error});
+ }
+
+ logFrontendRequest(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ this._processEntry({type: "request", message});
+ }
+
+ logWillHandleResponse(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ let entry = {type: "response", message};
+ this._processEntry(entry);
+ }
+
+ logDidHandleResponse(message, timings = null)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ let entry = {type: "response", message};
+ if (timings)
+ entry.timings = Object.shallowCopy(timings);
+
+ this._processEntry(entry);
+ }
+
+ logWillHandleEvent(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ let entry = {type: "event", message};
+ this._processEntry(entry);
+ }
+
+ logDidHandleEvent(message, timings = null)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ let entry = {type: "event", message};
+ if (timings)
+ entry.timings = Object.shallowCopy(timings);
+
+ this._processEntry(entry);
+ }
+
+ _processEntry(entry)
+ {
+ if (this._dumpTimingDataToConsole && entry.timings) {
+ if (entry.timings.rtt && entry.timings.dispatch)
+ this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms; RTT: ${entry.timings.rtt}ms`);
+ else if (entry.timings.dispatch)
+ this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms`);
+ } else if (this._dumpMessagesToConsole)
+ this._logToConsole(`${entry.type}: ${entry.message}`);
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js (0 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/ProtocolTracer.js 2015-12-09 22:45:21 UTC (rev 193870)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ProtocolTracer = class ProtocolTracer extends WebInspector.Object
+{
+ // Public
+
+ logStarted()
+ {
+ // To be overridden by subclasses.
+ }
+
+ logFrontendException(message, exception)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logProtocolError(message, error)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logFrontendRequest(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logWillHandleResponse(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logDidHandleResponse(message, timings = null)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logWillHandleEvent(message)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logDidHandleEvent(message, timings = null)
+ {
+ console.assert(typeof message === "string", "Must stringify messages to avoid leaking all JSON protocol messages.")
+
+ // To be overridden by subclasses.
+ }
+
+ logFinished()
+ {
+ // To be overridden by subclasses.
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (193869 => 193870)
--- trunk/Source/WebInspectorUI/UserInterface/Test.html 2015-12-09 22:39:46 UTC (rev 193869)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html 2015-12-09 22:45:21 UTC (rev 193870)
@@ -49,7 +49,11 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
+ <script src=""
+
<script src=""
<script src=""
<script src=""
@@ -135,7 +139,6 @@
<script src=""
<script src=""
<script src=""
- <script src=""
<script src=""
<script src=""
<script src=""