123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // Copyright 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.
- // This file defines a set of user experience metrics data recorded by the
- // MetricsService. This is the unit of data that is sent to the server.
- #ifndef COMPONENTS_METRICS_METRICS_LOG_H_
- #define COMPONENTS_METRICS_METRICS_LOG_H_
- #include <stdint.h>
- #include <memory>
- #include <string>
- #include "base/callback_forward.h"
- #include "base/memory/raw_ptr.h"
- #include "base/metrics/histogram_base.h"
- #include "base/strings/string_piece_forward.h"
- #include "base/time/time.h"
- #include "build/chromeos_buildflags.h"
- #include "components/metrics/metrics_reporting_default_state.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
- #include "third_party/metrics_proto/system_profile.pb.h"
- class PrefService;
- namespace base {
- class Clock;
- class HistogramFlattener;
- class HistogramSamples;
- class HistogramSnapshotManager;
- } // namespace base
- namespace network_time {
- class NetworkTimeTracker;
- } // namespace network_time
- namespace metrics {
- // Holds optional metadata associated with a log to be stored.
- struct LogMetadata {
- LogMetadata();
- LogMetadata(absl::optional<base::HistogramBase::Count> samples_count,
- absl::optional<uint64_t> user_id);
- LogMetadata(const LogMetadata& other);
- ~LogMetadata();
- // Adds |sample_count| to |samples_count|. If |samples_count| is empty, then
- // |sample_count| will populate |samples_count|.
- void AddSampleCount(base::HistogramBase::Count sample_count);
- // The total number of samples in this log if applicable.
- absl::optional<base::HistogramBase::Count> samples_count;
- // User id associated with the log.
- absl::optional<uint64_t> user_id;
- };
- class MetricsProvider;
- class MetricsServiceClient;
- class DelegatingProvider;
- namespace internal {
- // Maximum number of events before truncation.
- constexpr int kOmniboxEventLimit = 5000;
- constexpr int kUserActionEventLimit = 5000;
- SystemProfileProto::InstallerPackage ToInstallerPackage(
- base::StringPiece installer_package_name);
- } // namespace internal
- class MetricsLog {
- public:
- enum LogType {
- INITIAL_STABILITY_LOG, // The initial log containing stability stats.
- ONGOING_LOG, // Subsequent logs in a session.
- INDEPENDENT_LOG, // An independent log from a previous session.
- };
- // Loads "independent" metrics from a metrics provider and executes a
- // callback when complete, which could be immediate or after some
- // execution on a background thread.
- class IndependentMetricsLoader {
- public:
- explicit IndependentMetricsLoader(std::unique_ptr<MetricsLog> log);
- IndependentMetricsLoader(const IndependentMetricsLoader&) = delete;
- IndependentMetricsLoader& operator=(const IndependentMetricsLoader&) =
- delete;
- ~IndependentMetricsLoader();
- // Call ProvideIndependentMetrics (which may execute on a background thread)
- // for the |metrics_provider| and execute the |done_callback| when complete
- // with the result (true if successful). Though this can be called multiple
- // times to include data from multiple providers, later calls will override
- // system profile information set by earlier calls.
- void Run(base::OnceCallback<void(bool)> done_callback,
- MetricsProvider* metrics_provider);
- // Extract the filled log. No more Run() operations can be done after this.
- std::unique_ptr<MetricsLog> ReleaseLog();
- private:
- std::unique_ptr<MetricsLog> log_;
- std::unique_ptr<base::HistogramFlattener> flattener_;
- std::unique_ptr<base::HistogramSnapshotManager> snapshot_manager_;
- };
- // Creates a new metrics log of the specified type.
- // |client_id| is the identifier for this profile on this installation
- // |session_id| is an integer that's incremented on each application launch
- // |client| is used to interact with the embedder.
- // |local_state| is the PrefService that this instance should use.
- // Note: |this| instance does not take ownership of the |client|, but rather
- // stores a weak pointer to it. The caller should ensure that the |client| is
- // valid for the lifetime of this class.
- MetricsLog(const std::string& client_id,
- int session_id,
- LogType log_type,
- MetricsServiceClient* client);
- // As above, with a |clock| and |network_clock| to use to vend Now() calls. As
- // with |client|, the caller must ensure both remain valid for the lifetime of
- // this class.
- MetricsLog(const std::string& client_id,
- int session_id,
- LogType log_type,
- base::Clock* clock,
- const network_time::NetworkTimeTracker* network_clock,
- MetricsServiceClient* client);
- MetricsLog(const MetricsLog&) = delete;
- MetricsLog& operator=(const MetricsLog&) = delete;
- virtual ~MetricsLog();
- // Registers local state prefs used by this class.
- static void RegisterPrefs(PrefRegistrySimple* registry);
- // Computes the MD5 hash of the given string, and returns the first 8 bytes of
- // the hash.
- static uint64_t Hash(const std::string& value);
- // Get the GMT buildtime for the current binary, expressed in seconds since
- // January 1, 1970 GMT.
- // The value is used to identify when a new build is run, so that previous
- // reliability stats, from other builds, can be abandoned.
- static int64_t GetBuildTime();
- // Convenience function to return the current time at a resolution in seconds.
- // This wraps base::TimeTicks, and hence provides an abstract time that is
- // always incrementing for use in measuring time durations.
- static int64_t GetCurrentTime();
- // Records core profile settings into the SystemProfileProto.
- static void RecordCoreSystemProfile(MetricsServiceClient* client,
- SystemProfileProto* system_profile);
- // Records core profile settings into the SystemProfileProto without a client.
- static void RecordCoreSystemProfile(
- const std::string& version,
- metrics::SystemProfileProto::Channel channel,
- bool is_extended_stable_channel,
- const std::string& application_locale,
- const std::string& package_name,
- SystemProfileProto* system_profile);
- // Records a user-initiated action.
- void RecordUserAction(const std::string& key, base::TimeTicks action_time);
- // Record any changes in a given histogram for transmission.
- void RecordHistogramDelta(const std::string& histogram_name,
- const base::HistogramSamples& snapshot);
- // TODO(rkaplow): I think this can be a little refactored as it currently
- // records a pretty arbitrary set of things.
- // Records the current operating environment, including metrics provided by
- // the specified |delegating_provider|. The current environment is
- // returned as a SystemProfileProto.
- const SystemProfileProto& RecordEnvironment(
- DelegatingProvider* delegating_provider);
- // Loads the environment proto that was saved by the last RecordEnvironment()
- // call from prefs. On success, returns true. Otherwise, (if there was no
- // saved environment in prefs or it could not be decoded), returns false.
- bool LoadSavedEnvironmentFromPrefs(PrefService* local_state);
- // Records the log_written_by_app_version system_profile field if the client's
- // version is different from the system_profile's app_version.
- void RecordLogWrittenByAppVersionIfNeeded();
- // Populates the log with data about the previous session.
- // |delegating_provider| forwards the call to provide data to registered
- // MetricsProviders. |local_state| is used to schedule a write because a side
- // effect of providing some data is updating Local State prefs.
- void RecordPreviousSessionData(DelegatingProvider* delegating_provider,
- PrefService* local_state);
- // Populates the log with data about the current session. The uptimes are used
- // to populate the log with info about how long Chrome has been running.
- // |delegating_provider| forwards the call to provide data to registered
- // MetricsProviders. |local_state| is used to schedule a write because a side
- // effect of providing some data is updating Local State prefs.
- void RecordCurrentSessionData(base::TimeDelta incremental_uptime,
- base::TimeDelta uptime,
- DelegatingProvider* delegating_provider,
- PrefService* local_state);
- // Stop writing to this record and generate the encoded representation.
- // None of the Record* methods can be called after this is called.
- void CloseLog();
- // Truncate some of the fields within the log that we want to restrict in
- // size due to bandwidth concerns.
- void TruncateEvents();
- // Fills |encoded_log| with the serialized protobuf representation of the
- // record. Must only be called after CloseLog() has been called.
- void GetEncodedLog(std::string* encoded_log);
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- // Assigns a user ID to the log. This should be called immediately after
- // consotruction if it should be applied.
- void SetUserId(const std::string& user_id);
- #endif
- LogType log_type() const { return log_type_; }
- const LogMetadata& log_metadata() const { return log_metadata_; }
- // Exposed for the sake of mocking/accessing in test code.
- ChromeUserMetricsExtension* UmaProtoForTest() { return &uma_proto_; }
- protected:
- // Exposed for the sake of mocking/accessing in test code.
- // TODO(1034679): migrate to public UmaProtoForTest() method.
- ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; }
- // Exposed to allow subclass to access to export the uma_proto. Can be used
- // by external components to export logs to Chrome.
- const ChromeUserMetricsExtension* uma_proto() const { return &uma_proto_; }
- private:
- // Write the default state of the enable metrics checkbox.
- void WriteMetricsEnableDefault(EnableMetricsDefault metrics_default,
- SystemProfileProto* system_profile);
- // Within the stability group, write attributes that need to be updated asap
- // and can't be delayed until the user decides to restart chromium.
- // Delaying these stats would bias metrics away from happy long lived
- // chromium processes (ones that don't crash, and keep on running).
- void WriteRealtimeStabilityAttributes(base::TimeDelta incremental_uptime,
- base::TimeDelta uptime);
- // closed_ is true when record has been packed up for sending, and should
- // no longer be written to. It is only used for sanity checking.
- bool closed_;
- // The type of the log, i.e. initial or ongoing.
- const LogType log_type_;
- // Stores the protocol buffer representation for this log.
- ChromeUserMetricsExtension uma_proto_;
- // Used to interact with the embedder. Weak pointer; must outlive |this|
- // instance.
- const raw_ptr<MetricsServiceClient> client_;
- // The time when the current log was created.
- const base::TimeTicks creation_time_;
- // True if the environment has already been filled in by a call to
- // RecordEnvironment() or LoadSavedEnvironmentFromPrefs().
- bool has_environment_;
- // Optional metadata associated with the log.
- LogMetadata log_metadata_;
- // The clock used to vend Time::Now(). Note that this is not used for the
- // static function MetricsLog::GetCurrentTime(). Can be overridden for tests.
- raw_ptr<base::Clock> clock_;
- // The NetworkTimeTracker used to provide higher-quality wall clock times than
- // |clock_| (when available). Can be overridden for tests.
- raw_ptr<const network_time::NetworkTimeTracker> network_clock_;
- };
- } // namespace metrics
- #endif // COMPONENTS_METRICS_METRICS_LOG_H_
|