Bug 1463095 - Instrument inspection of filter changes in the Web Console with event telemetry
There are also a couple of telemetry.md changes that are not worth splitting out into a different bug.
MozReview-Commit-ID: JyzQs4NDe3j
--- a/devtools/client/webconsole/actions/filters.js
+++ b/devtools/client/webconsole/actions/filters.js
@@ -2,16 +2,18 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { getAllFilters } = require("devtools/client/webconsole/selectors/filters");
+const Telemetry = require("devtools/client/shared/telemetry");
+const telemetry = new Telemetry();
const {
FILTER_TEXT_SET,
FILTER_TOGGLE,
FILTERS_CLEAR,
DEFAULT_FILTERS_RESET,
PREFS,
FILTERS,
@@ -20,24 +22,36 @@ const {
function filterTextSet(text) {
return {
type: FILTER_TEXT_SET,
text
};
}
-function filterToggle(filter) {
+function filterToggle(filter, sessionId) {
return (dispatch, getState, {prefsService}) => {
dispatch({
type: FILTER_TOGGLE,
filter,
});
const filterState = getAllFilters(getState());
- prefsService.setBoolPref(PREFS.FILTER[filter.toUpperCase()], filterState[filter]);
+ const state = filterState[filter];
+ const active = Object.keys(filterState)
+ .filter(key => key !== "text" ? filterState[key] : "");
+ const inactive = Object.keys(filterState)
+ .filter(key => key !== "text" ? !filterState[key] : "");
+
+ telemetry.recordEvent("devtools.main", "filter_changed", "webconsole", null, {
+ "clicked": filter,
+ "active": active.join(","),
+ "inactive": inactive.join(","),
+ "session_id": sessionId
+ });
+ prefsService.setBoolPref(PREFS.FILTER[filter.toUpperCase()], state);
};
}
function filtersClear() {
return (dispatch, getState, {prefsService}) => {
dispatch({
type: FILTERS_CLEAR,
});
--- a/devtools/client/webconsole/components/FilterButton.js
+++ b/devtools/client/webconsole/components/FilterButton.js
@@ -24,15 +24,22 @@ function FilterButton(props) {
];
if (active) {
classList.push("checked");
}
return dom.button({
"aria-pressed": active === true,
className: classList.join(" "),
- onClick: () => {
- dispatch(actions.filterToggle(filterKey));
+ onClick: event => {
+ const frame = event.target.ownerGlobal.frameElement;
+ let sessionId = -1;
+
+ if (frame && frame.ownerGlobal.frameElement) {
+ sessionId = frame.ownerGlobal.frameElement.getAttribute("session_id");
+ }
+
+ dispatch(actions.filterToggle(filterKey, sessionId));
},
}, label);
}
module.exports = FilterButton;
--- a/devtools/client/webconsole/test/mochitest/browser_console_filters.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_filters.js
@@ -4,18 +4,43 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Check that the Browser Console does not use the same filter prefs as the Web
// Console.
"use strict";
const TEST_URI = "data:text/html;charset=utf8,<p>browser console filters";
+const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
+
+// We only go though the filterClicked() code path once in this test but that is
+// enough to test the telemetry event.
+const DATA = [
+ {
+ timestamp: null,
+ category: "devtools.main",
+ method: "filter_changed",
+ object: "webconsole",
+ value: null,
+ extra: {
+ clicked: "error",
+ active: "warn,log,info,debug",
+ inactive: "error,css,net,netxhr"
+ }
+ }
+];
add_task(async function() {
+ // Let's reset the counts.
+ Services.telemetry.clearEvents();
+
+ // Ensure no events have been logged
+ const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
+ ok(!snapshot.parent, "No events have been logged for the main process");
+
let hud = await openNewTabAndConsole(TEST_URI);
ok(hud, "web console opened");
let filterState = await getFilterState(hud);
ok(filterState.error, "The web console error filter is enabled");
info(`toggle "error" filter`);
await setFilterState(hud, {
@@ -41,9 +66,36 @@ add_task(async function() {
error: false
});
filterState = await getFilterState(hud);
ok(!filterState.error, "The browser console error filter is disabled");
await resetFilters(hud);
await setFilterBarVisible(hud, false);
+
+ checkResults();
});
+
+function checkResults() {
+ const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
+ const events = snapshot.parent.filter(event => event[1] === "devtools.main" &&
+ event[2] === "filter_changed" &&
+ event[3] === "webconsole" &&
+ event[4] === null
+ );
+
+ for (const i in DATA) {
+ const [ timestamp, category, method, object, value, extra ] = events[i];
+ const expected = DATA[i];
+
+ // ignore timestamp
+ ok(timestamp > 0, "timestamp is greater than 0");
+ is(category, expected.category, "category is correct");
+ is(method, expected.method, "method is correct");
+ is(object, expected.object, "object is correct");
+ is(value, expected.value, "value is correct");
+
+ is(extra.clicked, expected.extra.clicked, "clicked is correct");
+ is(extra.inactive, expected.extra.inactive, "inactive is correct");
+ is(extra.active, expected.extra.active, "active is correct");
+ }
+}
--- a/devtools/docs/frontend/telemetry.md
+++ b/devtools/docs/frontend/telemetry.md
@@ -103,17 +103,17 @@ devtools.copy.unique.css.selector:
- dev-developer-tools@lists.mozilla.org
release_channel_collection: opt-out
record_in_processes:
- 'main'
```
### Adding probes to `Events.yaml`
-Our entries are prefixed with `devtools.`. For example:
+Our entries are prefixed with `devtools.` and must contain a session_id key. For example:
```yaml
devtools.main:
open:
objects: ["tools"]
bug_numbers: [1416024]
notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
record_in_processes: ["main"]
@@ -121,16 +121,17 @@ devtools.main:
release_channel_collection: opt-out
expiry_version: never
extra_keys:
entrypoint: How was the toolbox opened? CommandLine, ContextMenu, DeveloperToolbar, HamburgerMenu, KeyShortcut, SessionRestore or SystemMenu
first_panel: The name of the first panel opened.
host: "Toolbox host (positioning): bottom, side, window or other."
splitconsole: Indicates whether the split console was open.
width: Toolbox width (px).
+ session_id: The toolbox session start time e.g. 13963. This must be read using toolbox.sessionId.
```
### 2. Using Histograms.json probes in DevTools code
Once the probe has been declared in the `Histograms.json` file, you'll need to actually use it in our code.
First, you need to give it an id in `devtools/client/shared/telemetry.js`. Similarly to the `Histograms.json` case, you'll want to follow the style of existing entries. For example:
@@ -393,17 +394,17 @@ async function openAndCloseToolbox(toolI
function checkResults() {
const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
const events = snapshot.parent.filter(event => event[1] === "devtools.main" &&
event[2] === "close" &&
event[3] === "tools" &&
event[4] === null
);
- for (let i in DATA) {
+ for (const i in DATA) {
const [ timestamp, category, method, object, value, extra ] = events[i];
const expected = DATA[i];
// ignore timestamp
ok(timestamp > 0, "timestamp is greater than 0");
is(category, expected.category, "category is correct");
is(method, expected.method, "method is correct");
is(object, expected.object, "object is correct");
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -603,8 +603,21 @@ devtools.main:
bug_numbers: [1463092]
notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
record_in_processes: ["main"]
description: User has clicked a link to a source file in the web console.
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.
+ filter_changed:
+ objects: ["webconsole"]
+ bug_numbers: [1463095]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User has changed a filter in the web console.
+ release_channel_collection: opt-out
+ expiry_version: never
+ extra_keys:
+ clicked: "The clicked filter: error, warn, log, info, debug, css, netxhr or net"
+ active: Comma separated list of active filters.
+ inactive: Comma separated list of inactive filters.
+ session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.