Bug 1549970 - Record telemetry events for about:debugging connection attempts r=daisuke,janerik
authorJulian Descottes <jdescottes@mozilla.com>
Mon, 13 May 2019 12:02:40 +0000
changeset 535482 1abd79d8d7da4aa6d94fb1ac3fbbe137fbc18edd
parent 535481 1983145fd5e53c8d355ca980131fc0c2f6552bf0
child 535483 c2c7d0b11f1365b96292f925ba1a24270d0b819c
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdaisuke, janerik
bugs1549970
milestone68.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 1549970 - Record telemetry events for about:debugging connection attempts r=daisuke,janerik Differential Revision: https://phabricator.services.mozilla.com/D30373
devtools/client/aboutdebugging-new/src/actions/runtimes.js
devtools/client/aboutdebugging-new/src/middleware/event-recording.js
devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates.js
devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates_network.js
toolkit/components/telemetry/Events.yaml
--- a/devtools/client/aboutdebugging-new/src/actions/runtimes.js
+++ b/devtools/client/aboutdebugging-new/src/actions/runtimes.js
@@ -81,40 +81,43 @@ function onRemoteDebuggerClientClosed() 
   window.AboutDebugging.onUSBRuntimesUpdated();
 }
 
 function onMultiE10sUpdated() {
   window.AboutDebugging.store.dispatch(updateMultiE10s());
 }
 
 function connectRuntime(id) {
+  // Create a random connection id to track the connection attempt in telemetry.
+  const connectionId = (Math.random() * 100000) | 0;
+
   return async (dispatch, getState) => {
-    dispatch({ type: CONNECT_RUNTIME_START, id });
+    dispatch({ type: CONNECT_RUNTIME_START, connectionId, id });
 
     // The preferences test-connection-timing-out-delay and test-connection-cancel-delay
     // don't have a default value but will be overridden during our tests.
     const connectionTimingOutDelay = Services.prefs.getIntPref(
       "devtools.aboutdebugging.test-connection-timing-out-delay",
       CONNECTION_TIMING_OUT_DELAY);
     const connectionCancelDelay = Services.prefs.getIntPref(
       "devtools.aboutdebugging.test-connection-cancel-delay", CONNECTION_CANCEL_DELAY);
 
     const connectionNotRespondingTimer = setTimeout(() => {
       // If connecting to the runtime takes time over CONNECTION_TIMING_OUT_DELAY,
       // we assume the connection prompt is showing on the runtime, show a dialog
       // to let user know that.
-      dispatch({ type: CONNECT_RUNTIME_NOT_RESPONDING, id });
+      dispatch({ type: CONNECT_RUNTIME_NOT_RESPONDING, connectionId, id });
     }, connectionTimingOutDelay);
     const connectionCancelTimer = setTimeout(() => {
       // Connect button of the runtime will be disabled during connection, but the status
       // continues till the connection was either succeed or failed. This may have a
       // possibility that the disabling continues unless page reloading, user will not be
       // able to click again. To avoid this, revert the connect button status after
       // CONNECTION_CANCEL_DELAY ms.
-      dispatch({ type: CONNECT_RUNTIME_CANCEL, id });
+      dispatch({ type: CONNECT_RUNTIME_CANCEL, connectionId, id });
     }, connectionCancelDelay);
 
     try {
       const runtime = findRuntimeById(id, getState().runtimes);
       const clientWrapper = await createClientForRuntime(runtime);
 
       const deviceDescription = await clientWrapper.getDeviceDescription();
       const compatibilityReport = await clientWrapper.checkVersionCompatibility();
@@ -178,24 +181,25 @@ function connectRuntime(id) {
       if (runtime.type !== RUNTIMES.THIS_FIREFOX) {
         // `closed` event will be emitted when disabling remote debugging
         // on the connected remote runtime.
         clientWrapper.addOneTimeListener("closed", onRemoteDebuggerClientClosed);
       }
 
       dispatch({
         type: CONNECT_RUNTIME_SUCCESS,
+        connectionId,
         runtime: {
           id,
           runtimeDetails,
           type: runtime.type,
         },
       });
     } catch (e) {
-      dispatch({ type: CONNECT_RUNTIME_FAILURE, id, error: e });
+      dispatch({ type: CONNECT_RUNTIME_FAILURE, connectionId, id, error: e });
     } finally {
       clearTimeout(connectionNotRespondingTimer);
       clearTimeout(connectionCancelTimer);
     }
   };
 }
 
 function createThisFirefoxRuntime() {
--- a/devtools/client/aboutdebugging-new/src/middleware/event-recording.js
+++ b/devtools/client/aboutdebugging-new/src/middleware/event-recording.js
@@ -5,16 +5,20 @@
 "use strict";
 
 const Telemetry = require("devtools/client/shared/telemetry");
 loader.lazyGetter(this, "telemetry", () => new Telemetry());
 // This is a unique id that should be submitted with all about:debugging events.
 loader.lazyGetter(this, "sessionId", () => parseInt(telemetry.msSinceProcessStart(), 10));
 
 const {
+  CONNECT_RUNTIME_CANCEL,
+  CONNECT_RUNTIME_FAILURE,
+  CONNECT_RUNTIME_NOT_RESPONDING,
+  CONNECT_RUNTIME_START,
   CONNECT_RUNTIME_SUCCESS,
   DISCONNECT_RUNTIME_SUCCESS,
   REMOTE_RUNTIMES_UPDATED,
   RUNTIMES,
   SELECT_PAGE_SUCCESS,
   SHOW_PROFILER_DIALOG,
   TELEMETRY_RECORD,
   UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS,
@@ -141,23 +145,51 @@ function onRemoteRuntimesUpdated(action,
       recordEvent("device_added", {
         "connection_type": action.runtimeType,
         "device_name": newDeviceName,
       });
     }
   }
 }
 
+function recordConnectionAttempt(connectionId, runtimeId, status, store) {
+  const runtime = findRuntimeById(runtimeId, store.getState().runtimes);
+  if (runtime.type === RUNTIMES.THIS_FIREFOX) {
+    // Only record connection_attempt events for remote runtimes.
+    return;
+  }
+
+  recordEvent("connection_attempt", {
+    "connection_id": connectionId,
+    "connection_type": runtime.type,
+    "runtime_id": getTelemetryRuntimeId(runtimeId),
+    "status": status,
+  });
+}
+
 /**
  * This middleware will record events to telemetry for some specific actions.
  */
 function eventRecordingMiddleware(store) {
   return next => action => {
     switch (action.type) {
+      case CONNECT_RUNTIME_CANCEL:
+        recordConnectionAttempt(action.connectionId, action.id, "cancelled", store);
+        break;
+      case CONNECT_RUNTIME_FAILURE:
+        recordConnectionAttempt(action.connectionId, action.id, "failed", store);
+        break;
+      case CONNECT_RUNTIME_NOT_RESPONDING:
+        recordConnectionAttempt(action.connectionId, action.id, "not responding", store);
+        break;
+      case CONNECT_RUNTIME_START:
+        recordConnectionAttempt(action.connectionId, action.id, "start", store);
+        break;
       case CONNECT_RUNTIME_SUCCESS:
+        recordConnectionAttempt(action.connectionId, action.runtime.id, "success", store);
         onConnectRuntimeSuccess(action, store);
         break;
       case DISCONNECT_RUNTIME_SUCCESS:
         onDisconnectRuntimeSuccess(action, store);
         break;
       case REMOTE_RUNTIMES_UPDATED:
         onRemoteRuntimesUpdated(action, store);
         break;
--- a/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates.js
+++ b/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates.js
@@ -72,16 +72,18 @@ add_task(async function testUsbRuntimeUp
   const runtime1ConnectedExtras = Object.assign({}, runtime1Extras, {
     "runtime_name": USB_RUNTIME_1.name,
   });
 
   await connectToRuntime(USB_RUNTIME_1.deviceName, document);
 
   checkTelemetryEvents([
     { method: "runtime_connected", extras: runtime1ConnectedExtras },
+    { method: "connection_attempt", extras: { status: "start" } },
+    { method: "connection_attempt", extras: { status: "success" } },
   ], sessionId);
 
   info("Add a second runtime");
   await addUsbRuntime(USB_RUNTIME_2, mocks, document);
   evts = checkTelemetryEvents([
     { method: "runtime_added", extras: RUNTIME_2_EXTRAS },
   ], sessionId);
 
--- a/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates_network.js
+++ b/devtools/client/aboutdebugging-new/test/browser/browser_aboutdebugging_telemetry_runtime_updates_network.js
@@ -45,16 +45,18 @@ add_task(async function testNetworkRunti
   // device_added event.
   checkTelemetryEvents([
     { method: "runtime_added", extras: networkRuntimeExtras },
   ], sessionId);
 
   await connectToRuntime(NETWORK_RUNTIME.host, document);
   checkTelemetryEvents([
     { method: "runtime_connected", extras: connectedNetworkRuntimeExtras },
+    { method: "connection_attempt", extras: { status: "start" } },
+    { method: "connection_attempt", extras: { status: "success" } },
   ], sessionId);
 
   info("Remove network runtime");
   mocks.removeRuntime(NETWORK_RUNTIME.host);
   await waitUntil(() => !findSidebarItemByText(NETWORK_RUNTIME.host, document));
   // Similarly we should not have any device removed event.
   checkTelemetryEvents([
     { method: "runtime_disconnected", extras: connectedNetworkRuntimeExtras },
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -586,16 +586,30 @@ devtools.main:
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User closes about:debugging.
     release_channel_collection: opt-out
     expiry_version: never
     extra_keys:
       width: Toolbox width rounded up to the nearest 50px.
       session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
+  connection_attempt:
+    objects: ["aboutdebugging"]
+    bug_numbers: [1549970]
+    notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+    record_in_processes: ["main"]
+    description: User is trying to connect to a remote runtime.
+    release_channel_collection: opt-out
+    expiry_version: never
+    extra_keys:
+      connection_id: Randomly generated id to keep to group various events related to the same connection attempt.
+      connection_type: Connection type
+      runtime_id: Random id generated to track events related to a single runtime
+      status: One of (cancelled, failed, not responding, start, success).
+      session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
   continue:
     objects: ["debugger"]
     bug_numbers: [1463122]
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User has pressed the continue button on a paused script.
     release_channel_collection: opt-out
     expiry_version: never
@@ -821,17 +835,17 @@ devtools.main:
     objects: ["netmonitor", "webconsole"]
     bug_numbers: [1531395, 1542312]
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User has changed log persist status.
     release_channel_collection: opt-out
     expiry_version: never
     extra_keys:
-      session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.   
+      session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
   pretty_print:
     objects: ["debugger"]
     bug_numbers: [1463125]
     notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
     record_in_processes: ["main"]
     description: User clicked the pretty print button to pretty print a script.
     release_channel_collection: opt-out
     expiry_version: never