metrics_log.h 12 KB

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