Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /**
6 * Telemetry.
7 *
8 * To add metrics for a tool:
9 *
10 * 1. Create boolean, flag and exponential entries in
11 * toolkit/components/telemetry/Histograms.json. Each type is optional but it
12 * is best if all three can be included.
13 *
14 * 2. Add your chart entries to browser/devtools/shared/telemetry.js
15 * (Telemetry.prototype._histograms):
16 * mytoolname: {
17 * histogram: "DEVTOOLS_MYTOOLNAME_OPENED_BOOLEAN",
18 * userHistogram: "DEVTOOLS_MYTOOLNAME_OPENED_PER_USER_FLAG",
19 * timerHistogram: "DEVTOOLS_MYTOOLNAME_TIME_ACTIVE_SECONDS"
20 * },
21 *
22 * 3. Include this module at the top of your tool. Use:
23 * let Telemetry = require("devtools/shared/telemetry")
24 *
25 * 4. Create a telemetry instance in your tool's constructor:
26 * this._telemetry = new Telemetry();
27 *
28 * 5. When your tool is opened call:
29 * this._telemetry.toolOpened("mytoolname");
30 *
31 * 6. When your tool is closed call:
32 * this._telemetry.toolClosed("mytoolname");
33 *
34 * Note:
35 * You can view telemetry stats for your local Firefox instance via
36 * about:telemetry.
37 *
38 * You can view telemetry stats for large groups of Firefox users at
39 * metrics.mozilla.com.
40 */
42 const TOOLS_OPENED_PREF = "devtools.telemetry.tools.opened.version";
44 this.Telemetry = function() {
45 // Bind pretty much all functions so that callers do not need to.
46 this.toolOpened = this.toolOpened.bind(this);
47 this.toolClosed = this.toolClosed.bind(this);
48 this.log = this.log.bind(this);
49 this.logOncePerBrowserVersion = this.logOncePerBrowserVersion.bind(this);
50 this.destroy = this.destroy.bind(this);
52 this._timers = new Map();
53 };
55 module.exports = Telemetry;
57 let {Cc, Ci, Cu} = require("chrome");
58 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
59 let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
61 Telemetry.prototype = {
62 _histograms: {
63 toolbox: {
64 timerHistogram: "DEVTOOLS_TOOLBOX_TIME_ACTIVE_SECONDS"
65 },
66 options: {
67 histogram: "DEVTOOLS_OPTIONS_OPENED_BOOLEAN",
68 userHistogram: "DEVTOOLS_OPTIONS_OPENED_PER_USER_FLAG",
69 timerHistogram: "DEVTOOLS_OPTIONS_TIME_ACTIVE_SECONDS"
70 },
71 webconsole: {
72 histogram: "DEVTOOLS_WEBCONSOLE_OPENED_BOOLEAN",
73 userHistogram: "DEVTOOLS_WEBCONSOLE_OPENED_PER_USER_FLAG",
74 timerHistogram: "DEVTOOLS_WEBCONSOLE_TIME_ACTIVE_SECONDS"
75 },
76 browserconsole: {
77 histogram: "DEVTOOLS_BROWSERCONSOLE_OPENED_BOOLEAN",
78 userHistogram: "DEVTOOLS_BROWSERCONSOLE_OPENED_PER_USER_FLAG",
79 timerHistogram: "DEVTOOLS_BROWSERCONSOLE_TIME_ACTIVE_SECONDS"
80 },
81 inspector: {
82 histogram: "DEVTOOLS_INSPECTOR_OPENED_BOOLEAN",
83 userHistogram: "DEVTOOLS_INSPECTOR_OPENED_PER_USER_FLAG",
84 timerHistogram: "DEVTOOLS_INSPECTOR_TIME_ACTIVE_SECONDS"
85 },
86 ruleview: {
87 histogram: "DEVTOOLS_RULEVIEW_OPENED_BOOLEAN",
88 userHistogram: "DEVTOOLS_RULEVIEW_OPENED_PER_USER_FLAG",
89 timerHistogram: "DEVTOOLS_RULEVIEW_TIME_ACTIVE_SECONDS"
90 },
91 computedview: {
92 histogram: "DEVTOOLS_COMPUTEDVIEW_OPENED_BOOLEAN",
93 userHistogram: "DEVTOOLS_COMPUTEDVIEW_OPENED_PER_USER_FLAG",
94 timerHistogram: "DEVTOOLS_COMPUTEDVIEW_TIME_ACTIVE_SECONDS"
95 },
96 layoutview: {
97 histogram: "DEVTOOLS_LAYOUTVIEW_OPENED_BOOLEAN",
98 userHistogram: "DEVTOOLS_LAYOUTVIEW_OPENED_PER_USER_FLAG",
99 timerHistogram: "DEVTOOLS_LAYOUTVIEW_TIME_ACTIVE_SECONDS"
100 },
101 fontinspector: {
102 histogram: "DEVTOOLS_FONTINSPECTOR_OPENED_BOOLEAN",
103 userHistogram: "DEVTOOLS_FONTINSPECTOR_OPENED_PER_USER_FLAG",
104 timerHistogram: "DEVTOOLS_FONTINSPECTOR_TIME_ACTIVE_SECONDS"
105 },
106 jsdebugger: {
107 histogram: "DEVTOOLS_JSDEBUGGER_OPENED_BOOLEAN",
108 userHistogram: "DEVTOOLS_JSDEBUGGER_OPENED_PER_USER_FLAG",
109 timerHistogram: "DEVTOOLS_JSDEBUGGER_TIME_ACTIVE_SECONDS"
110 },
111 jsbrowserdebugger: {
112 histogram: "DEVTOOLS_JSBROWSERDEBUGGER_OPENED_BOOLEAN",
113 userHistogram: "DEVTOOLS_JSBROWSERDEBUGGER_OPENED_PER_USER_FLAG",
114 timerHistogram: "DEVTOOLS_JSBROWSERDEBUGGER_TIME_ACTIVE_SECONDS"
115 },
116 styleeditor: {
117 histogram: "DEVTOOLS_STYLEEDITOR_OPENED_BOOLEAN",
118 userHistogram: "DEVTOOLS_STYLEEDITOR_OPENED_PER_USER_FLAG",
119 timerHistogram: "DEVTOOLS_STYLEEDITOR_TIME_ACTIVE_SECONDS"
120 },
121 shadereditor: {
122 histogram: "DEVTOOLS_SHADEREDITOR_OPENED_BOOLEAN",
123 userHistogram: "DEVTOOLS_SHADEREDITOR_OPENED_PER_USER_FLAG",
124 timerHistogram: "DEVTOOLS_SHADEREDITOR_TIME_ACTIVE_SECONDS"
125 },
126 jsprofiler: {
127 histogram: "DEVTOOLS_JSPROFILER_OPENED_BOOLEAN",
128 userHistogram: "DEVTOOLS_JSPROFILER_OPENED_PER_USER_FLAG",
129 timerHistogram: "DEVTOOLS_JSPROFILER_TIME_ACTIVE_SECONDS"
130 },
131 netmonitor: {
132 histogram: "DEVTOOLS_NETMONITOR_OPENED_BOOLEAN",
133 userHistogram: "DEVTOOLS_NETMONITOR_OPENED_PER_USER_FLAG",
134 timerHistogram: "DEVTOOLS_NETMONITOR_TIME_ACTIVE_SECONDS"
135 },
136 tilt: {
137 histogram: "DEVTOOLS_TILT_OPENED_BOOLEAN",
138 userHistogram: "DEVTOOLS_TILT_OPENED_PER_USER_FLAG",
139 timerHistogram: "DEVTOOLS_TILT_TIME_ACTIVE_SECONDS"
140 },
141 paintflashing: {
142 histogram: "DEVTOOLS_PAINTFLASHING_OPENED_BOOLEAN",
143 userHistogram: "DEVTOOLS_PAINTFLASHING_OPENED_PER_USER_FLAG",
144 timerHistogram: "DEVTOOLS_PAINTFLASHING_TIME_ACTIVE_SECONDS"
145 },
146 scratchpad: {
147 histogram: "DEVTOOLS_SCRATCHPAD_OPENED_BOOLEAN",
148 userHistogram: "DEVTOOLS_SCRATCHPAD_OPENED_PER_USER_FLAG",
149 timerHistogram: "DEVTOOLS_SCRATCHPAD_TIME_ACTIVE_SECONDS"
150 },
151 responsive: {
152 histogram: "DEVTOOLS_RESPONSIVE_OPENED_BOOLEAN",
153 userHistogram: "DEVTOOLS_RESPONSIVE_OPENED_PER_USER_FLAG",
154 timerHistogram: "DEVTOOLS_RESPONSIVE_TIME_ACTIVE_SECONDS"
155 },
156 developertoolbar: {
157 histogram: "DEVTOOLS_DEVELOPERTOOLBAR_OPENED_BOOLEAN",
158 userHistogram: "DEVTOOLS_DEVELOPERTOOLBAR_OPENED_PER_USER_FLAG",
159 timerHistogram: "DEVTOOLS_DEVELOPERTOOLBAR_TIME_ACTIVE_SECONDS"
160 },
161 custom: {
162 histogram: "DEVTOOLS_CUSTOM_OPENED_BOOLEAN",
163 userHistogram: "DEVTOOLS_CUSTOM_OPENED_PER_USER_FLAG",
164 timerHistogram: "DEVTOOLS_CUSTOM_TIME_ACTIVE_SECONDS"
165 }
166 },
168 /**
169 * Add an entry to a histogram.
170 *
171 * @param {String} id
172 * Used to look up the relevant histogram ID and log true to that
173 * histogram.
174 */
175 toolOpened: function(id) {
176 let charts = this._histograms[id] || this._histograms.custom;
178 if (charts.histogram) {
179 this.log(charts.histogram, true);
180 }
181 if (charts.userHistogram) {
182 this.logOncePerBrowserVersion(charts.userHistogram, true);
183 }
184 if (charts.timerHistogram) {
185 this._timers.set(charts.timerHistogram, new Date());
186 }
187 },
189 toolClosed: function(id) {
190 let charts = this._histograms[id];
192 if (!charts || !charts.timerHistogram) {
193 return;
194 }
196 let startTime = this._timers.get(charts.timerHistogram);
198 if (startTime) {
199 let time = (new Date() - startTime) / 1000;
200 this.log(charts.timerHistogram, time);
201 this._timers.delete(charts.timerHistogram);
202 }
203 },
205 /**
206 * Log a value to a histogram.
207 *
208 * @param {String} histogramId
209 * Histogram in which the data is to be stored.
210 * @param value
211 * Value to store.
212 */
213 log: function(histogramId, value) {
214 if (histogramId) {
215 let histogram;
217 try {
218 let histogram = Services.telemetry.getHistogramById(histogramId);
219 histogram.add(value);
220 } catch(e) {
221 dump("Warning: An attempt was made to write to the " + histogramId +
222 " histogram, which is not defined in Histograms.json\n");
223 }
224 }
225 },
227 /**
228 * Log info about usage once per browser version. This allows us to discover
229 * how many individual users are using our tools for each browser version.
230 *
231 * @param {String} perUserHistogram
232 * Histogram in which the data is to be stored.
233 */
234 logOncePerBrowserVersion: function(perUserHistogram, value) {
235 let currentVersion = appInfo.version;
236 let latest = Services.prefs.getCharPref(TOOLS_OPENED_PREF);
237 let latestObj = JSON.parse(latest);
239 let lastVersionHistogramUpdated = latestObj[perUserHistogram];
241 if (typeof lastVersionHistogramUpdated == "undefined" ||
242 lastVersionHistogramUpdated !== currentVersion) {
243 latestObj[perUserHistogram] = currentVersion;
244 latest = JSON.stringify(latestObj);
245 Services.prefs.setCharPref(TOOLS_OPENED_PREF, latest);
246 this.log(perUserHistogram, value);
247 }
248 },
250 destroy: function() {
251 for (let [histogram, time] of this._timers) {
252 time = (new Date() - time) / 1000;
254 this.log(histogram, time);
255 this._timers.delete(histogram);
256 }
257 }
258 };
260 XPCOMUtils.defineLazyGetter(this, "appInfo", function() {
261 return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
262 });