Bug 1467091 - Track application panel events with EventTelemetry
Events tracked here:
- service worker debug (with duration)
- service worker start
- service worker unregister
- click on aboutdebugging link at bottom of sw list
- click on any help link
MozReview-Commit-ID: J2RYy6iHXw9
--- a/devtools/client/application/initializer.js
+++ b/devtools/client/application/initializer.js
@@ -14,16 +14,17 @@ const { createFactory } = require("devto
const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
const { L10nRegistry } = require("resource://gre/modules/L10nRegistry.jsm");
const Services = require("Services");
const { configureStore } = require("./src/create-store");
const actions = require("./src/actions/index");
+const Telemetry = require("devtools/client/shared/telemetry");
const App = createFactory(require("./src/components/App"));
/**
* Global Application object in this panel. This object is expected by panel.js and is
* called to start the UI for the panel.
*/
window.Application = {
@@ -33,17 +34,23 @@ window.Application = {
this.mount = document.querySelector("#mount");
this.toolbox = toolbox;
this.client = toolbox.target.client;
this.store = configureStore();
this.actions = bindActionCreators(actions, this.store.dispatch);
+ const telemetry = new Telemetry();
+
const serviceContainer = {
+ recordEvent(action, extras) {
+ telemetry.recordEvent("devtools.main", action, "application", null, extras);
+ },
+
selectTool(toolId) {
return toolbox.selectTool(toolId);
}
};
this.client.addListener("workerListChanged", this.updateWorkers);
this.client.addListener("serviceWorkerRegistrationListChanged", this.updateWorkers);
this.client.addListener("registration-changed", this.updateWorkers);
--- a/devtools/client/application/src/components/App.js
+++ b/devtools/client/application/src/components/App.js
@@ -37,17 +37,17 @@ class App extends Component {
const isEmpty = workers.length === 0;
return (
LocalizationProvider(
{ messages: messageContexts },
main(
{ className: `application ${isEmpty ? "application--empty" : ""}` },
isEmpty ? WorkerListEmpty({ serviceContainer })
- : WorkerList({ workers, client })
+ : WorkerList({ client, serviceContainer, workers })
)
)
);
}
}
// Exports
--- a/devtools/client/application/src/components/Worker.js
+++ b/devtools/client/application/src/components/Worker.js
@@ -24,16 +24,17 @@ loader.lazyRequireGetter(this, "gDevTool
* the worker as well as action links and buttons to interact with the worker (e.g. debug,
* unregister, update etc...).
*/
class Worker extends Component {
static get propTypes() {
return {
client: PropTypes.instanceOf(DebuggerClient).isRequired,
debugDisabled: PropTypes.bool,
+ serviceContainer: PropTypes.object.isRequired,
worker: PropTypes.shape({
active: PropTypes.bool,
name: PropTypes.string.isRequired,
scope: PropTypes.string.isRequired,
// registrationActor can be missing in e10s.
registrationActor: PropTypes.string,
workerActor: PropTypes.string
}).isRequired
@@ -43,45 +44,55 @@ class Worker extends Component {
constructor(props) {
super(props);
this.debug = this.debug.bind(this);
this.start = this.start.bind(this);
this.unregister = this.unregister.bind(this);
}
- debug() {
+ async debug() {
if (!this.isRunning()) {
console.log("Service workers cannot be debugged if they are not running");
return;
}
const { client, worker } = this.props;
- gDevToolsBrowser.openWorkerToolbox(client, worker.workerActor);
+
+ const start = performance.now();
+ const toolbox = await gDevToolsBrowser.openWorkerToolbox(client, worker.workerActor);
+ toolbox.once("destroy", () => {
+ const duration = performance.now() - start;
+ this.props.serviceContainer.recordEvent("debug_serviceworker", { duration });
+ });
}
start() {
if (!this.isActive() || this.isRunning()) {
console.log("Running or inactive service workers cannot be started");
return;
}
const { client, worker } = this.props;
client.request({
to: worker.registrationActor,
type: "start"
});
+
+ this.props.serviceContainer.recordEvent("start_serviceworker", {});
}
unregister() {
const { client, worker } = this.props;
client.request({
to: worker.registrationActor,
type: "unregister"
});
+
+ this.props.serviceContainer.recordEvent("unregister_serviceworker", {});
}
isRunning() {
// We know the worker is running if it has a worker actor.
return !!this.props.worker.workerActor;
}
isActive() {
--- a/devtools/client/application/src/components/WorkerList.js
+++ b/devtools/client/application/src/components/WorkerList.js
@@ -17,43 +17,50 @@ const Localized = createFactory(FluentRe
* This component handles the list of service workers displayed in the application panel
* and also displays a suggestion to use about debugging for debugging other service
* workers.
*/
class WorkerList extends Component {
static get propTypes() {
return {
client: PropTypes.object.isRequired,
+ serviceContainer: PropTypes.object.isRequired,
workers: PropTypes.object.isRequired,
};
}
+ openAboutDebugging() {
+ openTrustedLink("about:debugging#workers");
+ this.props.serviceContainer.recordEvent("open_aboutdebugging", {});
+ }
+
render() {
- const { workers, client } = this.props;
+ const { client, serviceContainer, workers } = this.props;
return [
article({ className: "workers-container" },
Localized(
{ id: "serviceworker-list-header" },
h1({})
),
ul({},
workers.map(worker => Worker({
client,
debugDisabled: false,
+ serviceContainer,
worker,
})))
),
Localized(
{
id: "serviceworker-list-aboutdebugging",
a: a(
{
className: "aboutdebugging-plug__link",
- onClick: () => openTrustedLink("about:debugging#workers")
+ onClick: () => this.openAboutDebugging()
}
)
},
footer({ className: "aboutdebugging-plug" })
)
];
}
}
--- a/devtools/client/application/src/components/WorkerListEmpty.js
+++ b/devtools/client/application/src/components/WorkerListEmpty.js
@@ -22,29 +22,37 @@ const DOC_URL = "https://developer.mozil
class WorkerListEmpty extends Component {
static get propTypes() {
return {
serviceContainer: PropTypes.object.isRequired,
};
}
switchToConsole() {
- this.props.serviceContainer.selectTool("webconsole");
+ const { recordEvent, selectTool } = this.props.serviceContainer;
+ selectTool("webconsole");
+ recordEvent("open_help_link", { helpLink: "webconsole" });
}
switchToDebugger() {
- this.props.serviceContainer.selectTool("jsdebugger");
+ const { recordEvent, selectTool } = this.props.serviceContainer;
+ selectTool("jsdebugger");
+ recordEvent("open_help_link", { helpLink: "jsdebugger" });
}
openAboutDebugging() {
+ const { recordEvent } = this.props.serviceContainer;
openTrustedLink("about:debugging#workers");
+ recordEvent("open_help_link", { helpLink: "about:debugging#workers" });
}
openDocumentation() {
+ const { recordEvent } = this.props.serviceContainer;
openWebLink(DOC_URL);
+ recordEvent("open_help_link", { helpLink: "mdn (Using_Service_Workers)" });
}
render() {
return article(
{ className: "worker-list-empty" },
Localized({
id: "serviceworker-empty-intro",
a: a({ className: "external-link", onClick: () => this.openDocumentation() })
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -371,22 +371,25 @@ var gDevToolsBrowser = exports.gDevTools
* Open a window-hosted toolbox to debug the worker associated to the provided
* worker actor.
*
* @param {DebuggerClient} client
* @param {Object} workerActor
* worker actor form to debug
*/
openWorkerToolbox(client, workerActor) {
- client.attachWorker(workerActor, (response, workerClient) => {
- const workerTarget = TargetFactory.forWorker(workerClient);
- gDevTools.showToolbox(workerTarget, null, Toolbox.HostType.WINDOW)
- .then(toolbox => {
- toolbox.once("destroy", () => workerClient.detach());
- });
+ return new Promise(resolve => {
+ client.attachWorker(workerActor, (response, workerClient) => {
+ const workerTarget = TargetFactory.forWorker(workerClient);
+ gDevTools.showToolbox(workerTarget, null, Toolbox.HostType.WINDOW)
+ .then(toolbox => {
+ toolbox.once("destroy", () => workerClient.detach());
+ resolve(toolbox);
+ });
+ });
});
},
/**
* Install WebIDE widget
*/
// Used by itself
installWebIDEWidget() {
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -306,8 +306,53 @@ devtools.main:
bug_numbers: [1463083]
notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
record_in_processes: ["main"]
description: User has executed some JS in the Web Console.
release_channel_collection: opt-out
expiry_version: never
extra_keys:
lines: The number of lines contained in the command.
+ start_serviceworker:
+ objects: ["application"]
+ bug_numbers: [1451734]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User clicked on the Start link for a serviceworker in the application panel.
+ release_channel_collection: opt-out
+ expiry_version: never
+ debug_serviceworker:
+ objects: ["application"]
+ bug_numbers: [1451734]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User clicked on the Debug link for a serviceworker in the application panel.
+ release_channel_collection: opt-out
+ expiry_version: never
+ extra_keys:
+ duration: How much time the debugging toolbox was opened
+ unregister_serviceworker:
+ objects: ["application"]
+ bug_numbers: [1451734]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User clicked on the Unregister button for a serviceworker in the application panel.
+ release_channel_collection: opt-out
+ expiry_version: never
+ open_aboutdebugging:
+ objects: ["application"]
+ bug_numbers: [1451734]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User clicked on the aboutdebugging link displayed in the list of service workers of the application panel.
+ release_channel_collection: opt-out
+ expiry_version: never
+ open_help_link:
+ objects: ["application"]
+ bug_numbers: [1451734]
+ notification_emails: ["dev-developer-tools@lists.mozilla.org", "hkirschner@mozilla.com"]
+ record_in_processes: ["main"]
+ description: User clicked on a help link from the application panel empty screen.
+ release_channel_collection: opt-out
+ expiry_version: never
+ extra_keys:
+ helpLink: Action (toolid, or URL) triggered by clicking on the link
+