Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(634)

Side by Side Diff: netlog_viewer/log_util.js

Issue 2162963002: [polymer] Merge of master into polymer10-migration (Closed) Base URL: git@github.com:catapult-project/catapult.git@polymer10-migration
Patch Set: Merge polymer10-migration int polymer10-merge Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « netlog_viewer/log_grouper.js ('k') | netlog_viewer/log_view_painter.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 log_util = (function() {
6 'use strict';
7
8 /**
9 * Creates a new log dump. |events| is a list of all events, |polledData| is
10 * an object containing the results of each poll, |tabData| is an object
11 * containing data for individual tabs, |date| is the time the dump was
12 * created, as a formatted string, and |privacyStripping| is whether or not
13 * private information should be removed from the generated dump.
14 *
15 * Returns the new log dump as an object. Resulting object may have a null
16 * |numericDate|.
17 *
18 * TODO(eroman): Use javadoc notation for these parameters.
19 *
20 * Log dumps are just JSON objects containing five values:
21 *
22 * |userComments| User-provided notes describing what this dump file is
23 * about.
24 * |constants| needed to interpret the data. This also includes some
25 * browser state information.
26 * |events| from the NetLog.
27 * |polledData| from each PollableDataHelper available on the source OS.
28 * |tabData| containing any tab-specific state that's not present in
29 * |polledData|.
30 *
31 * |polledData| and |tabData| may be empty objects, or may be missing data for
32 * tabs not present on the OS the log is from.
33 */
34 function createLogDump(userComments, constants, events, polledData, tabData,
35 numericDate, privacyStripping) {
36 if (privacyStripping)
37 events = events.map(stripPrivacyInfo);
38
39 var logDump = {
40 'userComments': userComments,
41 'constants': constants,
42 'events': events,
43 'polledData': polledData,
44 'tabData': tabData
45 };
46
47 // Not technically client info, but it's used at the same point in the code.
48 if (numericDate && constants.clientInfo) {
49 constants.clientInfo.numericDate = numericDate;
50 }
51
52 return logDump;
53 }
54
55 /**
56 * Returns a new log dump created using the polled data and date from the
57 * |oldLogDump|. The other parts of the log dump come from current
58 * net-internals state.
59 */
60 function createUpdatedLogDump(userComments, oldLogDump, privacyStripping) {
61 var numericDate = null;
62 if (oldLogDump.constants.clientInfo &&
63 oldLogDump.constants.clientInfo.numericDate) {
64 numericDate = oldLogDump.constants.clientInfo.numericDate;
65 }
66 var logDump = createLogDump(
67 userComments,
68 Constants,
69 EventsTracker.getInstance().getAllCapturedEvents(),
70 oldLogDump.polledData,
71 getTabData_(),
72 numericDate,
73 privacyStripping);
74 return JSON.stringify(logDump);
75 }
76
77 /**
78 * Creates a full log dump using |polledData| and the return value of each
79 * tab's saveState function and passes it to |callback|.
80 */
81 function onUpdateAllCompleted(userComments, callback, privacyStripping,
82 polledData) {
83 var logDump = createLogDump(
84 userComments,
85 Constants,
86 EventsTracker.getInstance().getAllCapturedEvents(),
87 polledData,
88 getTabData_(),
89 timeutil.getCurrentTime(),
90 privacyStripping);
91 callback(JSON.stringify(logDump));
92 }
93
94 /**
95 * Called to create a new log dump. Must not be called once a dump has been
96 * loaded. Once a log dump has been created, |callback| is passed the dumped
97 * text as a string.
98 */
99 function createLogDumpAsync(userComments, callback, privacyStripping) {
100 g_browser.updateAllInfo(
101 onUpdateAllCompleted.bind(null, userComments, callback,
102 privacyStripping));
103 }
104
105 /**
106 * Gather any tab-specific state information prior to creating a log dump.
107 */
108 function getTabData_() {
109 var tabData = {};
110 var tabSwitcher = MainView.getInstance().tabSwitcher();
111 var tabIdToView = tabSwitcher.getAllTabViews();
112 for (var tabId in tabIdToView) {
113 var view = tabIdToView[tabId];
114 if (view.saveState)
115 tabData[tabId] = view.saveState();
116 }
117 }
118
119 /**
120 * Loads a full log dump. Returns a string containing a log of the load.
121 * |opt_fileName| should always be given when loading from a file, instead of
122 * from a log dump generated in-memory.
123 * The process goes like this:
124 * 1) Load constants. If this fails, or the version number can't be handled,
125 * abort the load. If this step succeeds, the load cannot be aborted.
126 * 2) Clear all events. Any event observers are informed of the clear as
127 * normal.
128 * 3) Call onLoadLogStart(polledData, tabData) for each view with an
129 * onLoadLogStart function. This allows tabs to clear any extra state
130 * that would affect the next step. |polledData| contains the data polled
131 * for all helpers, but |tabData| contains only the data from that
132 * specific tab.
133 * 4) Add all events from the log file.
134 * 5) Call onLoadLogFinish(polledData, tabData) for each view with an
135 * onLoadLogFinish function. The arguments are the same as in step 3. If
136 * there is no onLoadLogFinish function, it throws an exception, or it
137 * returns false instead of true, the data dump is assumed to contain no
138 * valid data for the tab, so the tab is hidden. Otherwise, the tab is
139 * shown.
140 */
141 function loadLogDump(logDump, opt_fileName) {
142 // Perform minimal validity check, and abort if it fails.
143 if (typeof(logDump) != 'object')
144 return 'Load failed. Top level JSON data is not an object.';
145
146 // String listing text summary of load errors, if any.
147 var errorString = '';
148
149 if (!areValidConstants(logDump.constants))
150 errorString += 'Invalid constants object.\n';
151 if (typeof(logDump.events) != 'object')
152 errorString += 'NetLog events missing.\n';
153 if (typeof(logDump.constants.logFormatVersion) != 'number')
154 errorString += 'Invalid version number.\n';
155
156 if (errorString.length > 0)
157 return 'Load failed:\n\n' + errorString;
158
159 if (typeof(logDump.polledData) != 'object')
160 logDump.polledData = {};
161 if (typeof(logDump.tabData) != 'object')
162 logDump.tabData = {};
163
164 var kSupportedLogFormatVersion = 1;
165
166 if (logDump.constants.logFormatVersion != kSupportedLogFormatVersion) {
167 return 'Unable to load different log version.' +
168 ' Found ' + logDump.constants.logFormatVersion +
169 ', Expected ' + kSupportedLogFormatVersion;
170 }
171
172 g_browser.receivedConstants(logDump.constants);
173
174 // Check for validity of each log entry, and then add the ones that pass.
175 // Since the events are kept around, and we can't just hide a single view
176 // on a bad event, we have more error checking for them than other data.
177 var validEvents = [];
178 var numDeprecatedPassiveEvents = 0;
179 for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) {
180 var event = logDump.events[eventIndex];
181 if (typeof event == 'object' &&
182 typeof event.source == 'object' &&
183 typeof event.time == 'string' &&
184 typeof EventTypeNames[event.type] == 'string' &&
185 typeof EventSourceTypeNames[event.source.type] == 'string' &&
186 getKeyWithValue(EventPhase, event.phase) != '?') {
187 if (event.wasPassivelyCaptured) {
188 // NOTE: Up until Chrome 18, log dumps included "passively captured"
189 // events. These are no longer supported, so skip past them
190 // to avoid confusing the rest of the code.
191 numDeprecatedPassiveEvents++;
192 continue;
193 }
194 validEvents.push(event);
195 }
196 }
197
198 // Make sure the loaded log contained an export date. If not we will
199 // synthesize one. This can legitimately happen for dump files created
200 // via command line flag, or for older dump formats (before Chrome 17).
201 if (typeof logDump.constants.clientInfo.numericDate != 'number') {
202 errorString += 'The log file is missing clientInfo.numericDate.\n';
203
204 if (validEvents.length > 0) {
205 errorString +=
206 'Synthesizing export date as time of last event captured.\n';
207 var lastEvent = validEvents[validEvents.length - 1];
208 ClientInfo.numericDate =
209 timeutil.convertTimeTicksToDate(lastEvent.time).getTime();
210 } else {
211 errorString += 'Can\'t guess export date!\n';
212 ClientInfo.numericDate = 0;
213 }
214 }
215
216 // Prevent communication with the browser. Once the constants have been
217 // loaded, it's safer to continue trying to load the log, even in the case
218 // of bad data.
219 MainView.getInstance().onLoadLog(opt_fileName);
220
221 // Delete all events. This will also update all logObservers.
222 EventsTracker.getInstance().deleteAllLogEntries();
223
224 // Inform all the views that a log file is being loaded, and pass in
225 // view-specific saved state, if any.
226 var tabSwitcher = MainView.getInstance().tabSwitcher();
227 var tabIdToView = tabSwitcher.getAllTabViews();
228 for (var tabId in tabIdToView) {
229 var view = tabIdToView[tabId];
230 view.onLoadLogStart(logDump.polledData, logDump.tabData[tabId]);
231 }
232 EventsTracker.getInstance().addLogEntries(validEvents);
233
234 var numInvalidEvents = logDump.events.length -
235 (validEvents.length + numDeprecatedPassiveEvents);
236 if (numInvalidEvents > 0) {
237 errorString += 'Unable to load ' + numInvalidEvents +
238 ' events, due to invalid data.\n\n';
239 }
240
241 if (numDeprecatedPassiveEvents > 0) {
242 errorString += 'Discarded ' + numDeprecatedPassiveEvents +
243 ' passively collected events. Use an older version of Chrome to' +
244 ' load this dump if you want to see them.\n\n';
245 }
246
247 // Update all views with data from the file. Show only those views which
248 // successfully load the data.
249 for (var tabId in tabIdToView) {
250 var view = tabIdToView[tabId];
251 var showView = false;
252 // The try block eliminates the need for checking every single value
253 // before trying to access it.
254 try {
255 if (view.onLoadLogFinish(logDump.polledData,
256 logDump.tabData[tabId],
257 logDump)) {
258 showView = true;
259 }
260 } catch (error) {
261 errorString += 'Caught error while calling onLoadLogFinish: ' +
262 error + '\n\n';
263 }
264 tabSwitcher.showTabLink(tabId, showView);
265 }
266
267 return errorString + 'Log loaded.';
268 }
269
270 /**
271 * Loads a log dump from the string |logFileContents|, which can be either a
272 * full net-internals dump, or a NetLog dump only. Returns a string
273 * containing a log of the load.
274 */
275 function loadLogFile(logFileContents, fileName) {
276 // Try and parse the log dump as a single JSON string. If this succeeds,
277 // it's most likely a full log dump. Otherwise, it may be a dump created by
278 // --log-net-log.
279 var parsedDump = null;
280 var errorString = '';
281 try {
282 parsedDump = JSON.parse(logFileContents);
283 } catch (error) {
284 try {
285 // We may have a --log-net-log=blah log dump. If so, remove the comma
286 // after the final good entry, and add the necessary close brackets.
287 var end = Math.max(logFileContents.lastIndexOf(',\n'),
288 logFileContents.lastIndexOf(',\r'));
289 if (end != -1) {
290 parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}');
291 errorString += 'Log file truncated. Events may be missing.\n';
292 }
293 }
294 catch (error2) {
295 }
296 }
297
298 if (!parsedDump)
299 return 'Unable to parse log dump as JSON file.';
300 return errorString + loadLogDump(parsedDump, fileName);
301 }
302
303 // Exports.
304 return {
305 createUpdatedLogDump: createUpdatedLogDump,
306 createLogDumpAsync: createLogDumpAsync,
307 loadLogFile: loadLogFile
308 };
309 })();
310
OLDNEW
« no previous file with comments | « netlog_viewer/log_grouper.js ('k') | netlog_viewer/log_view_painter.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698