1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Utility methods for accessing chrome.metricsPrivate API. 7 * 8 * To be included as a first script in main.html 9 */ 10 11var metrics = {}; 12 13/** 14 * A map from interval name to interval start timestamp. 15 */ 16metrics.intervals = {}; 17 18/** 19 * Start the named time interval. 20 * Should be followed by a call to recordInterval with the same name. 21 * 22 * @param {string} name Unique interval name. 23 */ 24metrics.startInterval = function(name) { 25 metrics.intervals[name] = Date.now(); 26}; 27 28metrics.startInterval('Load.Total'); 29metrics.startInterval('Load.Script'); 30 31/** 32 * Convert a short metric name to the full format. 33 * 34 * @param {string} name Short metric name. 35 * @return {string} Full metric name. 36 * @private 37 */ 38metrics.convertName_ = function(name) { 39 return 'FileBrowser.' + name; 40}; 41 42/** 43 * Wrapper method for calling chrome.fileManagerPrivate safely. 44 * @param {string} name Method name. 45 * @param {Array.<Object>} args Arguments. 46 * @private 47 */ 48metrics.call_ = function(name, args) { 49 try { 50 chrome.metricsPrivate[name].apply(chrome.metricsPrivate, args); 51 } catch (e) { 52 console.error(e.stack); 53 } 54}; 55 56/** 57 * Create a decorator function that calls a chrome.metricsPrivate function 58 * with the same name and correct parameters. 59 * 60 * @param {string} name Method name. 61 */ 62metrics.decorate = function(name) { 63 metrics[name] = function() { 64 var args = Array.apply(null, arguments); 65 args[0] = metrics.convertName_(args[0]); 66 metrics.call_(name, args); 67 if (metrics.log) { 68 console.log('chrome.metricsPrivate.' + name, args); 69 } 70 }; 71}; 72 73metrics.decorate('recordMediumCount'); 74metrics.decorate('recordSmallCount'); 75metrics.decorate('recordTime'); 76metrics.decorate('recordUserAction'); 77 78/** 79 * Complete the time interval recording. 80 * 81 * Should be preceded by a call to startInterval with the same name. * 82 * 83 * @param {string} name Unique interval name. 84 */ 85metrics.recordInterval = function(name) { 86 if (name in metrics.intervals) { 87 metrics.recordTime(name, Date.now() - metrics.intervals[name]); 88 } else { 89 console.error('Unknown interval: ' + name); 90 } 91}; 92 93/** 94 * Record an enum value. 95 * 96 * @param {string} name Metric name. 97 * @param {Object} value Enum value. 98 * @param {Array.<Object>|number} validValues Array of valid values 99 * or a boundary number value. 100 */ 101metrics.recordEnum = function(name, value, validValues) { 102 var boundaryValue; 103 var index; 104 if (validValues.constructor.name == 'Array') { 105 index = validValues.indexOf(value); 106 boundaryValue = validValues.length; 107 } else { 108 index = value; 109 boundaryValue = validValues; 110 } 111 // Collect invalid values in the overflow bucket at the end. 112 if (index < 0 || index > boundaryValue) 113 index = boundaryValue; 114 115 // Setting min to 1 looks strange but this is exactly the recommended way 116 // of using histograms for enum-like types. Bucket #0 works as a regular 117 // bucket AND the underflow bucket. 118 // (Source: UMA_HISTOGRAM_ENUMERATION definition in base/metrics/histogram.h) 119 var metricDescr = { 120 'metricName': metrics.convertName_(name), 121 'type': 'histogram-linear', 122 'min': 1, 123 'max': boundaryValue, 124 'buckets': boundaryValue + 1 125 }; 126 metrics.call_('recordValue', [metricDescr, index]); 127 if (metrics.log) { 128 console.log('chrome.metricsPrivate.recordValue', 129 [metricDescr.metricName, index, value]); 130 } 131}; 132