browser/devtools/shared/telemetry.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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 });

mercurial