Bug 1127918 - Record & submit the appropriate telemetry datasets when FHR is enabled. r=vladan
authorAlessio Placitelli <alessio.placitelli@gmail.com>
Mon, 09 Mar 2015 00:53:00 +0100
changeset 266015 386d8cc19d8d4ce51262cdb8e397325a6de13d0f
parent 266014 135c75e6fa1eb65189ebbebddffc5654b4d67c38
child 266016 c2ada63128e0ef31b14518de2051daa8c0c9da0d
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan
bugs1127918
milestone39.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 1127918 - Record & submit the appropriate telemetry datasets when FHR is enabled. r=vladan
toolkit/components/telemetry/TelemetrySession.jsm
toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -833,26 +833,24 @@ let Impl = {
 
     // Look for app-specific timestamps
     var appTimestamps = {};
     try {
       let o = {};
       Cu.import("resource://gre/modules/TelemetryTimestamps.jsm", o);
       appTimestamps = o.TelemetryTimestamps.get();
     } catch (ex) {}
-    try {
-      if (!IS_CONTENT_PROCESS) {
+
+    // Only submit this if the extended set is enabled.
+    if (!IS_CONTENT_PROCESS && Telemetry.canRecordExtended) {
+      try {
         ret.addonManager = AddonManagerPrivate.getSimpleMeasures();
-      }
-    } catch (ex) {}
-    try {
-      if (!IS_CONTENT_PROCESS) {
         ret.UITelemetry = UITelemetry.getSimpleMeasures();
-      }
-    } catch (ex) {}
+      } catch (ex) {}
+    }
 
     if (si.process) {
       for each (let field in Object.keys(si)) {
         if (field == "process")
           continue;
         ret[field] = si[field] - si.process
       }
 
@@ -979,21 +977,30 @@ let Impl = {
     }
 
     // add an upper bound
     if (last && last < c.length)
       retgram.values[r[last]] = 0;
     return retgram;
   },
 
+  /**
+   * Get the type of the dataset that needs to be collected, based on the preferences.
+   * @return {Integer} A value from nsITelemetry.DATASET_*.
+   */
+  getDatasetType: function() {
+    return Telemetry.canRecordExtended ? Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN
+                                       : Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
+  },
+
   getHistograms: function getHistograms(subsession, clearSubsession) {
     this._log.trace("getHistograms - subsession: " + subsession + ", clearSubsession: " + clearSubsession);
 
     let registered =
-      Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, []);
+      Telemetry.registeredHistograms(this.getDatasetType(), []);
     let hls = subsession ? Telemetry.snapshotSubsessionHistograms(clearSubsession)
                          : Telemetry.histogramSnapshots;
     let ret = {};
 
     for (let name of registered) {
       for (let n of [name, "STARTUP_" + name]) {
         if (n in hls) {
           ret[n] = this.packHistogram(hls[n]);
@@ -1022,17 +1029,17 @@ let Impl = {
 
     return ret;
   },
 
   getKeyedHistograms: function(subsession, clearSubsession) {
     this._log.trace("getKeyedHistograms - subsession: " + subsession + ", clearSubsession: " + clearSubsession);
 
     let registered =
-      Telemetry.registeredKeyedHistograms(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, []);
+      Telemetry.registeredKeyedHistograms(this.getDatasetType(), []);
     let ret = {};
 
     for (let id of registered) {
       ret[id] = {};
       let keyed = Telemetry.getKeyedHistogramById(id);
       let snapshot = null;
       if (subsession) {
         snapshot = clearSubsession ? keyed.snapshotSubsessionAndClear()
@@ -1110,16 +1117,21 @@ let Impl = {
 
     return ret;
   },
 
   /**
    * Pull values from about:memory into corresponding histograms
    */
   gatherMemory: function gatherMemory() {
+    if (!Telemetry.canRecordExtended) {
+      this._log.trace("gatherMemory - Extended data recording disabled, skipping.");
+      return;
+    }
+
     this._log.trace("gatherMemory");
 
     let mgr;
     try {
       mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
             getService(Ci.nsIMemoryReporterManager);
     } catch (e) {
       // OK to skip memory reporters in xpcshell
@@ -1237,17 +1249,17 @@ let Impl = {
 
   /**
    * Make a copy of interesting histograms at startup.
    */
   gatherStartupHistograms: function gatherStartupHistograms() {
     this._log.trace("gatherStartupHistograms");
 
     let info =
-      Telemetry.registeredHistograms(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, []);
+      Telemetry.registeredHistograms(this.getDatasetType(), []);
     let snapshots = Telemetry.histogramSnapshots;
     for (let name of info) {
       // Only duplicate histograms with actual data.
       if (this.isInterestingStartupHistogram(name) && name in snapshots) {
         Telemetry.histogramFrom("STARTUP_" + name, name);
       }
     }
   },
@@ -1269,38 +1281,46 @@ let Impl = {
                     ", submitting subsession data: " + isSubsession);
 
     // Payload common to chrome and content processes.
     let payloadObj = {
       ver: PAYLOAD_VERSION,
       simpleMeasurements: simpleMeasurements,
       histograms: this.getHistograms(isSubsession, clearSubsession),
       keyedHistograms: this.getKeyedHistograms(isSubsession, clearSubsession),
-      chromeHangs: Telemetry.chromeHangs,
-      threadHangStats: this.getThreadHangStats(Telemetry.threadHangStats),
-      log: TelemetryLog.entries(),
     };
 
+    // Add extended set measurements common to chrome & content processes
+    if (Telemetry.canRecordExtended) {
+      payloadObj.chromeHangs = Telemetry.chromeHangs;
+      payloadObj.threadHangStats = this.getThreadHangStats(Telemetry.threadHangStats);
+      payloadObj.log = TelemetryLog.entries();
+    }
+
     if (IS_CONTENT_PROCESS) {
       return payloadObj;
     }
 
     // Additional payload for chrome process.
     payloadObj.info = info;
-    payloadObj.slowSQL = Telemetry.slowSQL;
-    payloadObj.fileIOReports = Telemetry.fileIOReports;
-    payloadObj.lateWrites = Telemetry.lateWrites;
-    payloadObj.addonHistograms = this.getAddonHistograms();
-    payloadObj.addonDetails = AddonManagerPrivate.getTelemetryDetails();
-    payloadObj.UIMeasurements = UITelemetry.getUIMeasurements();
 
-    if (Object.keys(this._slowSQLStartup).length != 0 &&
-        (Object.keys(this._slowSQLStartup.mainThread).length ||
-         Object.keys(this._slowSQLStartup.otherThreads).length)) {
-      payloadObj.slowSQLStartup = this._slowSQLStartup;
+    // Add extended set measurements for chrome process.
+    if (Telemetry.canRecordExtended) {
+      payloadObj.slowSQL = Telemetry.slowSQL;
+      payloadObj.fileIOReports = Telemetry.fileIOReports;
+      payloadObj.lateWrites = Telemetry.lateWrites;
+      payloadObj.addonHistograms = this.getAddonHistograms();
+      payloadObj.addonDetails = AddonManagerPrivate.getTelemetryDetails();
+      payloadObj.UIMeasurements = UITelemetry.getUIMeasurements();
+
+      if (Object.keys(this._slowSQLStartup).length != 0 &&
+          (Object.keys(this._slowSQLStartup.mainThread).length ||
+           Object.keys(this._slowSQLStartup.otherThreads).length)) {
+        payloadObj.slowSQLStartup = this._slowSQLStartup;
+      }
     }
 
     if (this._childTelemetry.length) {
       payloadObj.childPayloads = this.getChildPayloads();
     }
 
     return payloadObj;
   },
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
@@ -1498,16 +1498,71 @@ add_task(function* test_schedulerNothing
   yield schedulerTickCallback();
 
   // Check that no aborted session ping was written to disk.
   Assert.ok(!(yield OS.File.exists(ABORTED_FILE)));
 
   yield TelemetrySession.shutdown();
 });
 
+add_task(function* test_pingExtendedStats() {
+  const EXTENDED_PAYLOAD_FIELDS = [
+    "chromeHangs", "threadHangStats", "log", "slowSQL", "fileIOReports", "lateWrites",
+    "addonHistograms", "addonDetails", "UIMeasurements",
+  ];
+
+  // Disable sending extended statistics.
+  Telemetry.canRecordExtended = false;
+
+  gRequestIterator = Iterator(new Request());
+  yield TelemetrySession.reset();
+  yield sendPing();
+
+  let request = yield gRequestIterator.next();
+  let ping = decodeRequestPayload(request);
+  checkPingFormat(ping, PING_TYPE_MAIN, true, true);
+
+  // Check that the payload does not contain extended statistics fields.
+  for (let f in EXTENDED_PAYLOAD_FIELDS) {
+    Assert.ok(!(EXTENDED_PAYLOAD_FIELDS[f] in ping.payload),
+              EXTENDED_PAYLOAD_FIELDS[f] + " must not be in the payload if the extended set is off.");
+  }
+
+  // We check this one separately so that we can reuse EXTENDED_PAYLOAD_FIELDS below, since
+  // slowSQLStartup might not be there.
+  Assert.ok(!("slowSQLStartup" in ping.payload),
+            "slowSQLStartup must not be sent if the extended set is off");
+
+  Assert.ok(!("addonManager" in ping.payload.simpleMeasurements),
+            "addonManager must not be sent if the extended set is off.");
+  Assert.ok(!("UITelemetry" in ping.payload.simpleMeasurements),
+            "UITelemetry must not be sent if the extended set is off.");
+
+  // Restore the preference.
+  Telemetry.canRecordExtended = true;
+
+  // Send a new ping that should contain the extended data.
+  yield TelemetrySession.reset();
+  yield sendPing();
+  request = yield gRequestIterator.next();
+  ping = decodeRequestPayload(request);
+  checkPingFormat(ping, PING_TYPE_MAIN, true, true);
+
+  // Check that the payload now contains extended statistics fields.
+  for (let f in EXTENDED_PAYLOAD_FIELDS) {
+    Assert.ok(EXTENDED_PAYLOAD_FIELDS[f] in ping.payload,
+              EXTENDED_PAYLOAD_FIELDS[f] + " must be in the payload if the extended set is on.");
+  }
+
+  Assert.ok("addonManager" in ping.payload.simpleMeasurements,
+            "addonManager must be sent if the extended set is on.");
+  Assert.ok("UITelemetry" in ping.payload.simpleMeasurements,
+            "UITelemetry must be sent if the extended set is on.");
+});
+
 add_task(function* stopServer(){
   gHttpServer.stop(do_test_finished);
 });
 
 // An iterable sequence of http requests
 function Request() {
   let defers = [];
   let current = 0;