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 8 #include <optional> 9 10 #include "base/memory/raw_ptr.h" 11 #include "base/observer_list.h" 12 #include "base/strings/string_piece.h" 13 #include "components/metrics/metrics_log.h" 14 15 namespace metrics { 16 17 // TODO(crbug/1363747): Add unit tests for the various calls to the notify 18 // functions in ReportingService and UnsentLogStore. 19 class MetricsLogsEventManager { 20 public: 21 enum class LogEvent { 22 // The log was staged (queued to be uploaded). 23 kLogStaged, 24 // The log was discarded. 25 kLogDiscarded, 26 // The log was trimmed. 27 kLogTrimmed, 28 // The log has been sent out and is currently being uploaded. 29 kLogUploading, 30 // The log was successfully uploaded. 31 kLogUploaded, 32 // The log was created. 33 kLogCreated, 34 }; 35 36 enum class CreateReason { 37 kUnknown, 38 // The log is a periodic log, which are created at regular intervals. 39 kPeriodic, 40 // The log was created due to the UMA/UKM service shutting down. 41 kServiceShutdown, 42 // The log was loaded from a previous session. 43 kLoadFromPreviousSession, 44 // The log was created due to the browser being backgrounded. 45 kBackgrounded, 46 // The log was created due to the browser being foregrounded. 47 kForegrounded, 48 // The log was created due to a new alternate ongoing log store being set. 49 kAlternateOngoingLogStoreSet, 50 // The log was created due to the alternate ongoing log store being unset. 51 kAlternateOngoingLogStoreUnset, 52 // The log was created due to the previous session having stability metrics 53 // to report. 54 kStability, 55 // The log was fully created and provided by a metrics provider. 56 kIndependent, 57 }; 58 59 class Observer : public base::CheckedObserver { 60 public: 61 virtual void OnLogCreated(base::StringPiece log_hash, 62 base::StringPiece log_data, 63 base::StringPiece log_timestamp, 64 CreateReason reason) = 0; 65 virtual void OnLogEvent(MetricsLogsEventManager::LogEvent event, 66 base::StringPiece log_hash, 67 base::StringPiece message) = 0; OnLogType(std::optional<MetricsLog::LogType> log_type)68 virtual void OnLogType(std::optional<MetricsLog::LogType> log_type) {} 69 70 protected: 71 Observer() = default; 72 ~Observer() override = default; 73 }; 74 75 // Helper class used to indicate that UMA logs created while an instance of 76 // this class is in scope are of a certain type. Only one instance of this 77 // class should exist at a time. 78 class ScopedNotifyLogType { 79 public: 80 ScopedNotifyLogType(MetricsLogsEventManager* logs_event_manager, 81 MetricsLog::LogType log_type); 82 83 ScopedNotifyLogType(const ScopedNotifyLogType& other) = delete; 84 ScopedNotifyLogType& operator=(const ScopedNotifyLogType& other) = delete; 85 86 ~ScopedNotifyLogType(); 87 88 private: 89 const raw_ptr<MetricsLogsEventManager> logs_event_manager_; 90 91 // Used to ensure that only one instance of this class exists at a time. 92 static bool instance_exists_; 93 }; 94 95 MetricsLogsEventManager(); 96 97 MetricsLogsEventManager(const MetricsLogsEventManager&) = delete; 98 MetricsLogsEventManager& operator=(const MetricsLogsEventManager&) = delete; 99 100 ~MetricsLogsEventManager(); 101 102 void AddObserver(Observer* observer); 103 void RemoveObserver(Observer* observer); 104 105 // Notifies observers that a log was newly created and is now known by the 106 // metrics service. This may occur when closing a log, or when loading a log 107 // from persistent storage. |log_hash| is the SHA1 hash of the log data, used 108 // to uniquely identify the log. This hash may be re-used to notify that an 109 // event occurred on the log (e.g., the log was trimmed, uploaded, etc.). See 110 // NotifyLogEvent(). |log_data| is the compressed serialized log protobuf 111 // (see UnsentLogStore::LogInfo for more details on the compression). 112 // |log_timestamp| is the time at which the log was closed. 113 void NotifyLogCreated(base::StringPiece log_hash, 114 base::StringPiece log_data, 115 base::StringPiece log_timestamp, 116 CreateReason reason); 117 118 // Notifies observers that an event |event| occurred on the log associated 119 // with |log_hash|. Optionally, a |message| can be associated with the event. 120 // In particular, for |kLogDiscarded|, |message| is the reason the log was 121 // discarded (e.g., log is ill-formed). For |kLogTrimmed|, |message| is the 122 // reason why the log was trimmed (e.g., log is too large). 123 void NotifyLogEvent(LogEvent event, 124 base::StringPiece log_hash, 125 base::StringPiece message = ""); 126 127 // Notifies observers that logs that are created after this function is called 128 // are of the type |log_type|. This should only be used in UMA. This info is 129 // not passed through NotifyLogCreated() because the concept of a log type 130 // only exists in UMA, and this class is intended to be re-used across 131 // different metrics collection services (e.g., UKM). 132 // Note: Typically, this should not be called directly. Consider using 133 // ScopedNotifyLogType. 134 void NotifyLogType(std::optional<MetricsLog::LogType> log_type); 135 136 private: 137 base::ObserverList<Observer> observers_; 138 }; 139 140 } // namespace metrics 141 142 #endif // COMPONENTS_METRICS_METRICS_LOGS_EVENT_MANAGER_H_ 143