--- a/devtools/client/accessibility/accessibility-panel.js
+++ b/devtools/client/accessibility/accessibility-panel.js
@@ -158,17 +158,17 @@ AccessibilityPanel.prototype = {
},
selectAccessible(accessibleFront) {
this.postContentMessage("selectAccessible", this._walker, accessibleFront);
},
selectAccessibleForNode(nodeFront, reason) {
if (reason) {
- this._telemetry.logKeyedScalar(
+ this._telemetry.keyedScalarAdd(
"devtools.accessibility.select_accessible_for_node", reason, 1);
}
this.postContentMessage("selectNodeAccessible", this._walker, nodeFront);
},
highlightAccessible(accessibleFront) {
this.postContentMessage("highlightAccessible", this._walker, accessibleFront);
--- a/devtools/client/accessibility/components/Description.js
+++ b/devtools/client/accessibility/components/Description.js
@@ -66,17 +66,17 @@ class Description extends Component {
this.onCanBeEnabledChange);
}
onEnable() {
let { accessibility, dispatch } = this.props;
this.setState({ enabling: true });
if (gTelemetry) {
- gTelemetry.logCountScalar(A11Y_SERVICE_ENABLED_COUNT, 1);
+ gTelemetry.scalarAdd(A11Y_SERVICE_ENABLED_COUNT, 1);
}
dispatch(enable(accessibility))
.then(() => this.setState({ enabling: false }))
.catch(() => this.setState({ enabling: false }));
}
onCanBeEnabledChange(canBeEnabled) {
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -502,17 +502,17 @@ DevTools.prototype = {
* Indicates the time at which the user event related to the toolbox
* opening started. This is a `Cu.now()` timing.
*/
logToolboxOpenTime(toolId, startTime) {
let delay = Cu.now() - startTime;
let telemetryKey = this._firstShowToolbox ?
"DEVTOOLS_COLD_TOOLBOX_OPEN_DELAY_MS" : "DEVTOOLS_WARM_TOOLBOX_OPEN_DELAY_MS";
- this._telemetry.logKeyed(telemetryKey, toolId, delay);
+ this._telemetry.getKeyedHistogramById(telemetryKey).add(toolId, delay);
this._telemetry.addEventProperty(
"devtools.main", "open", "tools", null, "first_panel",
this.makeToolIdHumanReadable(toolId));
},
makeToolIdHumanReadable(toolId) {
if (/^[0-9a-fA-F]{40}_temporary-addon/.test(toolId)) {
--- a/devtools/client/framework/toolbox-tabs-order-manager.js
+++ b/devtools/client/framework/toolbox-tabs-order-manager.js
@@ -139,17 +139,17 @@ class ToolboxTabsOrderManager {
.filter(definition => !tabs.some(tab => tab.dataset.id === definition.id))
.map(definition => definition.extensionId || definition.id);
const pref = tabIds.concat(overflowedTabIds).join(",");
Services.prefs.setCharPref(PREFERENCE_NAME, pref);
// Log which tabs reordered. The question we want to answer is:
// "How frequently are the tabs re-ordered, also which tabs get re-ordered?"
const toolId = this.dragTarget.dataset.extensionId || this.dragTarget.dataset.id;
- this.telemetry.logKeyedScalar(TABS_REORDERED_SCALAR, toolId, 1);
+ this.telemetry.keyedScalarAdd(TABS_REORDERED_SCALAR, toolId, 1);
}
this.dragTarget.ownerDocument.removeEventListener("mousemove", this.onMouseMove);
this.dragTarget.ownerDocument.removeEventListener("mouseout", this.onMouseOut);
this.dragTarget.ownerDocument.removeEventListener("mouseup", this.onMouseUp);
this.toolboxContainerElement.classList.remove("tabs-reordering");
this.dragTarget.style.left = null;
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -714,22 +714,22 @@ Toolbox.prototype = {
}
},
_pingTelemetry: function() {
this.telemetry.toolOpened("toolbox");
this.telemetry.logOncePerBrowserVersion(SCREENSIZE_HISTOGRAM,
system.getScreenDimensions());
- this.telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
+ this.telemetry.getHistogramById(HOST_HISTOGRAM).add(this._getTelemetryHostId());
// Log current theme. The question we want to answer is:
// "What proportion of users use which themes?"
let currentTheme = Services.prefs.getCharPref("devtools.theme");
- this.telemetry.logKeyedScalar(CURRENT_THEME_SCALAR, currentTheme, 1);
+ this.telemetry.keyedScalarAdd(CURRENT_THEME_SCALAR, currentTheme, 1);
this.telemetry.preparePendingEvent(
"devtools.main", "open", "tools", null,
["entrypoint", "first_panel", "host", "splitconsole", "width"]
);
this.telemetry.addEventProperty(
"devtools.main", "open", "tools", null, "host", this._getTelemetryHostString()
);
@@ -2128,18 +2128,17 @@ Toolbox.prototype = {
// Ignore the timing if the panel is still loading
if (!panel) {
return;
}
await panel.once("reloaded");
let delay = this.win.performance.now() - start;
let telemetryKey = "DEVTOOLS_TOOLBOX_PAGE_RELOAD_DELAY_MS";
- let histogram = Services.telemetry.getKeyedHistogramById(telemetryKey);
- histogram.add(toolId, delay);
+ this.telemetry.getKeyedHistogramById(telemetryKey).add(toolId, delay);
},
/**
* Refresh the host's title.
*/
_refreshHostTitle: function() {
let title;
if (this.target.name && this.target.name != this.target.url) {
@@ -2464,17 +2463,17 @@ Toolbox.prototype = {
this._buildDockOptions();
this._addKeysToWindow();
// We blurred the tools at start of switchHost, but also when clicking on
// host switching button. We now have to restore the focus.
this.focusTool(this.currentToolId, true);
this.emit("host-changed");
- this.telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
+ this.telemetry.getHistogramById(HOST_HISTOGRAM).add(this._getTelemetryHostId());
this.component.setCurrentHostType(hostType);
},
/**
* Test the availability of a tool (both globally registered tools and
* additional tools registered to this toolbox) by tool id.
*
--- a/devtools/client/inspector/grids/grid-inspector.js
+++ b/devtools/client/inspector/grids/grid-inspector.js
@@ -260,17 +260,17 @@ class GridInspector {
// This call might fail if called asynchrously after the toolbox is finished
// closing.
return;
}
// Log how many CSS Grid elements DevTools sees.
if (gridFronts.length > 0 &&
currentUrl != this.inspector.previousURL) {
- this.telemetry.log(CSS_GRID_COUNT_HISTOGRAM_ID, gridFronts.length);
+ this.telemetry.getHistogramById(CSS_GRID_COUNT_HISTOGRAM_ID).add(gridFronts.length);
this.inspector.previousURL = currentUrl;
}
let grids = [];
for (let i = 0; i < gridFronts.length; i++) {
let grid = gridFronts[i];
let nodeFront = grid.containerNodeFront;
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -269,17 +269,17 @@ Inspector.prototype = {
// Accessibility panel initializes the Inspector.
if (this.show3PaneTooltip && this.toolbox.currentToolId === "inspector") {
this.threePaneTooltip = new ThreePaneOnboardingTooltip(this.toolbox, this.panelDoc);
}
// Log the 3 pane inspector setting on inspector open. The question we want to answer
// is:
// "What proportion of users use the 3 pane vs 2 pane inspector on inspector open?"
- this.telemetry.logKeyedScalar(THREE_PANE_ENABLED_SCALAR, this.is3PaneModeEnabled, 1);
+ this.telemetry.keyedScalarAdd(THREE_PANE_ENABLED_SCALAR, this.is3PaneModeEnabled, 1);
this.emit("ready");
return this;
},
_onBeforeNavigate: function() {
this._defaultNode = null;
this.selection.setNodeFront(null);
@@ -2132,45 +2132,45 @@ Inspector.prototype = {
/**
* Copy a unique selector of the selected Node to the clipboard.
*/
copyUniqueSelector: function() {
if (!this.selection.isNode()) {
return;
}
- this.telemetry.logScalar("devtools.copy.unique.css.selector.opened", 1);
+ this.telemetry.scalarSet("devtools.copy.unique.css.selector.opened", 1);
this.selection.nodeFront.getUniqueSelector().then(selector => {
clipboardHelper.copyString(selector);
}).catch(console.error);
},
/**
* Copy the full CSS Path of the selected Node to the clipboard.
*/
copyCssPath: function() {
if (!this.selection.isNode()) {
return;
}
- this.telemetry.logScalar("devtools.copy.full.css.selector.opened", 1);
+ this.telemetry.scalarSet("devtools.copy.full.css.selector.opened", 1);
this.selection.nodeFront.getCssPath().then(path => {
clipboardHelper.copyString(path);
}).catch(console.error);
},
/**
* Copy the XPath of the selected Node to the clipboard.
*/
copyXPath: function() {
if (!this.selection.isNode()) {
return;
}
- this.telemetry.logScalar("devtools.copy.xpath.opened", 1);
+ this.telemetry.scalarSet("devtools.copy.xpath.opened", 1);
this.selection.nodeFront.getXPath().then(path => {
clipboardHelper.copyString(path);
}).catch(console.error);
},
/**
* Initiate gcli screenshot command on selected node.
*/
--- a/devtools/client/performance/modules/logic/telemetry.js
+++ b/devtools/client/performance/modules/logic/telemetry.js
@@ -1,15 +1,14 @@
/* 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 Telemetry = require("devtools/client/shared/telemetry");
-const flags = require("devtools/shared/flags");
const EVENTS = require("devtools/client/performance/events");
const EVENT_MAP_FLAGS = new Map([
[EVENTS.RECORDING_IMPORTED, "DEVTOOLS_PERFTOOLS_RECORDING_IMPORT_FLAG"],
[EVENTS.RECORDING_EXPORTED, "DEVTOOLS_PERFTOOLS_RECORDING_EXPORT_FLAG"],
]);
const RECORDING_FEATURES = [
@@ -26,20 +25,16 @@ function PerformanceTelemetry(emitter) {
this.onViewSelected = this.onViewSelected.bind(this);
for (let [event] of EVENT_MAP_FLAGS) {
this._emitter.on(event, this.onFlagEvent.bind(this, event));
}
this._emitter.on(EVENTS.RECORDING_STATE_CHANGE, this.onRecordingStateChange);
this._emitter.on(EVENTS.UI_DETAILS_VIEW_SELECTED, this.onViewSelected);
-
- if (flags.testing) {
- this.recordLogs();
- }
}
PerformanceTelemetry.prototype.destroy = function() {
if (this._previousView) {
this._telemetry.stopTimer(SELECTED_VIEW_HISTOGRAM_NAME, this._previousView);
}
this._telemetry.destroy();
@@ -47,76 +42,46 @@ PerformanceTelemetry.prototype.destroy =
this._emitter.off(event, this.onFlagEvent);
}
this._emitter.off(EVENTS.RECORDING_STATE_CHANGE, this.onRecordingStateChange);
this._emitter.off(EVENTS.UI_DETAILS_VIEW_SELECTED, this.onViewSelected);
this._emitter = null;
};
PerformanceTelemetry.prototype.onFlagEvent = function(eventName, ...data) {
- this._telemetry.log(EVENT_MAP_FLAGS.get(eventName), true);
+ this._telemetry.getHistogramById(EVENT_MAP_FLAGS.get(eventName)).add(true);
};
PerformanceTelemetry.prototype.onRecordingStateChange = function(status, model) {
if (status != "recording-stopped") {
return;
}
if (model.isConsole()) {
- this._telemetry.log("DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT", true);
+ this._telemetry.getHistogramById("DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT")
+ .add(true);
} else {
- this._telemetry.log("DEVTOOLS_PERFTOOLS_RECORDING_COUNT", true);
+ this._telemetry.getHistogramById("DEVTOOLS_PERFTOOLS_RECORDING_COUNT")
+ .add(true);
}
- this._telemetry.log("DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS", model.getDuration());
+ this._telemetry.getHistogramById("DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS")
+ .add(model.getDuration());
let config = model.getConfiguration();
for (let k in config) {
if (RECORDING_FEATURES.includes(k)) {
- this._telemetry.logKeyed("DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", k,
- config[k]);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED")
+ .add(k, config[k]);
}
}
};
PerformanceTelemetry.prototype.onViewSelected = function(viewName) {
if (this._previousView) {
this._telemetry.stopTimer(SELECTED_VIEW_HISTOGRAM_NAME, this._previousView);
}
this._previousView = viewName;
this._telemetry.startTimer(SELECTED_VIEW_HISTOGRAM_NAME);
};
-/**
- * Utility to record histogram calls to this instance.
- * Should only be used in testing mode; throws otherwise.
- */
-PerformanceTelemetry.prototype.recordLogs = function() {
- if (!flags.testing) {
- throw new Error("Can only record telemetry logs in tests.");
- }
-
- let originalLog = this._telemetry.log;
- let originalLogKeyed = this._telemetry.logKeyed;
- this._log = {};
-
- this._telemetry.log = (histo, data) => {
- let results = this._log[histo] = this._log[histo] || [];
- results.push(data);
- originalLog(histo, data);
- };
-
- this._telemetry.logKeyed = (histo, key, data) => {
- let results = this._log[histo] = this._log[histo] || [];
- results.push([key, data]);
- originalLogKeyed(histo, key, data);
- };
-};
-
-PerformanceTelemetry.prototype.getLogs = function() {
- if (!flags.testing) {
- throw new Error("Can only get telemetry logs in tests.");
- }
-
- return this._log;
-};
-
exports.PerformanceTelemetry = PerformanceTelemetry;
--- a/devtools/client/shared/telemetry.js
+++ b/devtools/client/shared/telemetry.js
@@ -18,20 +18,21 @@ const TOOLS_OPENED_PREF = "devtools.tele
const PENDING_EVENTS = new Map();
const PENDING_EVENT_PROPERTIES = new Map();
class Telemetry {
constructor() {
// Bind pretty much all functions so that callers do not need to.
this.toolOpened = this.toolOpened.bind(this);
this.toolClosed = this.toolClosed.bind(this);
- this.log = this.log.bind(this);
- this.logScalar = this.logScalar.bind(this);
- this.logCountScalar = this.logCountScalar.bind(this);
- this.logKeyedScalar = this.logKeyedScalar.bind(this);
+ this.getHistogramById = this.getHistogramById.bind(this);
+ this.getKeyedHistogramById = this.getKeyedHistogramById.bind(this);
+ this.scalarSet = this.scalarSet.bind(this);
+ this.scalarAdd = this.scalarAdd.bind(this);
+ this.keyedScalarAdd = this.keyedScalarAdd.bind(this);
this.logOncePerBrowserVersion = this.logOncePerBrowserVersion.bind(this);
this.recordEvent = this.recordEvent.bind(this);
this.setEventRecordingEnabled = this.setEventRecordingEnabled.bind(this);
this.preparePendingEvent = this.preparePendingEvent.bind(this);
this.addEventProperty = this.addEventProperty.bind(this);
this.destroy = this.destroy.bind(this);
this._timers = new Map();
@@ -201,26 +202,26 @@ class Telemetry {
* @param {String} id
* Used to look up the relevant histogram ID and log true to that
* histogram.
*/
toolOpened(id) {
let charts = this.histograms[id] || this.histograms.custom;
if (charts.histogram) {
- this.log(charts.histogram, true);
+ this.getHistogramById(charts.histogram).add(true);
}
if (charts.timerHistogram) {
this.startTimer(charts.timerHistogram);
}
if (charts.scalar) {
- this.logScalar(charts.scalar, 1);
+ this.scalarSet(charts.scalar, 1);
}
if (charts.countScalar) {
- this.logCountScalar(charts.countScalar, 1);
+ this.scalarAdd(charts.countScalar, 1);
}
}
/**
* Record that an action occurred. Aliases to `toolOpened`, so it's just for
* readability at the call site for cases where we aren't actually opening
* tools.
*/
@@ -256,56 +257,80 @@ class Telemetry {
* @param String key [optional]
* Optional key for a keyed histogram.
*/
stopTimer(histogramId, key) {
let startTime = this._timers.get(histogramId);
if (startTime) {
let time = (new Date() - startTime) / 1000;
if (!key) {
- this.log(histogramId, time);
+ this.getHistogramById(histogramId).add(time);
} else {
- this.logKeyed(histogramId, key, time);
+ this.getKeyedHistogramById(histogramId).add(key, time);
}
this._timers.delete(histogramId);
}
}
/**
* Log a value to a histogram.
*
* @param {String} histogramId
* Histogram in which the data is to be stored.
- * @param value
- * Value to store.
*/
- log(histogramId, value) {
- if (!histogramId) {
- return;
+ getHistogramById(histogramId) {
+ let histogram = null;
+
+ if (histogramId) {
+ try {
+ histogram = Services.telemetry.getHistogramById(histogramId);
+ } catch (e) {
+ dump(`Warning: An attempt was made to write to the ${histogramId} ` +
+ `histogram, which is not defined in Histograms.json\n` +
+ `CALLER: ${this.getCaller()}`);
+ }
}
- try {
- let histogram = Services.telemetry.getHistogramById(histogramId);
- histogram.add(value);
- } catch (e) {
- dump(`Warning: An attempt was made to write to the ${histogramId} ` +
- `histogram, which is not defined in Histograms.json\n` +
- `CALLER: ${this.getCaller()}`);
+ return histogram || {
+ add: () => {}
+ };
+ }
+
+ /**
+ * Get a keyed histogram.
+ *
+ * @param {String} histogramId
+ * Histogram in which the data is to be stored.
+ */
+ getKeyedHistogramById(histogramId) {
+ let histogram = null;
+
+ if (histogramId) {
+ try {
+ histogram = Services.telemetry.getKeyedHistogramById(histogramId);
+ } catch (e) {
+ dump(`Warning: An attempt was made to write to the ${histogramId} ` +
+ `histogram, which is not defined in Histograms.json\n` +
+ `CALLER: ${this.getCaller()}`);
+ }
}
+ return histogram || {
+ add: () => {}
+ };
}
/**
* Log a value to a scalar.
*
* @param {String} scalarId
* Scalar in which the data is to be stored.
* @param value
* Value to store.
*/
- logScalar(scalarId, value) {
+ scalarSet(scalarId, value) {
if (!scalarId) {
return;
}
try {
if (isNaN(value) && typeof value !== "boolean") {
dump(`Warning: An attempt was made to write a non-numeric and ` +
`non-boolean value ${value} to the ${scalarId} scalar. Only ` +
@@ -325,17 +350,17 @@ class Telemetry {
/**
* Log a value to a count scalar.
*
* @param {String} scalarId
* Scalar in which the data is to be stored.
* @param value
* Value to store.
*/
- logCountScalar(scalarId, value) {
+ scalarAdd(scalarId, value) {
if (!scalarId) {
return;
}
try {
if (isNaN(value)) {
dump(`Warning: An attempt was made to write a non-numeric value ` +
`${value} to the ${scalarId} scalar. Only numeric values are ` +
@@ -357,17 +382,17 @@ class Telemetry {
*
* @param {String} scalarId
* Scalar in which the data is to be stored.
* @param {String} key
* The key within the scalar.
* @param value
* Value to store.
*/
- logKeyedScalar(scalarId, key, value) {
+ keyedScalarAdd(scalarId, key, value) {
if (!scalarId) {
return;
}
try {
if (isNaN(value)) {
dump(`Warning: An attempt was made to write a non-numeric value ` +
`${value} to the ${scalarId} scalar. Only numeric values are ` +
@@ -380,44 +405,16 @@ class Telemetry {
} catch (e) {
dump(`Warning: An attempt was made to write to the ${scalarId} ` +
`scalar, which is not defined in Scalars.yaml\n` +
`CALLER: ${this.getCaller()}`);
}
}
/**
- * Log a value to a keyed histogram.
- *
- * @param {String} histogramId
- * Histogram in which the data is to be stored.
- * @param {String} key
- * The key within the single histogram.
- * @param [value]
- * Optional value to store.
- */
- logKeyed(histogramId, key, value) {
- if (histogramId) {
- try {
- let histogram = Services.telemetry.getKeyedHistogramById(histogramId);
-
- if (typeof value === "undefined") {
- histogram.add(key);
- } else {
- histogram.add(key, value);
- }
- } catch (e) {
- dump(`Warning: An attempt was made to write to the ${histogramId} ` +
- `histogram, which is not defined in Histograms.json\n` +
- `CALLER: ${this.getCaller()}`);
- }
- }
- }
-
- /**
* Log info about usage once per browser version. This allows us to discover
* how many individual users are using our tools for each browser version.
*
* @param {String} perUserHistogram
* Histogram in which the data is to be stored.
*/
logOncePerBrowserVersion(perUserHistogram, value) {
let currentVersion = Services.appinfo.version;
@@ -426,17 +423,17 @@ class Telemetry {
let lastVersionHistogramUpdated = latestObj[perUserHistogram];
if (typeof lastVersionHistogramUpdated == "undefined" ||
lastVersionHistogramUpdated !== currentVersion) {
latestObj[perUserHistogram] = currentVersion;
latest = JSON.stringify(latestObj);
Services.prefs.setCharPref(TOOLS_OPENED_PREF, latest);
- this.log(perUserHistogram, value);
+ this.getHistogramById(perUserHistogram).add(value);
}
}
/**
* Event telemetry is disabled by default. Use this method to enable it for
* a particular category.
*
* @param {String} category
@@ -581,16 +578,43 @@ class Telemetry {
*/
addEventProperties(category, method, object, value, pendingObject) {
for (let [key, val] of Object.entries(pendingObject)) {
this.addEventProperty(category, method, object, value, key, val);
}
}
/**
+ * A private method that is not to be used externally. This method is used to
+ * prepare a pending telemetry event for sending and then send it via
+ * recordEvent().
+ *
+ * @param {String} category
+ * The telemetry event category (a group name for events and helps to
+ * avoid name conflicts) e.g. "devtools.main"
+ * @param {String} method
+ * The telemetry event method (describes the type of event that
+ * occurred e.g. "open")
+ * @param {String} object
+ * The telemetry event object name (the name of the object the event
+ * occurred on) e.g. "tools" or "setting"
+ * @param {String|null} value
+ * The telemetry event value (a user defined value, providing context
+ * for the event) e.g. "console"
+ */
+ _sendPendingEvent(category, method, object, value) {
+ const sig = `${category},${method},${object},${value}`;
+ const { extra } = PENDING_EVENTS.get(sig);
+
+ PENDING_EVENTS.delete(sig);
+ PENDING_EVENT_PROPERTIES.delete(sig);
+ this.recordEvent(category, method, object, value, extra);
+ }
+
+ /**
* Send a telemetry event.
*
* @param {String} category
* The telemetry event category (a group name for events and helps to
* avoid name conflicts) e.g. "devtools.main"
* @param {String} method
* The telemetry event method (describes the type of event that
* occurred e.g. "open")
@@ -623,43 +647,16 @@ class Telemetry {
`of 80 characters\n` +
`CALLER: ${this.getCaller()}`);
}
}
Services.telemetry.recordEvent(category, method, object, value, extra);
}
/**
- * A private method that is not to be used externally. This method is used to
- * prepare a pending telemetry event for sending and then send it via
- * recordEvent().
- *
- * @param {String} category
- * The telemetry event category (a group name for events and helps to
- * avoid name conflicts) e.g. "devtools.main"
- * @param {String} method
- * The telemetry event method (describes the type of event that
- * occurred e.g. "open")
- * @param {String} object
- * The telemetry event object name (the name of the object the event
- * occurred on) e.g. "tools" or "setting"
- * @param {String|null} value
- * The telemetry event value (a user defined value, providing context
- * for the event) e.g. "console"
- */
- _sendPendingEvent(category, method, object, value) {
- const sig = `${category},${method},${object},${value}`;
- const { extra } = PENDING_EVENTS.get(sig);
-
- PENDING_EVENTS.delete(sig);
- PENDING_EVENT_PROPERTIES.delete(sig);
- this.recordEvent(category, method, object, value, extra);
- }
-
- /**
* Displays the first caller and calling line outside of this file in the
* event of an error. This is the line that made the call that produced the
* error.
*/
getCaller() {
return getNthPathExcluding(0, "/telemetry.js");
}
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -534,17 +534,17 @@ var UI = {
this.logActionState(action, false);
}
this._actionsToLog.clear();
},
logActionState: function(action, state) {
let histogramId = "DEVTOOLS_WEBIDE_CONNECTION_" +
action.toUpperCase() + "_USED";
- this._telemetry.log(histogramId, state);
+ this._telemetry.getHistogramById(histogramId).add(state);
},
/** ******** PROJECTS **********/
openProject: function() {
let project = AppManager.selectedProject;
if (!project) {
--- a/devtools/client/webide/modules/app-manager.js
+++ b/devtools/client/webide/modules/app-manager.js
@@ -430,20 +430,21 @@ var AppManager = exports.AppManager = {
} catch (e) {
reject(e);
}
}, reject);
});
// Record connection result in telemetry
let logResult = result => {
- this._telemetry.log("DEVTOOLS_WEBIDE_CONNECTION_RESULT", result);
+ this._telemetry.getHistogramById("DEVTOOLS_WEBIDE_CONNECTION_RESULT")
+ .add(result);
if (runtime.type) {
- this._telemetry.log("DEVTOOLS_WEBIDE_" + runtime.type +
- "_CONNECTION_RESULT", result);
+ this._telemetry.getHistogramById(
+ `DEVTOOLS_WEBIDE_${runtime.type}_CONNECTION_RESULT`).add(result);
}
};
deferred.then(() => logResult(true), () => logResult(false));
// If successful, record connection time in telemetry
deferred.then(() => {
const timerId = "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS";
this._telemetry.startTimer(timerId);
@@ -459,35 +460,42 @@ var AppManager = exports.AppManager = {
return deferred;
},
async _recordRuntimeInfo() {
if (!this.connected) {
return;
}
let runtime = this.selectedRuntime;
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE",
- runtime.type || "UNKNOWN", true);
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID",
- runtime.id || "unknown", true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_TYPE")
+ .add(runtime.type || "UNKNOWN", true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_ID")
+ .add(runtime.id || "unknown", true);
if (!this.deviceFront) {
this.update("runtime-telemetry");
return;
}
let d = await this.deviceFront.getDescription();
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PROCESSOR",
- d.processor, true);
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_OS",
- d.os, true);
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PLATFORM_VERSION",
- d.platformversion, true);
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_APP_TYPE",
- d.apptype, true);
- this._telemetry.logKeyed("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_VERSION",
- d.version, true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PROCESSOR")
+ .add(d.processor, true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_OS")
+ .add(d.os, true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_PLATFORM_VERSION")
+ .add(d.platformversion, true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_APP_TYPE")
+ .add(d.apptype, true);
+ this._telemetry
+ .getKeyedHistogramById("DEVTOOLS_WEBIDE_CONNECTED_RUNTIME_VERSION")
+ .add(d.version, true);
this.update("runtime-telemetry");
},
isMainProcessDebuggable: function() {
// Fx <39 exposes chrome tab actors on RootActor
// Fx >=39 exposes a dedicated actor via getProcess request
return this.connection.client &&
this.connection.client.mainRoot &&
--- a/devtools/shared/gcli/source/lib/gcli/mozui/inputter.js
+++ b/devtools/shared/gcli/source/lib/gcli/mozui/inputter.js
@@ -559,17 +559,18 @@ Inputter.prototype._handleDownArrow = fu
*/
Inputter.prototype._handleReturn = function() {
// Deny RETURN unless the command might work
if (this.requisition.status === Status.VALID) {
this._scrollingThroughHistory = false;
this.history.add(this.element.value);
let name = this.requisition.commandAssignment.value.name;
- this._telemetry.logKeyed("DEVTOOLS_GCLI_COMMANDS_KEYED", name);
+ this._telemetry.getKeyedHistogramById("DEVTOOLS_GCLI_COMMANDS_KEYED")
+ .add(name);
return this.requisition.exec().then(() => {
this.textChanged();
});
}
// If we can't execute the command, but there is a menu choice to use
// then use it.
--- a/devtools/startup/devtools-startup.js
+++ b/devtools/startup/devtools-startup.js
@@ -330,17 +330,17 @@ DevToolsStartup.prototype = {
pingOnboardingTelemetry() {
// Only ping telemetry once per profile.
let alreadyLoggedPref = "devtools.onboarding.telemetry.logged";
if (Services.prefs.getBoolPref(alreadyLoggedPref)) {
return;
}
let scalarId = "devtools.onboarding.is_devtools_user";
- this.telemetry.logScalar(scalarId, this.isDevToolsUser());
+ this.telemetry.scalarSet(scalarId, this.isDevToolsUser());
Services.prefs.setBoolPref(alreadyLoggedPref, true);
},
/**
* Register listeners to all possible entry points for Developer Tools.
* But instead of implementing the actual actions, defer to DevTools codebase.
* In most cases, it only needs to call this.initDevTools which handles the rest.
* We do that to prevent loading any DevTools module until the user intent to use them.
@@ -856,17 +856,17 @@ DevToolsStartup.prototype = {
if (this.recorded) {
return;
}
// Only save the first call for each firefox run as next call
// won't necessarely start the tool. For example key shortcuts may
// only change the currently selected tool.
try {
- this.telemetry.log("DEVTOOLS_ENTRY_POINT", reason);
+ this.telemetry.getHistogramById("DEVTOOLS_ENTRY_POINT").add(reason);
} catch (e) {
dump("DevTools telemetry entry point failed: " + e + "\n");
}
this.recorded = true;
},
// Used by tests and the toolbox to register the same key shortcuts in toolboxes loaded
// in a window window.