Bug 1198517 - [Metrics] Histogram support for user-timing-based metrics. r=janx
authorRuss Nicoletti <rnicoletti@mozilla.com>
Tue, 08 Sep 2015 13:11:46 -0700
changeset 295079 96d8527b59959a62c4c6ad5808a355d88f929392
parent 295078 df8915b9f1a4dc830020fa4e131a4cc5231c3907
child 295080 6eb3079ebf28f3cac694e6642d1accf48b8b9c54
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanx
bugs1198517
milestone43.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 1198517 - [Metrics] Histogram support for user-timing-based metrics. r=janx
b2g/chrome/content/devtools/hud.js
b2g/chrome/content/settings.js
modules/libpref/init/all.js
toolkit/components/telemetry/Histograms.json
--- a/b2g/chrome/content/devtools/hud.js
+++ b/b2g/chrome/content/devtools/hud.js
@@ -760,66 +760,100 @@ developerHUD.registerWatcher(eventLoopLa
  * to the app-launch epoch and emits an "app-start-time-<performance mark name>"
  * event containing the delta.
  */
 let performanceEntriesWatcher = {
   _client: null,
   _fronts: new Map(),
   _appLaunchName: null,
   _appLaunchStartTime: null,
+  _supported: [
+    'contentInteractive',
+    'navigationInteractive',
+    'navigationLoaded',
+    'visuallyLoaded',
+    'fullyLoaded',
+    'mediaEnumerated',
+    'scanEnd'
+  ],
 
   init(client) {
     this._client = client;
+    let setting = 'devtools.telemetry.supported_performance_marks';
+    let defaultValue = this._supported.join(',');
+
+    SettingsListener.observe(setting, defaultValue, supported => {
+      let value = supported || defaultValue;
+      this._supported = value.split(',');
+    });
   },
 
   trackTarget(target) {
     // The performanceEntries watcher doesn't register a metric because
     // currently the metrics generated are not displayed in
     // in the front-end.
 
     let front = new PerformanceEntriesFront(this._client, target.actor);
     this._fronts.set(target, front);
 
     // User timings are always gathered; there is no setting to enable/
     // disable.
     front.start();
 
     front.on('entry', detail => {
-      if (detail.type === 'mark') {
-        let name = detail.name;
-        let epoch = detail.epoch;
+
+      // Only process performance marks.
+      if (detail.type !== 'mark') {
+        return;
+      }
+
+      let name = detail.name;
+      let epoch = detail.epoch;
+
+      // FIXME There is a potential race condition that can result
+      // in some performance entries being disregarded. See bug 1189942.
+      //
+      // If this is an "app launch" mark, record the app that was
+      // launched and the epoch of when it was launched.
+      if (name.indexOf('appLaunch') !== -1) {
         let CHARS_UNTIL_APP_NAME = 7; // '@app://'
+        let startPos = name.indexOf('@app') + CHARS_UNTIL_APP_NAME;
+        let endPos = name.indexOf('.');
+        this._appLaunchName = name.slice(startPos, endPos);
+        this._appLaunchStartTime = epoch;
+        return;
+      }
 
-        // FIXME There is a potential race condition that can result
-        // in some performance entries being disregarded. See bug 1189942.
-        if (name.indexOf('appLaunch') != -1) {
-          let appStartPos = name.indexOf('@app') + CHARS_UNTIL_APP_NAME;
-          let length = (name.indexOf('.') - appStartPos);
-          this._appLaunchName = name.substr(appStartPos, length);
-          this._appLaunchStartTime = epoch;
-        } else {
-          let origin = detail.origin;
-          origin = origin.substr(0, origin.indexOf('.'));
-          if (this._appLaunchName === origin) {
-            let time = epoch - this._appLaunchStartTime;
-            let eventName = 'app-startup-time-' + name;
+      // Only process supported performance marks
+      if (this._supported.indexOf(name) === -1) {
+        return;
+      }
+
+      let origin = detail.origin;
+      origin = origin.slice(0, origin.indexOf('.'));
+
+      // Continue if the performance mark corresponds to the app
+      // for which we have recorded app launch information.
+      if (this._appLaunchName !== origin) {
+        return;
+      }
 
-            // Events based on performance marks are for telemetry only, they are
-            // not displayed in the HUD front end.
-            target._logHistogram({name: eventName, value: time});
+      let time = epoch - this._appLaunchStartTime;
+      let eventName = 'app_startup_time_' + name;
+
+      // Events based on performance marks are for telemetry only, they are
+      // not displayed in the HUD front end.
+      target._logHistogram({name: eventName, value: time});
 
-            memoryWatcher.front(target).residentUnique().then(value => {
-              eventName = 'app-memory-' + name;
-              target._logHistogram({name: eventName, value: value});
-            }, err => {
-              console.error(err);
-            });
-          }
-        }
-      }
+      memoryWatcher.front(target).residentUnique().then(value => {
+        eventName = 'app_memory_' + name;
+        target._logHistogram({name: eventName, value: value});
+      }, err => {
+        console.error(err);
+      });
     });
   },
 
   untrackTarget(target) {
     let fronts = this._fronts;
     if (fronts.has(target)) {
       fronts.get(target).destroy();
       fronts.delete(target);
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -568,16 +568,20 @@ let settingsToObserve = {
   'devtools.discovery.device': {
     prefName: 'dom.presentation.device.name',
     defaultValue: 'Firefox OS'
   },
   'devtools.eventlooplag.threshold': 100,
   'devtools.remote.wifi.visible': {
     resetToPref: true
   },
+  'devtools.telemetry.supported_performance_marks': {
+    resetToPref: true
+  },
+
   'dom.mozApps.use_reviewer_certs': false,
   'dom.mozApps.signed_apps_installable_from': 'https://marketplace.firefox.com',
   'dom.presentation.discovery.enabled': false,
   'dom.presentation.discoverable': false,
   'dom.serviceWorkers.interception.enabled': true,
   'dom.serviceWorkers.testing.enabled': false,
   'gfx.layerscope.enabled': false,
   'layers.draw-borders': false,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -895,16 +895,19 @@ pref("devtools.gcli.underscoreSrc", "htt
 // Set imgur upload client ID
 pref("devtools.gcli.imgurClientID", '0df414e888d7240');
 // Imgur's upload URL
 pref("devtools.gcli.imgurUploadURL", "https://api.imgur.com/3/image");
 
 // GCLI commands directory
 pref("devtools.commands.dir", "");
 
+// Allows setting the performance marks for which telemetry metrics will be recorded.
+pref("devtools.telemetry.supported_performance_marks", "contentInteractive,navigationInteractive,navigationLoaded,visuallyLoaded,fullyLoaded,mediaEnumerated,scanEnd");
+
 // view source
 pref("view_source.syntax_highlight", true);
 pref("view_source.wrap_long_lines", false);
 pref("view_source.editor.external", false);
 pref("view_source.editor.path", "");
 // allows to add further arguments to the editor; use the %LINE% placeholder
 // for jumping to a specific line (e.g. "/line:%LINE%" or "--goto %LINE%")
 pref("view_source.editor.args", "");
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -8885,16 +8885,135 @@
     "description": "Number of errors, keyed by appName."
   },
   "DEVTOOLS_HUD_WARNINGS": {
     "expires_in_version": "never",
     "kind": "count",
     "keyed": "true",
     "description": "Number of warnings, keyed by appName."
   },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_CONTENTINTERACTIVE": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'contentInteractive' performance mark, keyed by appName.",
+    "high": "2000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONINTERACTIVE": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'navigationInteractive' performance mark, keyed by appName.",
+    "high": "3000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_NAVIGATIONLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'navigationLoaded' performance mark, keyed by appName.",
+    "high": "4000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_VISUALLYLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'visuallyLoaded' performance mark, keyed by appName.",
+    "high": "5000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_MEDIAENUMERATED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'mediaEnumerated' performance mark, keyed by appName.",
+    "high": "5000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_FULLYLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'fullyLoaded' performance mark, keyed by appName.",
+    "high": "30000",
+    "n_buckets": 30
+  },
+  "DEVTOOLS_HUD_APP_STARTUP_TIME_SCANEND": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The duration in ms between application launch and the 'scanEnd' performance mark, keyed by appName.",
+    "high": "30000",
+    "n_buckets": 30
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_CONTENTINTERACTIVE": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'contentInteractive' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "3000000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONINTERACTIVE": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'navigationInteractive' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "3000000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_NAVIGATIONLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'navigationLoaded' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "3000000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_VISUALLYLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'visuallyLoaded' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "3000000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_MEDIAENUMERATED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'mediaEnumerated' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "3000000",
+    "n_buckets": 10
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_FULLYLOADED": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'fullyLoaded' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "4000000",
+    "n_buckets": 20
+  },
+  "DEVTOOLS_HUD_APP_MEMORY_SCANEND": {
+    "expires_in_version": "never",
+    "kind": "linear",
+    "keyed": "true",
+    "description": "The USS memory consumed by an application at the time of the 'scanEnd' performance mark, keyed by appName.",
+    "low": "2000000",
+    "high": "4000000",
+    "n_buckets": 20
+  },
   "GRAPHICS_SANITY_TEST_REASON": {
     "alert_emails": ["danderson@mozilla.com"],
     "expires_in_version": "43",
     "kind": "enumerated",
     "n_values": 20,
     "releaseChannelCollection": "opt-out",
     "description": "Reports why a graphics sanity test was run. 0=First Run, 1=App Updated, 2=Device Change, 3=Driver Change."
   },