Bug 1158511 - Add 'most recent expired visit' telemetry. r=adw draft
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 29 Jan 2016 17:06:04 +0100
changeset 327171 a2afc1e3b6be66d125b2f8793e79d03a9d336d28
parent 327170 ccbe2dff012aa388153990e0a3e9c1323663270a
child 513665 7822c0c566f55311c089b807097fa9c8f96610bc
push id10203
push usermak77@bonardo.net
push dateFri, 29 Jan 2016 20:51:55 +0000
reviewersadw
bugs1158511
milestone47.0a1
Bug 1158511 - Add 'most recent expired visit' telemetry. r=adw
toolkit/components/places/nsPlacesExpiration.js
toolkit/components/telemetry/Histograms.json
--- a/toolkit/components/places/nsPlacesExpiration.js
+++ b/toolkit/components/places/nsPlacesExpiration.js
@@ -117,27 +117,27 @@ const SHUTDOWN_WITH_RECENT_CLEARHISTORY_
 // If the pages delta from the last ANALYZE is over this threashold, the tables
 // should be analyzed again.
 const ANALYZE_PAGES_THRESHOLD = 100;
 
 // If the number of pages over history limit is greater than this threshold,
 // expiration will be more aggressive, to bring back history to a saner size.
 const OVERLIMIT_PAGES_THRESHOLD = 1000;
 
-const USECS_PER_DAY = 86400000000;
+const MSECS_PER_DAY = 86400000;
 const ANNOS_EXPIRE_POLICIES = [
   { bind: "expire_days",
     type: Ci.nsIAnnotationService.EXPIRE_DAYS,
-    time: 7 * USECS_PER_DAY },
+    time: 7 * 1000 * MSECS_PER_DAY },
   { bind: "expire_weeks",
     type: Ci.nsIAnnotationService.EXPIRE_WEEKS,
-    time: 30 * USECS_PER_DAY },
+    time: 30 * 1000 * MSECS_PER_DAY },
   { bind: "expire_months",
     type: Ci.nsIAnnotationService.EXPIRE_MONTHS,
-    time: 180 * USECS_PER_DAY },
+    time: 180 * 1000 * MSECS_PER_DAY },
 ];
 
 // When we expire we can use these limits:
 // - SMALL for usual partial expirations, will expire a small chunk.
 // - LARGE for idle or shutdown expirations, will expire a large chunk.
 // - UNLIMITED for clearHistory, will expire everything.
 // - DEBUG will use a known limit, passed along with the debug notification.
 const LIMIT = {
@@ -357,18 +357,20 @@ const EXPIRATION_QUERIES = {
   },
 
   // Select entries for notifications.
   // If p_id is set whole_entry = 1, then we have expired the full page.
   // Either p_id or v_id are always set.
   QUERY_SELECT_NOTIFICATIONS: {
     sql: `SELECT url, guid, MAX(visit_date) AS visit_date,
                  MAX(IFNULL(MIN(p_id, 1), MIN(v_id, 0))) AS whole_entry,
-                 expected_results
-          FROM expiration_notify
+                 expected_results,
+                 (SELECT MAX(visit_date) FROM expiration_notify
+                  WHERE url = n.url AND p_id ISNULL) AS most_recent_expired_visit
+          FROM expiration_notify n
           GROUP BY url`,
     actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN_DIRTY |
              ACTION.IDLE_DIRTY | ACTION.IDLE_DAILY | ACTION.DEBUG
   },
 
   // Empty the notifications table.
   QUERY_DELETE_NOTIFICATIONS: {
     sql: "DELETE FROM expiration_notify",
@@ -639,19 +641,31 @@ nsPlacesExpiration.prototype = {
         this._expectedResultsCount = row.getResultByName("expected_results");
       if (this._expectedResultsCount > 0)
         this._expectedResultsCount--;
 
       let uri = Services.io.newURI(row.getResultByName("url"), null, null);
       let guid = row.getResultByName("guid");
       let visitDate = row.getResultByName("visit_date");
       let wholeEntry = row.getResultByName("whole_entry");
+      let mostRecentExpiredVisit = row.getResultByName("most_recent_expired_visit");
       let reason = Ci.nsINavHistoryObserver.REASON_EXPIRED;
       let observers = PlacesUtils.history.getObservers();
 
+      if (mostRecentExpiredVisit) {
+        try {
+          let days = parseInt((Date.now() - (mostRecentExpiredVisit / 1000)) / MSECS_PER_DAY);
+          Services.telemetry
+                  .getHistogramById("PLACES_MOST_RECENT_EXPIRED_VISIT_DAYS")
+                  .add(days);
+        } catch (ex) {
+          Components.utils.reportError("Unable to report telemetry.");
+        }
+      }
+
       // Dispatch expiration notifications to history.
       if (wholeEntry) {
         notify(observers, "onDeleteURI", [uri, guid, reason]);
       } else {
         notify(observers, "onDeleteVisits", [uri, visitDate, guid, reason, 0]);
       }
     }
   },
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3235,16 +3235,25 @@
     "expires_in_version": "never",
     "kind": "exponential",
     "low": 1000,
     "high": "150000",
     "n_buckets": 20,
     "releaseChannelCollection": "opt-out",
     "description": "PLACES: Number of unique pages"
   },
+  "PLACES_MOST_RECENT_EXPIRED_VISIT_DAYS": {
+    "alert_emails": ["mbonardo@mozilla.com"],
+    "expires_in_version": "never",
+    "kind": "linear",
+    "low": 30,
+    "high": 730,
+    "n_buckets": 12,
+    "description": "PLACES: the most recent expired visit in days"
+  },
   "PLACES_BOOKMARKS_COUNT": {
     "expires_in_version": "never",
     "kind": "exponential",
     "low": 100,
     "high": "8000",
     "n_buckets": 15,
     "releaseChannelCollection": "opt-out",
     "description": "PLACES: Number of bookmarks"