Web Inspector: Protocol Logging: log messages as objects if inspector^2 is open
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Protocol / LoggingProtocolTracer.js
1 /*
2  * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WI.LoggingProtocolTracer = class LoggingProtocolTracer extends WI.ProtocolTracer
27 {
28     constructor()
29     {
30         super();
31
32         this._dumpMessagesToConsole = false;
33         this._dumpTimingDataToConsole = false;
34         this._filterMultiplexingBackend = true;
35         this._logToConsole = window.InspectorTest ? InspectorFrontendHost.unbufferedLog.bind(InspectorFrontendHost) : console.log;
36     }
37
38     // Public
39
40     set dumpMessagesToConsole(value)
41     {
42         this._dumpMessagesToConsole = !!value;
43     }
44
45     get dumpMessagesToConsole()
46     {
47         return this._dumpMessagesToConsole;
48     }
49
50     set dumpTimingDataToConsole(value)
51     {
52         this._dumpTimingDataToConsole = !!value;
53     }
54
55     get dumpTimingDataToConsole()
56     {
57         return this._dumpTimingDataToConsole;
58     }
59
60     set filterMultiplexingBackend(value)
61     {
62         this._filterMultiplexingBackend = !!value;
63     }
64
65     get filterMultiplexingBackend()
66     {
67         return this._filterMultiplexingBackend;
68     }
69
70     logFrontendException(connection, message, exception)
71     {
72         this._processEntry({type: "exception", connection, message, exception});
73     }
74
75     logFrontendRequest(connection, message)
76     {
77         this._processEntry({type: "request", connection, message});
78     }
79
80     logWillHandleResponse(connection, message)
81     {
82         let entry = {type: "response", connection, message};
83         this._processEntry(entry);
84     }
85
86     logDidHandleResponse(connection, message, timings = null)
87     {
88         let entry = {type: "response", connection, message};
89         if (timings)
90             entry.timings = Object.shallowCopy(timings);
91
92         this._processEntry(entry);
93     }
94
95     logWillHandleEvent(connection, message)
96     {
97         let entry = {type: "event", connection, message};
98         this._processEntry(entry);
99     }
100
101     logDidHandleEvent(connection, message, timings = null)
102     {
103         let entry = {type: "event", connection, message};
104         if (timings)
105             entry.timings = Object.shallowCopy(timings);
106
107         this._processEntry(entry);
108     }
109
110     _processEntry(entry)
111     {
112         if (this._dumpTimingDataToConsole && entry.timings) {
113             if (entry.timings.rtt && entry.timings.dispatch)
114                 this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms; RTT: ${entry.timings.rtt}ms`);
115             else if (entry.timings.dispatch)
116                 this._logToConsole(`time-stats: Handling: ${entry.timings.dispatch || NaN}ms`);
117         } else if (this._dumpMessagesToConsole && !entry.timings) {
118             let connection = entry.connection;
119             let targetId = connection && connection.target ? connection.target.identifier : "unknown";
120             if (this._filterMultiplexingBackend && targetId === "multi")
121                 return;
122
123             let prefix = `${entry.type} (${targetId})`;
124             if (!window.InspectorTest && InspectorFrontendHost.isBeingInspected())
125                 this._logToConsole(prefix, entry.message);
126             else
127                 this._logToConsole(`${prefix}: ${JSON.stringify(entry.message)}`);
128
129             if (entry.exception) {
130                 this._logToConsole(entry.exception);
131                 if (entry.exception.stack)
132                     this._logToConsole(entry.exception.stack);
133             }
134         }
135     }
136 };