diff options
Diffstat (limited to 'devtools/client/performance/modules/logic/telemetry.js')
-rw-r--r-- | devtools/client/performance/modules/logic/telemetry.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/devtools/client/performance/modules/logic/telemetry.js b/devtools/client/performance/modules/logic/telemetry.js new file mode 100644 index 000000000..b8e322170 --- /dev/null +++ b/devtools/client/performance/modules/logic/telemetry.js @@ -0,0 +1,122 @@ +/* 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 = [ + "withMarkers", "withTicks", "withMemory", "withAllocations" +]; + +const SELECTED_VIEW_HISTOGRAM_NAME = "DEVTOOLS_PERFTOOLS_SELECTED_VIEW_MS"; + +function PerformanceTelemetry(emitter) { + this._emitter = emitter; + this._telemetry = new Telemetry(); + this.onFlagEvent = this.onFlagEvent.bind(this); + this.onRecordingStateChange = this.onRecordingStateChange.bind(this); + this.onViewSelected = this.onViewSelected.bind(this); + + for (let [event] of EVENT_MAP_FLAGS) { + this._emitter.on(event, this.onFlagEvent); + } + + 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(); + for (let [event] of EVENT_MAP_FLAGS) { + 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); +}; + +PerformanceTelemetry.prototype.onRecordingStateChange = function (_, status, model) { + if (status != "recording-stopped") { + return; + } + + if (model.isConsole()) { + this._telemetry.log("DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT", true); + } else { + this._telemetry.log("DEVTOOLS_PERFTOOLS_RECORDING_COUNT", true); + } + + this._telemetry.log("DEVTOOLS_PERFTOOLS_RECORDING_DURATION_MS", model.getDuration()); + + let config = model.getConfiguration(); + for (let k in config) { + if (RECORDING_FEATURES.indexOf(k) !== -1) { + this._telemetry.logKeyed("DEVTOOLS_PERFTOOLS_RECORDING_FEATURES_USED", 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 = (function (histo, data) { + let results = this._log[histo] = this._log[histo] || []; + results.push(data); + originalLog(histo, data); + }).bind(this); + + this._telemetry.logKeyed = (function (histo, key, data) { + let results = this._log[histo] = this._log[histo] || []; + results.push([key, data]); + originalLogKeyed(histo, key, data); + }).bind(this); +}; + +PerformanceTelemetry.prototype.getLogs = function () { + if (!flags.testing) { + throw new Error("Can only get telemetry logs in tests."); + } + + return this._log; +}; + +exports.PerformanceTelemetry = PerformanceTelemetry; |