Bug 1483817 - Font Inspector telemetry needs more granular OS versioning r=gl

- Added test to `devtools/client/inspector/test/browser_inspector_sidebarstate.js`.
- Added the OS and build number to the `devtools.main::sidepanel_changed` event.
- Created an `osNameAndVersion` getter inside `telemetry.js` because this can be useful whenever an OS supports new features.
- Log the `devtools.main::tool_timer` event from `telemetry.toolOpened` and `telemetry.toolClosed` for the animation inspector, computed view, font inspector, layout view and rule view.
- Updated the `telemetry.md` document because there is little point in breaking that change out to another bug.
- Added the devtools.main::tool_timer event to Events.yaml.

Differential Revision: https://phabricator.services.mozilla.com/D3982

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Michael Ratcliffe 2018-08-23 19:48:17 +00:00
parent 587291095f
commit 231e09d925
5 changed files with 150 additions and 13 deletions

View file

@ -5,8 +5,49 @@
const TEST_URI = "data:text/html;charset=UTF-8," +
"<h1>browser_inspector_sidebarstate.js</h1>";
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
const TELEMETRY_DATA = [
{
timestamp: null,
category: "devtools.main",
method: "tool_timer",
object: "computedview",
value: null,
extra: {
time_open: ""
}
},
{
timestamp: null,
category: "devtools.main",
method: "tool_timer",
object: "layoutview",
value: null,
extra: {
time_open: ""
}
},
{
timestamp: null,
category: "devtools.main",
method: "tool_timer",
object: "ruleview",
value: null,
extra: {
time_open: ""
}
}
];
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 { inspector, toolbox } = await openInspectorForURL(TEST_URI);
info("Selecting computed view.");
@ -34,4 +75,26 @@ add_task(async function() {
is(inspector.sidebar.getCurrentTabID(), "layoutview",
"Layout view is selected by default.");
checkTelemetryResults();
});
function checkTelemetryResults() {
const snapshot = Services.telemetry.snapshotEvents(OPTOUT, true);
const events = snapshot.parent.filter(event => event[1] === "devtools.main" &&
event[2] === "tool_timer"
);
for (const i in TELEMETRY_DATA) {
const [ timestamp, category, method, object, value, extra ] = events[i];
const expected = TELEMETRY_DATA[i];
// ignore timestamp
ok(timestamp > 0, "timestamp is greater than 0");
ok(extra.time_open > 0, "time_open 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");
}
}

View file

@ -335,15 +335,17 @@ ToolSidebar.prototype = {
currentToolId = this.getTelemetryPanelNameOrOther(currentToolId);
if (previousToolId) {
previousToolId = this.getTelemetryPanelNameOrOther(previousToolId);
const sessionId = this._toolPanel._toolbox.sessionId;
this._telemetry.toolClosed(previousToolId);
previousToolId = this.getTelemetryPanelNameOrOther(previousToolId);
this._telemetry.toolClosed(previousToolId, sessionId);
this._telemetry.recordEvent("devtools.main", "sidepanel_changed", "inspector", null,
{
"oldpanel": previousToolId,
"newpanel": currentToolId,
"session_id": this._toolPanel._toolbox.sessionId
"os": this._telemetry.osNameAndVersion,
"session_id": sessionId
}
);
}

View file

@ -13,6 +13,7 @@
const Services = require("Services");
const { TelemetryStopwatch } = require("resource://gre/modules/TelemetryStopwatch.jsm");
const { getNthPathExcluding } = require("devtools/shared/platform/stack");
const { TelemetryEnvironment } = require("resource://gre/modules/TelemetryEnvironment.jsm");
// Object to be shared among all instances.
const PENDING_EVENTS = new Map();
@ -36,6 +37,22 @@ class Telemetry {
this.toolClosed = this.toolClosed.bind(this);
}
get osNameAndVersion() {
const osInfo = TelemetryEnvironment.currentEnvironment.system.os;
if (!osInfo) {
return "Unknown OS";
}
let osVersion = `${osInfo.name} ${osInfo.version}`;
if (osInfo.windowsBuildNumber) {
osVersion += `.${osInfo.windowsBuildNumber}`;
}
return osVersion;
}
/**
* Time since the system wide epoch. This is not a monotonic timer but
* can be used across process boundaries.
@ -557,6 +574,19 @@ class Telemetry {
return;
}
if (charts.useTimedEvent) {
if (id === "newanimationinspector") {
id = "animationinspector";
}
this.preparePendingEvent("devtools.main", "tool_timer", id, null, [
"os",
"time_open",
"session_id"
]);
this.addEventProperty("devtools.main", "tool_timer", id, null,
"time_open", this.msSystemNow());
}
if (charts.timerHist) {
this.start(charts.timerHist, this);
}
@ -573,15 +603,38 @@ class Telemetry {
*
* @param {String} id
* The ID of the tool opened.
* @param {String} sessionId
* Optional toolbox session id used only when a tool's chart has a
* useTimedEvent property set to true.
*
* NOTE: This method is designed for tools that send multiple probes on open,
* one of those probes being a counter and the other a timer. If you
* only have one probe you should be using another method.
*/
toolClosed(id) {
toolClosed(id, sessionId) {
const charts = getChartsFromToolId(id);
if (charts && charts.timerHist) {
if (!charts) {
return;
}
if (charts.useTimedEvent) {
if (id === "newanimationinspector") {
id = "animationinspector";
}
const sig = `devtools.main,tool_timer,${id},null`;
const event = PENDING_EVENTS.get(sig);
const time = this.msSystemNow() - event.extra.time_open;
this.addEventProperties("devtools.main", "tool_timer", id, null, {
"time_open": time,
"os": this.osNameAndVersion,
"session_id": sessionId
});
}
if (charts.timerHist) {
this.finish(charts.timerHist, this);
}
}
@ -601,6 +654,7 @@ function getChartsFromToolId(id) {
const lowerCaseId = id.toLowerCase();
let useTimedEvent = null;
let timerHist = null;
let countHist = null;
let countScalar = null;
@ -616,24 +670,19 @@ function getChartsFromToolId(id) {
switch (id) {
case "ABOUTDEBUGGING":
case "ANIMATIONINSPECTOR":
case "BROWSERCONSOLE":
case "CANVASDEBUGGER":
case "COMPUTEDVIEW":
case "DEVELOPERTOOLBAR":
case "DOM":
case "FONTINSPECTOR":
case "INSPECTOR":
case "JSBROWSERDEBUGGER":
case "JSDEBUGGER":
case "JSPROFILER":
case "LAYOUTVIEW":
case "MEMORY":
case "NETMONITOR":
case "OPTIONS":
case "PAINTFLASHING":
case "RESPONSIVE":
case "RULEVIEW":
case "SCRATCHPAD":
case "SHADEREDITOR":
case "STORAGE":
@ -654,6 +703,15 @@ function getChartsFromToolId(id) {
timerHist = `DEVTOOLS_${id}_TIME_ACTIVE_SECONDS`;
countScalar = `devtools.accessibility.picker_used_count`;
break;
case "ANIMATIONINSPECTOR":
case "COMPUTEDVIEW":
case "FONTINSPECTOR":
case "LAYOUTVIEW":
case "RULEVIEW":
useTimedEvent = true;
timerHist = `DEVTOOLS_${id}_TIME_ACTIVE_SECONDS`;
countHist = `DEVTOOLS_${id}_OPENED_COUNT`;
break;
default:
timerHist = `DEVTOOLS_CUSTOM_TIME_ACTIVE_SECONDS`;
countHist = `DEVTOOLS_CUSTOM_OPENED_COUNT`;
@ -665,6 +723,7 @@ function getChartsFromToolId(id) {
}
return {
useTimedEvent: useTimedEvent,
timerHist: timerHist,
countHist: countHist,
countScalar: countScalar

View file

@ -342,7 +342,7 @@ const { Toolbox } = require("devtools/client/framework/toolbox");
const URL = "data:text/html;charset=utf8,browser_toolbox_telemetry_close.js";
const OPTOUT = Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTOUT;
const { SIDE, BOTTOM } = Toolbox.HostType;
const DATA = [
const TELEMETRY_DATA = [
{
timestamp: null,
category: "devtools.main",
@ -398,9 +398,9 @@ function checkResults() {
event[4] === null
);
for (let i in DATA) {
for (const i in TELEMETRY_DATA) {
const [ timestamp, category, method, object, value, extra ] = events[i];
const expected = DATA[i];
const expected = TELEMETRY_DATA[i];
// ignore timestamp
ok(timestamp > 0, "timestamp is greater than 0");

View file

@ -538,6 +538,7 @@ devtools.main:
extra_keys:
oldpanel: The panel the user is switching from
newpanel: The panel the user is switching to
os: The OS name and version e.g. "Linux 4.4.0-1014-aws", "Darwin 14.5.0", "Windows_NT 6.1.7601" or "Windows_NT 10.0.15063." This can be used to make sense of data when a feature is only available from a particular operating system build number.
session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
edit_resend:
objects: ["netmonitor"]
@ -688,3 +689,15 @@ devtools.main:
expiry_version: never
extra_keys:
session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.
tool_timer:
objects: ["animationinspector", "computedview", "fontinspector", "layoutview", "ruleview"]
bug_numbers: [1483817]
notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
record_in_processes: ["main"]
description: The amount of time a tool was opened for.
release_channel_collection: opt-out
expiry_version: never
extra_keys:
time_open: Time open.
os: The OS name and version e.g. "Linux 4.4.0-1014-aws", "Darwin 14.5.0", "Windows_NT 6.1.7601" or "Windows_NT 10.0.15063." This can be used to make sense of data when a feature is only available from a particular operating system build number.
session_id: The start time of the session in milliseconds since epoch (Unix Timestamp) e.g. 1396381378123.