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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: netlog_viewer/log_util.js
diff --git a/netlog_viewer/log_util.js b/netlog_viewer/log_util.js
new file mode 100644
index 0000000000000000000000000000000000000000..d360fdab51f6d6adb16d0427569fefd7bc2e43e5
--- /dev/null
+++ b/netlog_viewer/log_util.js
@@ -0,0 +1,310 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+log_util = (function() {
+ 'use strict';
+
+ /**
+ * Creates a new log dump. |events| is a list of all events, |polledData| is
+ * an object containing the results of each poll, |tabData| is an object
+ * containing data for individual tabs, |date| is the time the dump was
+ * created, as a formatted string, and |privacyStripping| is whether or not
+ * private information should be removed from the generated dump.
+ *
+ * Returns the new log dump as an object. Resulting object may have a null
+ * |numericDate|.
+ *
+ * TODO(eroman): Use javadoc notation for these parameters.
+ *
+ * Log dumps are just JSON objects containing five values:
+ *
+ * |userComments| User-provided notes describing what this dump file is
+ * about.
+ * |constants| needed to interpret the data. This also includes some
+ * browser state information.
+ * |events| from the NetLog.
+ * |polledData| from each PollableDataHelper available on the source OS.
+ * |tabData| containing any tab-specific state that's not present in
+ * |polledData|.
+ *
+ * |polledData| and |tabData| may be empty objects, or may be missing data for
+ * tabs not present on the OS the log is from.
+ */
+ function createLogDump(userComments, constants, events, polledData, tabData,
+ numericDate, privacyStripping) {
+ if (privacyStripping)
+ events = events.map(stripPrivacyInfo);
+
+ var logDump = {
+ 'userComments': userComments,
+ 'constants': constants,
+ 'events': events,
+ 'polledData': polledData,
+ 'tabData': tabData
+ };
+
+ // Not technically client info, but it's used at the same point in the code.
+ if (numericDate && constants.clientInfo) {
+ constants.clientInfo.numericDate = numericDate;
+ }
+
+ return logDump;
+ }
+
+ /**
+ * Returns a new log dump created using the polled data and date from the
+ * |oldLogDump|. The other parts of the log dump come from current
+ * net-internals state.
+ */
+ function createUpdatedLogDump(userComments, oldLogDump, privacyStripping) {
+ var numericDate = null;
+ if (oldLogDump.constants.clientInfo &&
+ oldLogDump.constants.clientInfo.numericDate) {
+ numericDate = oldLogDump.constants.clientInfo.numericDate;
+ }
+ var logDump = createLogDump(
+ userComments,
+ Constants,
+ EventsTracker.getInstance().getAllCapturedEvents(),
+ oldLogDump.polledData,
+ getTabData_(),
+ numericDate,
+ privacyStripping);
+ return JSON.stringify(logDump);
+ }
+
+ /**
+ * Creates a full log dump using |polledData| and the return value of each
+ * tab's saveState function and passes it to |callback|.
+ */
+ function onUpdateAllCompleted(userComments, callback, privacyStripping,
+ polledData) {
+ var logDump = createLogDump(
+ userComments,
+ Constants,
+ EventsTracker.getInstance().getAllCapturedEvents(),
+ polledData,
+ getTabData_(),
+ timeutil.getCurrentTime(),
+ privacyStripping);
+ callback(JSON.stringify(logDump));
+ }
+
+ /**
+ * Called to create a new log dump. Must not be called once a dump has been
+ * loaded. Once a log dump has been created, |callback| is passed the dumped
+ * text as a string.
+ */
+ function createLogDumpAsync(userComments, callback, privacyStripping) {
+ g_browser.updateAllInfo(
+ onUpdateAllCompleted.bind(null, userComments, callback,
+ privacyStripping));
+ }
+
+ /**
+ * Gather any tab-specific state information prior to creating a log dump.
+ */
+ function getTabData_() {
+ var tabData = {};
+ var tabSwitcher = MainView.getInstance().tabSwitcher();
+ var tabIdToView = tabSwitcher.getAllTabViews();
+ for (var tabId in tabIdToView) {
+ var view = tabIdToView[tabId];
+ if (view.saveState)
+ tabData[tabId] = view.saveState();
+ }
+ }
+
+ /**
+ * Loads a full log dump. Returns a string containing a log of the load.
+ * |opt_fileName| should always be given when loading from a file, instead of
+ * from a log dump generated in-memory.
+ * The process goes like this:
+ * 1) Load constants. If this fails, or the version number can't be handled,
+ * abort the load. If this step succeeds, the load cannot be aborted.
+ * 2) Clear all events. Any event observers are informed of the clear as
+ * normal.
+ * 3) Call onLoadLogStart(polledData, tabData) for each view with an
+ * onLoadLogStart function. This allows tabs to clear any extra state
+ * that would affect the next step. |polledData| contains the data polled
+ * for all helpers, but |tabData| contains only the data from that
+ * specific tab.
+ * 4) Add all events from the log file.
+ * 5) Call onLoadLogFinish(polledData, tabData) for each view with an
+ * onLoadLogFinish function. The arguments are the same as in step 3. If
+ * there is no onLoadLogFinish function, it throws an exception, or it
+ * returns false instead of true, the data dump is assumed to contain no
+ * valid data for the tab, so the tab is hidden. Otherwise, the tab is
+ * shown.
+ */
+ function loadLogDump(logDump, opt_fileName) {
+ // Perform minimal validity check, and abort if it fails.
+ if (typeof(logDump) != 'object')
+ return 'Load failed. Top level JSON data is not an object.';
+
+ // String listing text summary of load errors, if any.
+ var errorString = '';
+
+ if (!areValidConstants(logDump.constants))
+ errorString += 'Invalid constants object.\n';
+ if (typeof(logDump.events) != 'object')
+ errorString += 'NetLog events missing.\n';
+ if (typeof(logDump.constants.logFormatVersion) != 'number')
+ errorString += 'Invalid version number.\n';
+
+ if (errorString.length > 0)
+ return 'Load failed:\n\n' + errorString;
+
+ if (typeof(logDump.polledData) != 'object')
+ logDump.polledData = {};
+ if (typeof(logDump.tabData) != 'object')
+ logDump.tabData = {};
+
+ var kSupportedLogFormatVersion = 1;
+
+ if (logDump.constants.logFormatVersion != kSupportedLogFormatVersion) {
+ return 'Unable to load different log version.' +
+ ' Found ' + logDump.constants.logFormatVersion +
+ ', Expected ' + kSupportedLogFormatVersion;
+ }
+
+ g_browser.receivedConstants(logDump.constants);
+
+ // Check for validity of each log entry, and then add the ones that pass.
+ // Since the events are kept around, and we can't just hide a single view
+ // on a bad event, we have more error checking for them than other data.
+ var validEvents = [];
+ var numDeprecatedPassiveEvents = 0;
+ for (var eventIndex = 0; eventIndex < logDump.events.length; ++eventIndex) {
+ var event = logDump.events[eventIndex];
+ if (typeof event == 'object' &&
+ typeof event.source == 'object' &&
+ typeof event.time == 'string' &&
+ typeof EventTypeNames[event.type] == 'string' &&
+ typeof EventSourceTypeNames[event.source.type] == 'string' &&
+ getKeyWithValue(EventPhase, event.phase) != '?') {
+ if (event.wasPassivelyCaptured) {
+ // NOTE: Up until Chrome 18, log dumps included "passively captured"
+ // events. These are no longer supported, so skip past them
+ // to avoid confusing the rest of the code.
+ numDeprecatedPassiveEvents++;
+ continue;
+ }
+ validEvents.push(event);
+ }
+ }
+
+ // Make sure the loaded log contained an export date. If not we will
+ // synthesize one. This can legitimately happen for dump files created
+ // via command line flag, or for older dump formats (before Chrome 17).
+ if (typeof logDump.constants.clientInfo.numericDate != 'number') {
+ errorString += 'The log file is missing clientInfo.numericDate.\n';
+
+ if (validEvents.length > 0) {
+ errorString +=
+ 'Synthesizing export date as time of last event captured.\n';
+ var lastEvent = validEvents[validEvents.length - 1];
+ ClientInfo.numericDate =
+ timeutil.convertTimeTicksToDate(lastEvent.time).getTime();
+ } else {
+ errorString += 'Can\'t guess export date!\n';
+ ClientInfo.numericDate = 0;
+ }
+ }
+
+ // Prevent communication with the browser. Once the constants have been
+ // loaded, it's safer to continue trying to load the log, even in the case
+ // of bad data.
+ MainView.getInstance().onLoadLog(opt_fileName);
+
+ // Delete all events. This will also update all logObservers.
+ EventsTracker.getInstance().deleteAllLogEntries();
+
+ // Inform all the views that a log file is being loaded, and pass in
+ // view-specific saved state, if any.
+ var tabSwitcher = MainView.getInstance().tabSwitcher();
+ var tabIdToView = tabSwitcher.getAllTabViews();
+ for (var tabId in tabIdToView) {
+ var view = tabIdToView[tabId];
+ view.onLoadLogStart(logDump.polledData, logDump.tabData[tabId]);
+ }
+ EventsTracker.getInstance().addLogEntries(validEvents);
+
+ var numInvalidEvents = logDump.events.length -
+ (validEvents.length + numDeprecatedPassiveEvents);
+ if (numInvalidEvents > 0) {
+ errorString += 'Unable to load ' + numInvalidEvents +
+ ' events, due to invalid data.\n\n';
+ }
+
+ if (numDeprecatedPassiveEvents > 0) {
+ errorString += 'Discarded ' + numDeprecatedPassiveEvents +
+ ' passively collected events. Use an older version of Chrome to' +
+ ' load this dump if you want to see them.\n\n';
+ }
+
+ // Update all views with data from the file. Show only those views which
+ // successfully load the data.
+ for (var tabId in tabIdToView) {
+ var view = tabIdToView[tabId];
+ var showView = false;
+ // The try block eliminates the need for checking every single value
+ // before trying to access it.
+ try {
+ if (view.onLoadLogFinish(logDump.polledData,
+ logDump.tabData[tabId],
+ logDump)) {
+ showView = true;
+ }
+ } catch (error) {
+ errorString += 'Caught error while calling onLoadLogFinish: ' +
+ error + '\n\n';
+ }
+ tabSwitcher.showTabLink(tabId, showView);
+ }
+
+ return errorString + 'Log loaded.';
+ }
+
+ /**
+ * Loads a log dump from the string |logFileContents|, which can be either a
+ * full net-internals dump, or a NetLog dump only. Returns a string
+ * containing a log of the load.
+ */
+ function loadLogFile(logFileContents, fileName) {
+ // Try and parse the log dump as a single JSON string. If this succeeds,
+ // it's most likely a full log dump. Otherwise, it may be a dump created by
+ // --log-net-log.
+ var parsedDump = null;
+ var errorString = '';
+ try {
+ parsedDump = JSON.parse(logFileContents);
+ } catch (error) {
+ try {
+ // We may have a --log-net-log=blah log dump. If so, remove the comma
+ // after the final good entry, and add the necessary close brackets.
+ var end = Math.max(logFileContents.lastIndexOf(',\n'),
+ logFileContents.lastIndexOf(',\r'));
+ if (end != -1) {
+ parsedDump = JSON.parse(logFileContents.substring(0, end) + ']}');
+ errorString += 'Log file truncated. Events may be missing.\n';
+ }
+ }
+ catch (error2) {
+ }
+ }
+
+ if (!parsedDump)
+ return 'Unable to parse log dump as JSON file.';
+ return errorString + loadLogDump(parsedDump, fileName);
+ }
+
+ // Exports.
+ return {
+ createUpdatedLogDump: createUpdatedLogDump,
+ createLogDumpAsync: createLogDumpAsync,
+ loadLogFile: loadLogFile
+ };
+})();
+
« 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