| // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview Utility methods for accessing chrome.metricsPrivate API. |
| * |
| * To be included as a first script in main.html |
| */ |
| |
| var metrics; // Needs to be defined in each window which uses metrics. |
| const metricsBase = {}; |
| |
| /** |
| * A map from interval name to interval start timestamp. |
| */ |
| metricsBase.intervals = {}; |
| |
| /** |
| * A mapping of enum names to valid values. This object is consulted |
| * any time an enum value is being reported un-accompanied by a list |
| * of valid values. |
| * |
| * <p>Values mut be provided by base classes. Values should correspond exactly |
| * with values from histograms.xml. |
| * |
| * @private {!Object<!Array<*>|number>} |
| */ |
| metricsBase.validEnumValues_ = {}; |
| |
| |
| /** |
| * Start the named time interval. |
| * Should be followed by a call to recordInterval with the same name. |
| * |
| * @param {string} name Unique interval name. |
| */ |
| metricsBase.startInterval = name => { |
| metricsBase.intervals[name] = Date.now(); |
| }; |
| |
| /** |
| * Convert a short metric name to the full format. |
| * |
| * @param {string} name Short metric name. |
| * @return {string} Full metric name. |
| * @private |
| */ |
| metricsBase.convertName_ = name => { |
| throw new Error('metricsBase.convertName_() must be overrideen by subclass.'); |
| }; |
| |
| /** |
| * Wrapper method for calling chrome.fileManagerPrivate safely. |
| * @param {string} methodName Method name. |
| * @param {Array<Object>} args Arguments. |
| * @private |
| */ |
| metricsBase.call_ = (methodName, args) => { |
| try { |
| chrome.metricsPrivate[methodName].apply(chrome.metricsPrivate, args); |
| } catch (e) { |
| console.error(e.stack); |
| } |
| // Support writing metrics.log in manual testing to log method calls. |
| if (/** @type{{ log: (boolean|undefined) }} */ (metrics).log) { |
| console.log('chrome.metricsPrivate.' + methodName, args); |
| } |
| }; |
| |
| /** |
| * Records a value than can range from 1 to 10,000. |
| * @param {string} name Short metric name. |
| * @param {number} value Value to be recorded. |
| */ |
| metricsBase.recordMediumCount = (name, value) => { |
| metrics.call_('recordMediumCount', [metrics.convertName_(name), value]); |
| }; |
| |
| /** |
| * Records a value than can range from 1 to 100. |
| * @param {string} name Short metric name. |
| * @param {number} value Value to be recorded. |
| */ |
| metricsBase.recordSmallCount = (name, value) => { |
| metrics.call_('recordSmallCount', [metrics.convertName_(name), value]); |
| }; |
| |
| /** |
| * Records an elapsed time of no more than 10 seconds. |
| * @param {string} name Short metric name. |
| * @param {number} time Time to be recorded in milliseconds. |
| */ |
| metricsBase.recordTime = (name, time) => { |
| metrics.call_('recordTime', [metrics.convertName_(name), time]); |
| }; |
| |
| /** |
| * Records a boolean value to the given metric. |
| * @param {string} name Short metric name. |
| * @param {boolean} value The value to be recorded. |
| */ |
| metricsBase.recordBoolean = (name, value) => { |
| metrics.call_('recordBoolean', [metrics.convertName_(name), value]); |
| }; |
| |
| /** |
| * Records an action performed by the user. |
| * @param {string} name Short metric name. |
| */ |
| metricsBase.recordUserAction = name => { |
| metrics.call_('recordUserAction', [metrics.convertName_(name)]); |
| }; |
| |
| /** |
| * Records an elapsed time of no more than 10 seconds. |
| * @param {string} name Short metric name. |
| * @param {number} value Numeric value to be recorded in units |
| * that match the histogram definition (in histograms.xml). |
| */ |
| metricsBase.recordValue = (name, value) => { |
| metrics.call_('recordValue', [metrics.convertName_(name), value]); |
| }; |
| |
| /** |
| * Complete the time interval recording. |
| * |
| * Should be preceded by a call to startInterval with the same name. * |
| * |
| * @param {string} name Unique interval name. |
| */ |
| metricsBase.recordInterval = name => { |
| if (name in metrics.intervals) { |
| metrics.recordTime(name, Date.now() - metrics.intervals[name]); |
| } else { |
| console.error('Unknown interval: ' + name); |
| } |
| }; |
| |
| /** |
| * Record an enum value. |
| * |
| * @param {string} name Metric name. |
| * @param {*} value Enum value. |
| * @param {Array<*>|number=} opt_validValues Array of valid values |
| * or a boundary number (one-past-the-end) value. |
| */ |
| metricsBase.recordEnum = (name, value, opt_validValues) => { |
| let boundaryValue; |
| let index; |
| |
| let validValues = opt_validValues; |
| if (metrics.validEnumValues_ && name in metrics.validEnumValues_) { |
| console.assert(validValues === undefined); |
| validValues = metrics.validEnumValues_[name]; |
| } |
| console.assert(validValues !== undefined); |
| |
| if (validValues.constructor.name == 'Array') { |
| index = validValues.indexOf(value); |
| boundaryValue = validValues.length; |
| } else { |
| index = /** @type {number} */ (value); |
| boundaryValue = validValues; |
| } |
| // Collect invalid values in the overflow bucket at the end. |
| if (index < 0 || index >= boundaryValue) { |
| index = boundaryValue - 1; |
| } |
| |
| // Setting min to 1 looks strange but this is exactly the recommended way |
| // of using histograms for enum-like types. Bucket #0 works as a regular |
| // bucket AND the underflow bucket. |
| // (Source: UMA_HISTOGRAM_ENUMERATION definition in base/metrics/histogram.h) |
| const metricDescr = { |
| 'metricName': metrics.convertName_(name), |
| 'type': chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LINEAR, |
| 'min': 1, |
| 'max': boundaryValue, |
| 'buckets': boundaryValue |
| }; |
| metrics.call_('recordValue', [metricDescr, index]); |
| }; |