Bug 1091140, add telemetry for sanitize, r=vdjeric
authorNeil Deakin <neil@mozilla.com>
Mon, 26 Jan 2015 20:58:22 -0500
changeset 253032 05dfcf108b4fc66ded06fcb9b4d653b7e63ed2af
parent 253031 f5c6c57fc11a3da2627648a654fcdf3cca525fa5
child 253033 45921e3d97733905f6bd0a3a6f05554ed66ce6b4
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvdjeric
bugs1091140
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1091140, add telemetry for sanitize, r=vdjeric
browser/base/content/sanitize.js
toolkit/components/telemetry/Histograms.json
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -12,16 +12,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                                   "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
+                                  "resource://gre/modules/TelemetryStopwatch.jsm");
 
 function Sanitizer() {}
 Sanitizer.prototype = {
   // warning to the caller: this one may raise an exception (e.g. bug #265028)
   clearItem: function (aItemName)
   {
     if (this.items[aItemName].canClear)
       this.items[aItemName].clear();
@@ -87,25 +89,28 @@ Sanitizer.prototype = {
       // When cancelled, reject immediately
       if (!ok) {
         deferred.reject("Sanitizer canceled closing windows");
       }
 
       return deferred.promise;
     }
 
+    TelemetryStopwatch.start("FX_SANITIZE_TOTAL");
+
     // Cache the range of times to clear
     if (this.ignoreTimespan)
       var range = null;  // If we ignore timespan, clear everything
     else
       range = this.range || Sanitizer.getClearRange();
 
     let itemCount = Object.keys(itemsToClear).length;
     let onItemComplete = function() {
       if (!--itemCount) {
+        TelemetryStopwatch.finish("FX_SANITIZE_TOTAL");
         seenError ? deferred.reject() : deferred.resolve();
       }
     };
     for (let itemName of itemsToClear) {
       let item = this.items[itemName];
       item.range = range;
       if ("clear" in item) {
         let clearCallback = (itemName, aCanClear) => {
@@ -141,40 +146,46 @@ Sanitizer.prototype = {
   // pref to determine a range
   ignoreTimespan : true,
   range : null,
 
   items: {
     cache: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_CACHE");
+
         var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].
                     getService(Ci.nsICacheStorageService);
         try {
           // Cache doesn't consult timespan, nor does it have the
           // facility for timespan-based eviction.  Wipe it.
           cache.clear();
         } catch(er) {}
 
         var imageCache = Cc["@mozilla.org/image/tools;1"].
                          getService(Ci.imgITools).getImgCacheForDocument(null);
         try {
           imageCache.clearCache(false); // true=chrome, false=content
         } catch(er) {}
+
+        TelemetryStopwatch.finish("FX_SANITIZE_CACHE");
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     cookies: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_COOKIES");
+
         var cookieMgr = Components.classes["@mozilla.org/cookiemanager;1"]
                                   .getService(Ci.nsICookieManager);
         if (this.range) {
           // Iterate through the cookies and delete any created after our cutoff.
           var cookiesEnum = cookieMgr.enumerator;
           while (cookiesEnum.hasMoreElements()) {
             var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
 
@@ -212,40 +223,46 @@ Sanitizer.prototype = {
                   ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, -1);
                 } catch (e) {
                   // Ignore errors from the plugin
                 }
               }
             }
           }
         }
+
+        TelemetryStopwatch.finish("FX_SANITIZE_COOKIES");
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     offlineApps: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_OFFLINEAPPS");
         Components.utils.import("resource:///modules/offlineAppCache.jsm");
         OfflineAppCacheHelper.clear();
+        TelemetryStopwatch.finish("FX_SANITIZE_OFFLINEAPPS");
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     history: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_HISTORY");
+
         if (this.range)
           PlacesUtils.history.removeVisitsByTimeframe(this.range[0], this.range[1]);
         else
           PlacesUtils.history.removeAllPages();
 
         try {
           var os = Components.classes["@mozilla.org/observer-service;1"]
                              .getService(Components.interfaces.nsIObserverService);
@@ -254,29 +271,33 @@ Sanitizer.prototype = {
         }
         catch (e) { }
 
         try {
           var predictor = Components.classes["@mozilla.org/network/predictor;1"]
                                     .getService(Components.interfaces.nsINetworkPredictor);
           predictor.reset();
         } catch (e) { }
+
+        TelemetryStopwatch.finish("FX_SANITIZE_HISTORY");
       },
 
       get canClear()
       {
         // bug 347231: Always allow clearing history due to dependencies on
         // the browser:purge-session-history notification. (like error console)
         return true;
       }
     },
 
     formdata: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_FORMDATA");
+
         // Clear undo history of all searchBars
         var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
                                       .getService(Components.interfaces.nsIWindowMediator);
         var windows = windowManager.getEnumerator("navigator:browser");
         while (windows.hasMoreElements()) {
           let currentWindow = windows.getNext();
           let currentDocument = currentWindow.document;
           let searchBar = currentDocument.getElementById("searchbar");
@@ -291,16 +312,18 @@ Sanitizer.prototype = {
           tabBrowser._lastFindValue = "";
         }
 
         let change = { op: "remove" };
         if (this.range) {
           [ change.firstUsedStart, change.firstUsedEnd ] = this.range;
         }
         FormHistory.update(change);
+
+        TelemetryStopwatch.finish("FX_SANITIZE_FORMDATA");
       },
 
       canClear : function(aCallback, aArg)
       {
         var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
                                       .getService(Components.interfaces.nsIWindowMediator);
         var windows = windowManager.getEnumerator("navigator:browser");
         while (windows.hasMoreElements()) {
@@ -337,80 +360,93 @@ Sanitizer.prototype = {
         FormHistory.count({}, countDone);
         return false;
       }
     },
 
     downloads: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_DOWNLOADS");
         Task.spawn(function () {
           let filterByTime = null;
           if (this.range) {
             // Convert microseconds back to milliseconds for date comparisons.
             let rangeBeginMs = this.range[0] / 1000;
             let rangeEndMs = this.range[1] / 1000;
             filterByTime = download => download.startTime >= rangeBeginMs &&
                                        download.startTime <= rangeEndMs;
           }
 
           // Clear all completed/cancelled downloads
           let list = yield Downloads.getList(Downloads.ALL);
           list.removeFinished(filterByTime);
-        }.bind(this)).then(null, Components.utils.reportError);
+          TelemetryStopwatch.finish("FX_SANITIZE_DOWNLOADS");
+        }.bind(this)).then(null, error => {
+          TelemetryStopwatch.finish("FX_SANITIZE_DOWNLOADS");
+          Components.utils.reportError(error);
+        });
       },
 
       canClear : function(aCallback, aArg)
       {
         aCallback("downloads", true, aArg);
         return false;
       }
     },
 
     passwords: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_PASSWORDS");
         var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
                               .getService(Components.interfaces.nsILoginManager);
         // Passwords are timeless, and don't respect the timeSpan setting
         pwmgr.removeAllLogins();
+        TelemetryStopwatch.finish("FX_SANITIZE_PASSWORDS");
       },
 
       get canClear()
       {
         var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
                               .getService(Components.interfaces.nsILoginManager);
         var count = pwmgr.countLogins("", "", ""); // count all logins
         return (count > 0);
       }
     },
 
     sessions: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_SESSIONS");
+
         // clear all auth tokens
         var sdr = Components.classes["@mozilla.org/security/sdr;1"]
                             .getService(Components.interfaces.nsISecretDecoderRing);
         sdr.logoutAndTeardown();
 
         // clear FTP and plain HTTP auth sessions
         var os = Components.classes["@mozilla.org/observer-service;1"]
                            .getService(Components.interfaces.nsIObserverService);
         os.notifyObservers(null, "net:clear-active-logins", null);
+
+        TelemetryStopwatch.finish("FX_SANITIZE_SESSIONS");
       },
 
       get canClear()
       {
         return true;
       }
     },
 
     siteSettings: {
       clear: function ()
       {
+        TelemetryStopwatch.start("FX_SANITIZE_SITESETTINGS");
+
         // Clear site-specific permissions like "Allow this site to open popups"
         // we ignore the "end" range and hope it is now() - none of the
         // interfaces used here support a true range anyway.
         let startDateMS = this.range == null ? null : this.range[0] / 1000;
         var pm = Components.classes["@mozilla.org/permissionmanager;1"]
                            .getService(Components.interfaces.nsIPermissionManager);
         if (startDateMS == null) {
           pm.removeAll();
@@ -439,16 +475,18 @@ Sanitizer.prototype = {
           pwmgr.setLoginSavingEnabled(host, true);
         }
 
         // Clear site security settings - no support for ranges in this
         // interface either, so we clearAll().
         var sss = Cc["@mozilla.org/ssservice;1"]
                     .getService(Ci.nsISiteSecurityService);
         sss.clearAll();
+
+        TelemetryStopwatch.finish("FX_SANITIZE_SITESETTINGS");
       },
 
       get canClear()
       {
         return true;
       }
     },
     openWindows: {
@@ -511,16 +549,18 @@ Sanitizer.prototype = {
           if (existingWindow.performance.now() > (startDate + 60 * 1000)) {
             this._resetAllWindowClosures(windowList);
             return false;
           }
         }
 
         // If/once we get here, we should actually be able to close all windows.
 
+        TelemetryStopwatch.start("FX_SANITIZE_OPENWINDOWS");
+
         // First create a new window. We do this first so that on non-mac, we don't
         // accidentally close the app by closing all the windows.
         let handler = Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler);
         let defaultArgs = handler.defaultArgs;
         let features = "chrome,all,dialog=no," + this.privateStateForNewWindow;
         let newWindow = existingWindow.openDialog("chrome://browser/content/", "_blank",
                                                   features, defaultArgs);
 #ifdef XP_MACOSX
@@ -550,28 +590,32 @@ Sanitizer.prototype = {
             return;
 
           Services.obs.removeObserver(onWindowOpened, "browser-delayed-startup-finished");
 #ifdef XP_MACOSX
           newWindow.removeEventListener("fullscreen", onFullScreen);
 #endif
           newWindowOpened = true;
           // If we're the last thing to happen, invoke callback.
-          if (numWindowsClosing == 0)
+          if (numWindowsClosing == 0) {
+            TelemetryStopwatch.finish("FX_SANITIZE_OPENWINDOWS");
             aCallback();
+          }
         }
 
         let numWindowsClosing = windowList.length;
         function onWindowClosed() {
           numWindowsClosing--;
           if (numWindowsClosing == 0) {
             Services.obs.removeObserver(onWindowClosed, "xul-window-destroyed");
             // If we're the last thing to happen, invoke callback.
-            if (newWindowOpened)
+            if (newWindowOpened) {
+              TelemetryStopwatch.finish("FX_SANITIZE_OPENWINDOWS");
               aCallback();
+            }
           }
         }
 
         Services.obs.addObserver(onWindowOpened, "browser-delayed-startup-finished", false);
         Services.obs.addObserver(onWindowClosed, "xul-window-destroyed", false);
 
         // Start the process of closing windows
         while (windowList.length) {
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7150,16 +7150,115 @@
   },
   "DATA_STORAGE_ENTRIES": {
     "expires_in_version": "default",
     "kind": "linear",
     "high": "1024",
     "n_buckets": 16,
     "description": "The number of entries in persistent DataStorage (HSTS and HPKP data, basically)"
   },
+  "FX_SANITIZE_TOTAL": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Total time it takes to sanitize (ms)"
+  },
+  "FX_SANITIZE_CACHE": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize the cache (ms)"
+  },
+  "FX_SANITIZE_COOKIES": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize cookies (ms)"
+  },
+  "FX_SANITIZE_OFFLINEAPPS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize stored offline app data (ms)"
+  },
+  "FX_SANITIZE_HISTORY": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize history (ms)"
+  },
+  "FX_SANITIZE_FORMDATA": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize stored form data (ms)"
+  },
+  "FX_SANITIZE_DOWNLOADS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize recent downloads (ms)"
+  },
+  "FX_SANITIZE_PASSWORDS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize saved passwords (ms)"
+  },
+  "FX_SANITIZE_SESSIONS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize saved sessions (ms)"
+  },
+  "FX_SANITIZE_SITESETTINGS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize site-specific settings (ms)"
+  },
+  "FX_SANITIZE_OPENWINDOWS": {
+    "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
+    "expires_in_version": "40",
+    "kind": "exponential",
+    "high": "30000",
+    "n_buckets": 20,
+    "extended_statistics_ok": true,
+    "description": "Sanitize: Time it takes to sanitize the open windows list (ms)"
+  },
   "PWMGR_BLOCKLIST_NUM_SITES": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 100,
     "n_buckets" : 10,
     "extended_statistics_ok": true,
     "description": "The number of sites for which the user has explicitly rejected saving logins"
   },