1 // Copyright 2014 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 COMPONENTS_METRICS_METRICS_LOG_H_ 9 #define COMPONENTS_METRICS_METRICS_LOG_H_ 10 11 #include <stdint.h> 12 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 #include "base/macros.h" 18 #include "base/time/time.h" 19 #include "components/metrics/metrics_service_client.h" 20 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" 21 22 class PrefService; 23 24 namespace base { 25 class HistogramFlattener; 26 class HistogramSamples; 27 class HistogramSnapshotManager; 28 } // namespace base 29 30 namespace metrics { 31 32 class MetricsProvider; 33 class DelegatingProvider; 34 35 namespace internal { 36 // Maximum number of events before truncation. 37 constexpr int kOmniboxEventLimit = 5000; 38 constexpr int kUserActionEventLimit = 5000; 39 } // namespace internal 40 41 class MetricsLog { 42 public: 43 enum LogType { 44 INITIAL_STABILITY_LOG, // The initial log containing stability stats. 45 ONGOING_LOG, // Subsequent logs in a session. 46 INDEPENDENT_LOG, // An independent log from a previous session. 47 }; 48 49 // Loads "independent" metrics from a metrics provider and executes a 50 // callback when complete, which could be immediate or after some 51 // execution on a background thread. 52 class IndependentMetricsLoader { 53 public: 54 explicit IndependentMetricsLoader(std::unique_ptr<MetricsLog> log); 55 ~IndependentMetricsLoader(); 56 57 // Call ProvideIndependentMetrics (which may execute on a background thread) 58 // for the |metrics_provider| and execute the |done_callback| when complete 59 // with the result (true if successful). Though this can be called multiple 60 // times to include data from multiple providers, later calls will override 61 // system profile information set by earlier calls. 62 void Run(base::OnceCallback<void(bool)> done_callback, 63 MetricsProvider* metrics_provider); 64 65 // Extract the filled log. No more Run() operations can be done after this. 66 std::unique_ptr<MetricsLog> ReleaseLog(); 67 68 private: 69 std::unique_ptr<MetricsLog> log_; 70 std::unique_ptr<base::HistogramFlattener> flattener_; 71 std::unique_ptr<base::HistogramSnapshotManager> snapshot_manager_; 72 73 DISALLOW_COPY_AND_ASSIGN(IndependentMetricsLoader); 74 }; 75 76 // Creates a new metrics log of the specified type. 77 // |client_id| is the identifier for this profile on this installation 78 // |session_id| is an integer that's incremented on each application launch 79 // |client| is used to interact with the embedder. 80 // |local_state| is the PrefService that this instance should use. 81 // Note: |this| instance does not take ownership of the |client|, but rather 82 // stores a weak pointer to it. The caller should ensure that the |client| is 83 // valid for the lifetime of this class. 84 MetricsLog(const std::string& client_id, 85 int session_id, 86 LogType log_type, 87 MetricsServiceClient* client); 88 virtual ~MetricsLog(); 89 90 // Registers local state prefs used by this class. 91 static void RegisterPrefs(PrefRegistrySimple* registry); 92 93 // Computes the MD5 hash of the given string, and returns the first 8 bytes of 94 // the hash. 95 static uint64_t Hash(const std::string& value); 96 97 // Get the GMT buildtime for the current binary, expressed in seconds since 98 // January 1, 1970 GMT. 99 // The value is used to identify when a new build is run, so that previous 100 // reliability stats, from other builds, can be abandoned. 101 static int64_t GetBuildTime(); 102 103 // Convenience function to return the current time at a resolution in seconds. 104 // This wraps base::TimeTicks, and hence provides an abstract time that is 105 // always incrementing for use in measuring time durations. 106 static int64_t GetCurrentTime(); 107 108 // Record core profile settings into the SystemProfileProto. 109 static void RecordCoreSystemProfile(MetricsServiceClient* client, 110 SystemProfileProto* system_profile); 111 112 // Record core profile settings into the SystemProfileProto without a client. 113 static void RecordCoreSystemProfile( 114 const std::string& version, 115 metrics::SystemProfileProto::Channel channel, 116 const std::string& application_locale, 117 const std::string& package_name, 118 SystemProfileProto* system_profile); 119 120 // Records a user-initiated action. 121 void RecordUserAction(const std::string& key, base::TimeTicks action_time); 122 123 // Record any changes in a given histogram for transmission. 124 void RecordHistogramDelta(const std::string& histogram_name, 125 const base::HistogramSamples& snapshot); 126 127 // TODO(rkaplow): I think this can be a little refactored as it currently 128 // records a pretty arbitrary set of things. 129 // Records the current operating environment, including metrics provided by 130 // the specified |delegating_provider|. The current environment is 131 // returned as a SystemProfileProto. 132 const SystemProfileProto& RecordEnvironment( 133 DelegatingProvider* delegating_provider); 134 135 // Loads the environment proto that was saved by the last RecordEnvironment() 136 // call from prefs. On success, returns true and |app_version| contains the 137 // recovered version. Otherwise (if there was no saved environment in prefs 138 // or it could not be decoded), returns false and |app_version| is empty. 139 bool LoadSavedEnvironmentFromPrefs(PrefService* local_state, 140 std::string* app_version); 141 142 // Record data from providers about the previous session into the log. 143 void RecordPreviousSessionData(DelegatingProvider* delegating_provider); 144 145 // Record data from providers about the current session into the log. 146 void RecordCurrentSessionData(DelegatingProvider* delegating_provider, 147 base::TimeDelta incremental_uptime, 148 base::TimeDelta uptime); 149 150 // Stop writing to this record and generate the encoded representation. 151 // None of the Record* methods can be called after this is called. 152 void CloseLog(); 153 154 // Truncate some of the fields within the log that we want to restrict in 155 // size due to bandwidth concerns. 156 void TruncateEvents(); 157 158 // Fills |encoded_log| with the serialized protobuf representation of the 159 // record. Must only be called after CloseLog() has been called. 160 void GetEncodedLog(std::string* encoded_log); 161 creation_time()162 const base::TimeTicks& creation_time() const { 163 return creation_time_; 164 } 165 log_type()166 LogType log_type() const { return log_type_; } 167 168 // Exposed for the sake of mocking/accessing in test code. UmaProtoForTest()169 ChromeUserMetricsExtension* UmaProtoForTest() { return &uma_proto_; } 170 171 protected: 172 // Exposed for the sake of mocking/accessing in test code. 173 // TODO(1034679): migrate to public UmaProtoForTest() method. uma_proto()174 ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; } 175 176 // Exposed to allow subclass to access to export the uma_proto. Can be used 177 // by external components to export logs to Chrome. uma_proto()178 const ChromeUserMetricsExtension* uma_proto() const { 179 return &uma_proto_; 180 } 181 182 private: 183 // Write the default state of the enable metrics checkbox. 184 void WriteMetricsEnableDefault(EnableMetricsDefault metrics_default, 185 SystemProfileProto* system_profile); 186 187 // Within the stability group, write attributes that need to be updated asap 188 // and can't be delayed until the user decides to restart chromium. 189 // Delaying these stats would bias metrics away from happy long lived 190 // chromium processes (ones that don't crash, and keep on running). 191 void WriteRealtimeStabilityAttributes(base::TimeDelta incremental_uptime, 192 base::TimeDelta uptime); 193 194 // closed_ is true when record has been packed up for sending, and should 195 // no longer be written to. It is only used for sanity checking. 196 bool closed_; 197 198 // The type of the log, i.e. initial or ongoing. 199 const LogType log_type_; 200 201 // Stores the protocol buffer representation for this log. 202 ChromeUserMetricsExtension uma_proto_; 203 204 // Used to interact with the embedder. Weak pointer; must outlive |this| 205 // instance. 206 MetricsServiceClient* const client_; 207 208 // The time when the current log was created. 209 const base::TimeTicks creation_time_; 210 211 // True if the environment has already been filled in by a call to 212 // RecordEnvironment() or LoadSavedEnvironmentFromPrefs(). 213 bool has_environment_; 214 215 DISALLOW_COPY_AND_ASSIGN(MetricsLog); 216 }; 217 218 } // namespace metrics 219 220 #endif // COMPONENTS_METRICS_METRICS_LOG_H_ 221