Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 1 | // Copyright 2022 The Chromium Authors |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef COMPONENTS_METRICS_METRICS_LOGS_EVENT_MANAGER_H_ |
| 6 | #define COMPONENTS_METRICS_METRICS_LOGS_EVENT_MANAGER_H_ |
| 7 | |
Arthur Sonzogni | c571efb | 2024-01-26 20:26:18 | [diff] [blame] | 8 | #include <optional> |
Helmut Januschka | ff1c3ec | 2024-04-25 19:38:32 | [diff] [blame] | 9 | #include <string_view> |
Arthur Sonzogni | c571efb | 2024-01-26 20:26:18 | [diff] [blame] | 10 | |
Keishi Hattori | c1b0023 | 2022-11-22 09:04:26 | [diff] [blame] | 11 | #include "base/memory/raw_ptr.h" |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 12 | #include "base/observer_list.h" |
Luc Nguyen | a47bc69 | 2022-11-01 22:57:36 | [diff] [blame] | 13 | #include "components/metrics/metrics_log.h" |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 14 | |
| 15 | namespace metrics { |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 16 | |
Alison Gale | 45c4058f | 2024-04-26 19:30:02 | [diff] [blame] | 17 | // TODO(crbug.com/40238818): Add unit tests for the various calls to the notify |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 18 | // functions in ReportingService and UnsentLogStore. |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 19 | class MetricsLogsEventManager { |
| 20 | public: |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 21 | enum class LogEvent { |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 22 | // The log was staged (queued to be uploaded). |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 23 | kLogStaged, |
| 24 | // The log was discarded. |
| 25 | kLogDiscarded, |
| 26 | // The log was trimmed. |
| 27 | kLogTrimmed, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 28 | // The log has been sent out and is currently being uploaded. |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 29 | kLogUploading, |
| 30 | // The log was successfully uploaded. |
| 31 | kLogUploaded, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 32 | // The log was created. |
| 33 | kLogCreated, |
| 34 | }; |
| 35 | |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 36 | // These values are persisted to logs. Entries should not be renumbered and |
| 37 | // numeric values should never be reused. |
| 38 | // LINT.IfChange(CreateReason) |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 39 | enum class CreateReason { |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 40 | kUnknown = 0, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 41 | // The log is a periodic log, which are created at regular intervals. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 42 | kPeriodic = 1, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 43 | // The log was created due to the UMA/UKM service shutting down. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 44 | kServiceShutdown = 2, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 45 | // The log was loaded from a previous session. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 46 | kLoadFromPreviousSession = 3, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 47 | // The log was created due to the browser being backgrounded. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 48 | kBackgrounded = 4, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 49 | // The log was created due to the browser being foregrounded. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 50 | kForegrounded = 5, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 51 | // The log was created due to a new alternate ongoing log store being set. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 52 | kAlternateOngoingLogStoreSet = 6, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 53 | // The log was created due to the alternate ongoing log store being unset. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 54 | kAlternateOngoingLogStoreUnset = 7, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 55 | // The log was created due to the previous session having stability metrics |
| 56 | // to report. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 57 | kStability = 8, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 58 | // The log was fully created and provided by a metrics provider. |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 59 | kIndependent = 9, |
| 60 | // The log was created due to a manual upload from the client. |
| 61 | kOutOfBand = 10, |
| 62 | kMaxValue = kOutOfBand, |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 63 | }; |
Hira Mahmood | a5a694b8 | 2025-02-18 16:59:59 | [diff] [blame] | 64 | // LINT.ThenChange(/tools/metrics/histograms/metadata/uma/enums.xml:MetricsLogCreateReason) |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 65 | |
| 66 | class Observer : public base::CheckedObserver { |
| 67 | public: |
Helmut Januschka | ff1c3ec | 2024-04-25 19:38:32 | [diff] [blame] | 68 | virtual void OnLogCreated(std::string_view log_hash, |
| 69 | std::string_view log_data, |
| 70 | std::string_view log_timestamp, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 71 | CreateReason reason) = 0; |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 72 | virtual void OnLogEvent(MetricsLogsEventManager::LogEvent event, |
Helmut Januschka | ff1c3ec | 2024-04-25 19:38:32 | [diff] [blame] | 73 | std::string_view log_hash, |
| 74 | std::string_view message) = 0; |
Arthur Sonzogni | c571efb | 2024-01-26 20:26:18 | [diff] [blame] | 75 | virtual void OnLogType(std::optional<MetricsLog::LogType> log_type) {} |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 76 | |
| 77 | protected: |
| 78 | Observer() = default; |
| 79 | ~Observer() override = default; |
| 80 | }; |
| 81 | |
Luc Nguyen | a47bc69 | 2022-11-01 22:57:36 | [diff] [blame] | 82 | // Helper class used to indicate that UMA logs created while an instance of |
| 83 | // this class is in scope are of a certain type. Only one instance of this |
| 84 | // class should exist at a time. |
| 85 | class ScopedNotifyLogType { |
| 86 | public: |
| 87 | ScopedNotifyLogType(MetricsLogsEventManager* logs_event_manager, |
| 88 | MetricsLog::LogType log_type); |
| 89 | |
| 90 | ScopedNotifyLogType(const ScopedNotifyLogType& other) = delete; |
| 91 | ScopedNotifyLogType& operator=(const ScopedNotifyLogType& other) = delete; |
| 92 | |
| 93 | ~ScopedNotifyLogType(); |
| 94 | |
| 95 | private: |
Keishi Hattori | c1b0023 | 2022-11-22 09:04:26 | [diff] [blame] | 96 | const raw_ptr<MetricsLogsEventManager> logs_event_manager_; |
Luc Nguyen | a47bc69 | 2022-11-01 22:57:36 | [diff] [blame] | 97 | |
| 98 | // Used to ensure that only one instance of this class exists at a time. |
| 99 | static bool instance_exists_; |
| 100 | }; |
| 101 | |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 102 | MetricsLogsEventManager(); |
| 103 | |
| 104 | MetricsLogsEventManager(const MetricsLogsEventManager&) = delete; |
| 105 | MetricsLogsEventManager& operator=(const MetricsLogsEventManager&) = delete; |
| 106 | |
| 107 | ~MetricsLogsEventManager(); |
| 108 | |
| 109 | void AddObserver(Observer* observer); |
| 110 | void RemoveObserver(Observer* observer); |
| 111 | |
| 112 | // Notifies observers that a log was newly created and is now known by the |
| 113 | // metrics service. This may occur when closing a log, or when loading a log |
| 114 | // from persistent storage. |log_hash| is the SHA1 hash of the log data, used |
| 115 | // to uniquely identify the log. This hash may be re-used to notify that an |
| 116 | // event occurred on the log (e.g., the log was trimmed, uploaded, etc.). See |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 117 | // NotifyLogEvent(). |log_data| is the compressed serialized log protobuf |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 118 | // (see UnsentLogStore::LogInfo for more details on the compression). |
| 119 | // |log_timestamp| is the time at which the log was closed. |
Helmut Januschka | ff1c3ec | 2024-04-25 19:38:32 | [diff] [blame] | 120 | void NotifyLogCreated(std::string_view log_hash, |
| 121 | std::string_view log_data, |
| 122 | std::string_view log_timestamp, |
Luc Nguyen | d53ac1d | 2023-01-30 17:47:43 | [diff] [blame] | 123 | CreateReason reason); |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 124 | |
Luc Nguyen | 3e8432e | 2022-10-06 21:23:44 | [diff] [blame] | 125 | // Notifies observers that an event |event| occurred on the log associated |
| 126 | // with |log_hash|. Optionally, a |message| can be associated with the event. |
| 127 | // In particular, for |kLogDiscarded|, |message| is the reason the log was |
| 128 | // discarded (e.g., log is ill-formed). For |kLogTrimmed|, |message| is the |
| 129 | // reason why the log was trimmed (e.g., log is too large). |
| 130 | void NotifyLogEvent(LogEvent event, |
Helmut Januschka | ff1c3ec | 2024-04-25 19:38:32 | [diff] [blame] | 131 | std::string_view log_hash, |
| 132 | std::string_view message = ""); |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 133 | |
Luc Nguyen | a47bc69 | 2022-11-01 22:57:36 | [diff] [blame] | 134 | // Notifies observers that logs that are created after this function is called |
| 135 | // are of the type |log_type|. This should only be used in UMA. This info is |
| 136 | // not passed through NotifyLogCreated() because the concept of a log type |
| 137 | // only exists in UMA, and this class is intended to be re-used across |
| 138 | // different metrics collection services (e.g., UKM). |
| 139 | // Note: Typically, this should not be called directly. Consider using |
| 140 | // ScopedNotifyLogType. |
Arthur Sonzogni | c571efb | 2024-01-26 20:26:18 | [diff] [blame] | 141 | void NotifyLogType(std::optional<MetricsLog::LogType> log_type); |
Luc Nguyen | a47bc69 | 2022-11-01 22:57:36 | [diff] [blame] | 142 | |
Luc Nguyen | 8901ecf | 2022-09-23 23:47:27 | [diff] [blame] | 143 | private: |
| 144 | base::ObserverList<Observer> observers_; |
| 145 | }; |
| 146 | |
| 147 | } // namespace metrics |
| 148 | |
shaochenguang | 61f8f1d8 | 2023-11-29 23:57:17 | [diff] [blame] | 149 | #endif // COMPONENTS_METRICS_METRICS_LOGS_EVENT_MANAGER_H_ |