metrics_helpers.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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// This file defines a set of user experience metrics data recorded by 6// the MetricsService. This is the unit of data that is sent to the server. 7 8#ifndef CHROME_COMMON_METRICS_HELPERS_H_ 9#define CHROME_COMMON_METRICS_HELPERS_H_ 10#pragma once 11 12#include <map> 13#include <string> 14 15#include "base/basictypes.h" 16#include "base/histogram.h" 17#include "base/time.h" 18#include "chrome/common/page_transition_types.h" 19 20class GURL; 21class MetricsLog; 22 23// This class provides base functionality for logging metrics data. 24class MetricsLogBase { 25 public: 26 // Creates a new metrics log 27 // client_id is the identifier for this profile on this installation 28 // session_id is an integer that's incremented on each application launch 29 MetricsLogBase(const std::string& client_id, int session_id, 30 const std::string& version_string); 31 virtual ~MetricsLogBase(); 32 33 // Records a user-initiated action. 34 void RecordUserAction(const char* key); 35 36 enum WindowEventType { 37 WINDOW_CREATE = 0, 38 WINDOW_OPEN, 39 WINDOW_CLOSE, 40 WINDOW_DESTROY 41 }; 42 43 void RecordWindowEvent(WindowEventType type, int window_id, int parent_id); 44 45 // Records a page load. 46 // window_id - the index of the tab in which the load took place 47 // url - which URL was loaded 48 // origin - what kind of action initiated the load 49 // load_time - how long it took to load the page 50 void RecordLoadEvent(int window_id, 51 const GURL& url, 52 PageTransition::Type origin, 53 int session_index, 54 base::TimeDelta load_time); 55 56 // Record any changes in a given histogram for transmission. 57 void RecordHistogramDelta(const Histogram& histogram, 58 const Histogram::SampleSet& snapshot); 59 60 // Stop writing to this record and generate the encoded representation. 61 // None of the Record* methods can be called after this is called. 62 void CloseLog(); 63 64 // These methods allow retrieval of the encoded representation of the 65 // record. They can only be called after CloseLog() has been called. 66 // GetEncodedLog returns false if buffer_size is less than 67 // GetEncodedLogSize(); 68 int GetEncodedLogSize(); 69 bool GetEncodedLog(char* buffer, int buffer_size); 70 // Returns an empty string on failure. 71 std::string GetEncodedLogString(); 72 73 // Returns the amount of time in seconds that this log has been in use. 74 int GetElapsedSeconds(); 75 76 int num_events() { return num_events_; } 77 78 void set_hardware_class(const std::string& hardware_class) { 79 hardware_class_ = hardware_class; 80 } 81 82 // Creates an MD5 hash of the given value, and returns hash as a byte 83 // buffer encoded as a std::string. 84 static std::string CreateHash(const std::string& value); 85 86 // Return a base64-encoded MD5 hash of the given string. 87 static std::string CreateBase64Hash(const std::string& string); 88 89 // Get the GMT buildtime for the current binary, expressed in seconds since 90 // Januray 1, 1970 GMT. 91 // The value is used to identify when a new build is run, so that previous 92 // reliability stats, from other builds, can be abandoned. 93 static int64 GetBuildTime(); 94 95 // Use |extension| in all uploaded appversions in addition to the standard 96 // version string. 97 static void set_version_extension(const std::string& extension) { 98 version_extension_ = extension; 99 } 100 101 virtual MetricsLog* AsMetricsLog() { 102 return NULL; 103 } 104 105 protected: 106 class XmlWrapper; 107 108 // Returns a string containing the current time. 109 // Virtual so that it can be overridden for testing. 110 virtual std::string GetCurrentTimeString(); 111 // Helper class that invokes StartElement from constructor, and EndElement 112 // from destructor. 113 // 114 // Use the macro OPEN_ELEMENT_FOR_SCOPE to help avoid usage problems. 115 class ScopedElement { 116 public: 117 ScopedElement(MetricsLogBase* log, const std::string& name) : log_(log) { 118 DCHECK(log); 119 log->StartElement(name.c_str()); 120 } 121 122 ScopedElement(MetricsLogBase* log, const char* name) : log_(log) { 123 DCHECK(log); 124 log->StartElement(name); 125 } 126 127 ~ScopedElement() { 128 log_->EndElement(); 129 } 130 131 private: 132 MetricsLogBase* log_; 133 }; 134 friend class ScopedElement; 135 136 static const char* WindowEventTypeToString(WindowEventType type); 137 138 // Frees the resources allocated by the XML document writer: the 139 // main writer object as well as the XML tree structure, if 140 // applicable. 141 void FreeDocWriter(); 142 143 // Convenience versions of xmlWriter functions 144 void StartElement(const char* name); 145 void EndElement(); 146 void WriteAttribute(const std::string& name, const std::string& value); 147 void WriteIntAttribute(const std::string& name, int value); 148 void WriteInt64Attribute(const std::string& name, int64 value); 149 150 // Write the attributes that are common to every metrics event type. 151 void WriteCommonEventAttributes(); 152 153 // An extension that is appended to the appversion in each log. 154 static std::string version_extension_; 155 156 base::Time start_time_; 157 base::Time end_time_; 158 159 std::string client_id_; 160 std::string session_id_; 161 std::string hardware_class_; 162 163 // locked_ is true when record has been packed up for sending, and should 164 // no longer be written to. It is only used for sanity checking and is 165 // not a real lock. 166 bool locked_; 167 168 // Isolated to limit the dependency on the XML library for our consumers. 169 XmlWrapper* xml_wrapper_; 170 171 int num_events_; // the number of events recorded in this log 172 173 DISALLOW_COPY_AND_ASSIGN(MetricsLogBase); 174}; 175 176// This class provides base functionality for logging metrics data. 177// TODO(ananta) 178// Factor out more common code from chrome and chrome frame metrics service 179// into this class. 180class MetricsServiceBase { 181 protected: 182 MetricsServiceBase(); 183 virtual ~MetricsServiceBase(); 184 185 // Check to see if there is a log that needs to be, or is being, transmitted. 186 bool pending_log() const { 187 return pending_log_ || !compressed_log_.empty(); 188 } 189 190 // Compress the report log in |input| using bzip2, store the result in 191 // |output|. 192 bool Bzip2Compress(const std::string& input, std::string* output); 193 194 // Discard |pending_log_|, and clear |compressed_log_|. Called after 195 // processing of this log is complete. 196 void DiscardPendingLog(); 197 198 // Record complete list of histograms into the current log. 199 // Called when we close a log. 200 void RecordCurrentHistograms(); 201 202 // Record a specific histogram . 203 void RecordHistogram(const Histogram& histogram); 204 205 // A log that we are currently transmiting, or about to try to transmit. 206 MetricsLogBase* pending_log_; 207 208 // An alternate form of |pending_log_|. We persistently save this version 209 // into prefs if we can't transmit it. As a result, sometimes all we have is 210 // the compressed text version. 211 std::string compressed_log_; 212 213 // The log that we are still appending to. 214 MetricsLogBase* current_log_; 215 216 // Maintain a map of histogram names to the sample stats we've sent. 217 typedef std::map<std::string, Histogram::SampleSet> LoggedSampleMap; 218 219 // For histograms, record what we've already logged (as a sample for each 220 // histogram) so that we can send only the delta with the next log. 221 LoggedSampleMap logged_samples_; 222 223 DISALLOW_COPY_AND_ASSIGN(MetricsServiceBase); 224}; 225 226#endif // CHROME_COMMON_METRICS_HELPERS_H_ 227