Bug 1338522 - Add telemetry for UI responsiveness during import of profile data from another browser. r=francois,Gijs

MozReview-Commit-ID: Cmh0rhZEPDo

--HG--
extra : rebase_source : 303278eeced0fa177a2147d0fe1e010c976e7c76
This commit is contained in:
Dão Gottwald 2017-02-18 00:01:50 +01:00
parent 004f014a86
commit 75df2a0b7d
4 changed files with 126 additions and 22 deletions

View File

@ -28,6 +28,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ResponsivenessMonitor",
"resource://gre/modules/ResponsivenessMonitor.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
"resource://gre/modules/Sqlite.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
@ -212,7 +214,7 @@ this.MigratorPrototype = {
return types.reduce((a, b) => { a |= b; return a }, 0);
},
getKey: function MP_getKey() {
getBrowserKey: function MP_getBrowserKey() {
return this.contractID.match(/\=([^\=]+)$/)[1];
},
@ -237,40 +239,64 @@ this.MigratorPrototype = {
});
};
let getHistogramForResourceType = resourceType => {
let getHistogramIdForResourceType = (resourceType, template) => {
if (resourceType == MigrationUtils.resourceTypes.HISTORY) {
return "FX_MIGRATION_HISTORY_IMPORT_MS";
return template.replace("*", "HISTORY");
}
if (resourceType == MigrationUtils.resourceTypes.BOOKMARKS) {
return "FX_MIGRATION_BOOKMARKS_IMPORT_MS";
return template.replace("*", "BOOKMARKS");
}
if (resourceType == MigrationUtils.resourceTypes.PASSWORDS) {
return "FX_MIGRATION_LOGINS_IMPORT_MS";
return template.replace("*", "LOGINS");
}
return null;
};
let maybeStartTelemetryStopwatch = (resourceType) => {
let histogram = getHistogramForResourceType(resourceType);
if (histogram) {
TelemetryStopwatch.startKeyed(histogram, this.getKey());
let browserKey = this.getBrowserKey();
let maybeStartTelemetryStopwatch = resourceType => {
let histogramId = getHistogramIdForResourceType(resourceType, "FX_MIGRATION_*_IMPORT_MS");
if (histogramId) {
TelemetryStopwatch.startKeyed(histogramId, browserKey);
}
return histogramId;
};
let maybeStopTelemetryStopwatch = (resourceType) => {
let histogram = getHistogramForResourceType(resourceType);
if (histogram) {
TelemetryStopwatch.finishKeyed(histogram, this.getKey());
let maybeStartResponsivenessMonitor = resourceType => {
let responsivenessMonitor;
let responsivenessHistogramId =
getHistogramIdForResourceType(resourceType, "FX_MIGRATION_*_JANK_MS");
if (responsivenessHistogramId) {
responsivenessMonitor = new ResponsivenessMonitor();
}
return {responsivenessMonitor, responsivenessHistogramId};
};
let maybeFinishResponsivenessMonitor = (responsivenessMonitor, histogramId) => {
if (responsivenessMonitor) {
let accumulatedDelay = responsivenessMonitor.finish();
if (histogramId) {
try {
Services.telemetry.getKeyedHistogramById(histogramId)
.add(browserKey, accumulatedDelay);
} catch (ex) {
Cu.reportError(histogramId + ": " + ex);
}
}
}
};
let collectQuantityTelemetry = () => {
try {
for (let resourceType of Object.keys(MigrationUtils._importQuantities)) {
let histogramId =
"FX_MIGRATION_" + resourceType.toUpperCase() + "_QUANTITY";
let histogram = Services.telemetry.getKeyedHistogramById(histogramId);
histogram.add(this.getKey(), MigrationUtils._importQuantities[resourceType]);
for (let resourceType of Object.keys(MigrationUtils._importQuantities)) {
let histogramId =
"FX_MIGRATION_" + resourceType.toUpperCase() + "_QUANTITY";
try {
Services.telemetry.getKeyedHistogramById(histogramId)
.add(browserKey, MigrationUtils._importQuantities[resourceType]);
} catch (ex) {
Cu.reportError(histogramId + ": " + ex);
}
} catch (ex) { /* Telemetry is exception-happy */ }
}
};
// Called either directly or through the bookmarks import callback.
@ -297,7 +323,10 @@ this.MigratorPrototype = {
for (let [migrationType, itemResources] of resourcesGroupedByItems) {
notify("Migration:ItemBeforeMigrate", migrationType);
maybeStartTelemetryStopwatch(migrationType);
let stopwatchHistogramId = maybeStartTelemetryStopwatch(migrationType);
let {responsivenessMonitor, responsivenessHistogramId} =
maybeStartResponsivenessMonitor(migrationType);
let itemSuccess = false;
for (let res of itemResources) {
@ -311,7 +340,11 @@ this.MigratorPrototype = {
migrationType);
resourcesGroupedByItems.delete(migrationType);
maybeStopTelemetryStopwatch(migrationType);
if (stopwatchHistogramId) {
TelemetryStopwatch.finishKeyed(stopwatchHistogramId, browserKey);
}
maybeFinishResponsivenessMonitor(responsivenessMonitor, responsivenessHistogramId);
if (resourcesGroupedByItems.size == 0) {
collectQuantityTelemetry();

View File

@ -5114,6 +5114,39 @@
"keyed": true,
"description": "How long it took to import logins (passwords) from another browser, keyed by the name of the browser."
},
"FX_MIGRATION_BOOKMARKS_JANK_MS": {
"bug_numbers": [1338522],
"alert_emails": ["dao@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"n_buckets": 20,
"high": 60000,
"releaseChannelCollection": "opt-out",
"keyed": true,
"description": "Accumulated timer delay (variance between when the timer was expected to fire and when it actually fired) in milliseconds as an indicator for decreased main-thread responsiveness while importing bookmarks from another browser, keyed by the name of the browser (see gAvailableMigratorKeys in MigrationUtils.jsm). The import is happening on a background thread and should ideally not affect the UI noticeably."
},
"FX_MIGRATION_HISTORY_JANK_MS": {
"bug_numbers": [1338522],
"alert_emails": ["dao@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"n_buckets": 20,
"high": 60000,
"releaseChannelCollection": "opt-out",
"keyed": true,
"description": "Accumulated timer delay (variance between when the timer was expected to fire and when it actually fired) in milliseconds as an indicator for decreased main-thread responsiveness while importing history from another browser, keyed by the name of the browser (see gAvailableMigratorKeys in MigrationUtils.jsm). The import is happening on a background thread and should ideally not affect the UI noticeably."
},
"FX_MIGRATION_LOGINS_JANK_MS": {
"bug_numbers": [1338522],
"alert_emails": ["dao@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"n_buckets": 20,
"high": 60000,
"releaseChannelCollection": "opt-out",
"keyed": true,
"description": "Accumulated timer delay (variance between when the timer was expected to fire and when it actually fired) in milliseconds as an indicator for decreased main-thread responsiveness while importing logins / passwords from another browser, keyed by the name of the browser (see gAvailableMigratorKeys in MigrationUtils.jsm). The import is happening on a background thread and should ideally not affect the UI noticeably."
},
"FX_MIGRATION_BOOKMARKS_QUANTITY": {
"bug_numbers": [1279501],
"alert_emails": ["gijs@mozilla.com"],

View File

@ -0,0 +1,37 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["ResponsivenessMonitor"];
const { classes: Cc, interfaces: Ci } = Components;
function ResponsivenessMonitor(intervalMS = 100) {
this._intervalMS = intervalMS;
this._prevTimestamp = Date.now();
this._accumulatedDelay = 0;
this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._timer.initWithCallback(this, this._intervalMS, Ci.nsITimer.TYPE_REPEATING_SLACK);
}
ResponsivenessMonitor.prototype = {
notify() {
let now = Date.now();
this._accumulatedDelay += Math.max(0, now - this._prevTimestamp - this._intervalMS);
this._prevTimestamp = now;
},
abort() {
if (this._timer) {
this._timer.cancel();
this._timer = null;
}
},
finish() {
this.abort();
return this._accumulatedDelay;
},
};

View File

@ -78,6 +78,7 @@ EXTRA_JS_MODULES += [
'RemoteSecurityUI.jsm',
'RemoteWebProgress.jsm',
'ResetProfile.jsm',
'ResponsivenessMonitor.jsm',
'secondscreen/RokuApp.jsm',
'secondscreen/SimpleServiceDiscovery.jsm',
'SelectContentHelper.jsm',