xref: /aosp_15_r20/external/cronet/components/metrics/metrics_log_store.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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 #include "components/metrics/metrics_log_store.h"
6 
7 #include "components/metrics/metrics_pref_names.h"
8 #include "components/metrics/metrics_service_client.h"
9 #include "components/metrics/unsent_log_store_metrics_impl.h"
10 #include "components/prefs/pref_registry_simple.h"
11 
12 namespace metrics {
13 
14 // static
RegisterPrefs(PrefRegistrySimple * registry)15 void MetricsLogStore::RegisterPrefs(PrefRegistrySimple* registry) {
16   registry->RegisterListPref(prefs::kMetricsInitialLogs);
17   registry->RegisterListPref(prefs::kMetricsOngoingLogs);
18   registry->RegisterDictionaryPref(prefs::kMetricsInitialLogsMetadata);
19   registry->RegisterDictionaryPref(prefs::kMetricsOngoingLogsMetadata);
20 }
21 
MetricsLogStore(PrefService * local_state,StorageLimits storage_limits,const std::string & signing_key,MetricsLogsEventManager * logs_event_manager)22 MetricsLogStore::MetricsLogStore(PrefService* local_state,
23                                  StorageLimits storage_limits,
24                                  const std::string& signing_key,
25                                  MetricsLogsEventManager* logs_event_manager)
26     : unsent_logs_loaded_(false),
27       logs_event_manager_(logs_event_manager),
28       initial_log_queue_(
29           std::make_unique<UnsentLogStoreMetricsImpl>(),
30           local_state,
31           prefs::kMetricsInitialLogs,
32           prefs::kMetricsInitialLogsMetadata,
33           UnsentLogStore::UnsentLogStoreLimits{
34               storage_limits.initial_log_queue_limits.min_log_count,
35               storage_limits.initial_log_queue_limits.min_queue_size_bytes,
36               // Each individual initial log can be any size.
37               /*max_log_size_bytes=*/0},
38           signing_key,
39           logs_event_manager),
40       ongoing_log_queue_(std::make_unique<UnsentLogStoreMetricsImpl>(),
41                          local_state,
42                          prefs::kMetricsOngoingLogs,
43                          prefs::kMetricsOngoingLogsMetadata,
44                          storage_limits.ongoing_log_queue_limits,
45                          signing_key,
46                          logs_event_manager) {}
47 
~MetricsLogStore()48 MetricsLogStore::~MetricsLogStore() {}
49 
LoadPersistedUnsentLogs()50 void MetricsLogStore::LoadPersistedUnsentLogs() {
51   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
52 
53   {
54     MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
55         logs_event_manager_, MetricsLog::LogType::INITIAL_STABILITY_LOG);
56     initial_log_queue_.LoadPersistedUnsentLogs();
57   }
58 
59   {
60     // Note that we assume that logs loaded from the persistent storage for
61     // |ongoing_log_queue_| are of type "ongoing". They could, however, be
62     // independent logs, but we unfortunately cannot determine this since we
63     // don't persist the type of log.
64     MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
65         logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
66     ongoing_log_queue_.LoadPersistedUnsentLogs();
67   }
68 
69   unsent_logs_loaded_ = true;
70 }
71 
StoreLog(const std::string & log_data,MetricsLog::LogType log_type,const LogMetadata & log_metadata,MetricsLogsEventManager::CreateReason reason)72 void MetricsLogStore::StoreLog(const std::string& log_data,
73                                MetricsLog::LogType log_type,
74                                const LogMetadata& log_metadata,
75                                MetricsLogsEventManager::CreateReason reason) {
76   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
77 
78   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
79       logs_event_manager_, log_type);
80   GetLogStoreForLogType(log_type)->StoreLog(log_data, log_metadata, reason);
81 }
82 
StoreLogInfo(std::unique_ptr<UnsentLogStore::LogInfo> log_info,size_t uncompressed_log_size,MetricsLog::LogType log_type,MetricsLogsEventManager::CreateReason reason)83 void MetricsLogStore::StoreLogInfo(
84     std::unique_ptr<UnsentLogStore::LogInfo> log_info,
85     size_t uncompressed_log_size,
86     MetricsLog::LogType log_type,
87     MetricsLogsEventManager::CreateReason reason) {
88   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
89       logs_event_manager_, log_type);
90   GetLogStoreForLogType(log_type)->StoreLogInfo(std::move(log_info),
91                                                 uncompressed_log_size, reason);
92 }
93 
Purge()94 void MetricsLogStore::Purge() {
95   initial_log_queue_.Purge();
96   ongoing_log_queue_.Purge();
97   if (has_alternate_ongoing_log_store()) {
98     alternate_ongoing_log_queue_->Purge();
99   }
100 }
101 
GetSigningKeyForLogType(MetricsLog::LogType log_type)102 const std::string& MetricsLogStore::GetSigningKeyForLogType(
103     MetricsLog::LogType log_type) {
104   return GetLogStoreForLogType(log_type)->signing_key();
105 }
106 
SetAlternateOngoingLogStore(std::unique_ptr<UnsentLogStore> log_store)107 void MetricsLogStore::SetAlternateOngoingLogStore(
108     std::unique_ptr<UnsentLogStore> log_store) {
109   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
110 
111   DCHECK(!has_alternate_ongoing_log_store());
112   DCHECK(unsent_logs_loaded_);
113   alternate_ongoing_log_queue_ = std::move(log_store);
114   alternate_ongoing_log_queue_->SetLogsEventManager(logs_event_manager_);
115 
116   // Note that we assume that logs loaded from the persistent storage for
117   // |alternate_ongoing_log_queue_| are of type "ongoing". They could, however,
118   // be independent logs, but we unfortunately cannot determine this since we
119   // don't persist the type of log.
120   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
121       logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
122   alternate_ongoing_log_queue_->LoadPersistedUnsentLogs();
123 }
124 
UnsetAlternateOngoingLogStore()125 void MetricsLogStore::UnsetAlternateOngoingLogStore() {
126   DCHECK(has_alternate_ongoing_log_store());
127   alternate_ongoing_log_queue_->TrimAndPersistUnsentLogs(
128       /*overwrite_in_memory_store=*/true);
129   alternate_ongoing_log_queue_.reset();
130 }
131 
has_unsent_logs() const132 bool MetricsLogStore::has_unsent_logs() const {
133   return initial_log_queue_.has_unsent_logs() ||
134          ongoing_log_queue_.has_unsent_logs() ||
135          alternate_ongoing_log_store_has_unsent_logs();
136 }
137 
has_staged_log() const138 bool MetricsLogStore::has_staged_log() const {
139   return initial_log_queue_.has_staged_log() ||
140          ongoing_log_queue_.has_staged_log() ||
141          alternate_ongoing_log_store_has_staged_log();
142 }
143 
staged_log() const144 const std::string& MetricsLogStore::staged_log() const {
145   return get_staged_log_queue()->staged_log();
146 }
147 
staged_log_hash() const148 const std::string& MetricsLogStore::staged_log_hash() const {
149   return get_staged_log_queue()->staged_log_hash();
150 }
151 
staged_log_signature() const152 const std::string& MetricsLogStore::staged_log_signature() const {
153   return get_staged_log_queue()->staged_log_signature();
154 }
155 
staged_log_user_id() const156 std::optional<uint64_t> MetricsLogStore::staged_log_user_id() const {
157   return get_staged_log_queue()->staged_log_user_id();
158 }
159 
staged_log_metadata() const160 const LogMetadata MetricsLogStore::staged_log_metadata() const {
161   return get_staged_log_queue()->staged_log_metadata();
162 }
163 
has_alternate_ongoing_log_store() const164 bool MetricsLogStore::has_alternate_ongoing_log_store() const {
165   return alternate_ongoing_log_queue_ != nullptr;
166 }
167 
get_staged_log_queue() const168 const UnsentLogStore* MetricsLogStore::get_staged_log_queue() const {
169   DCHECK(has_staged_log());
170 
171   // This is the order in which logs should be staged. Should be consistent with
172   // StageNextLog.
173   if (initial_log_queue_.has_staged_log())
174     return &initial_log_queue_;
175   else if (alternate_ongoing_log_store_has_staged_log())
176     return alternate_ongoing_log_queue_.get();
177   return &ongoing_log_queue_;
178 }
179 
alternate_ongoing_log_store_has_unsent_logs() const180 bool MetricsLogStore::alternate_ongoing_log_store_has_unsent_logs() const {
181   return has_alternate_ongoing_log_store() &&
182          alternate_ongoing_log_queue_->has_unsent_logs();
183 }
184 
alternate_ongoing_log_store_has_staged_log() const185 bool MetricsLogStore::alternate_ongoing_log_store_has_staged_log() const {
186   return has_alternate_ongoing_log_store() &&
187          alternate_ongoing_log_queue_->has_staged_log();
188 }
189 
GetLogStoreForLogType(MetricsLog::LogType log_type)190 UnsentLogStore* MetricsLogStore::GetLogStoreForLogType(
191     MetricsLog::LogType log_type) {
192   switch (log_type) {
193     case MetricsLog::INITIAL_STABILITY_LOG:
194       return &initial_log_queue_;
195     case MetricsLog::ONGOING_LOG:
196     case MetricsLog::INDEPENDENT_LOG:
197       return has_alternate_ongoing_log_store()
198                  ? alternate_ongoing_log_queue_.get()
199                  : &ongoing_log_queue_;
200   }
201 }
202 
StageNextLog()203 void MetricsLogStore::StageNextLog() {
204   DCHECK(!has_staged_log());
205   if (initial_log_queue_.has_unsent_logs())
206     initial_log_queue_.StageNextLog();
207   else if (alternate_ongoing_log_store_has_unsent_logs())
208     alternate_ongoing_log_queue_->StageNextLog();
209   else if (ongoing_log_queue_.has_unsent_logs())
210     ongoing_log_queue_.StageNextLog();
211 }
212 
DiscardStagedLog(base::StringPiece reason)213 void MetricsLogStore::DiscardStagedLog(base::StringPiece reason) {
214   DCHECK(has_staged_log());
215   if (initial_log_queue_.has_staged_log())
216     initial_log_queue_.DiscardStagedLog(reason);
217   else if (alternate_ongoing_log_store_has_staged_log())
218     alternate_ongoing_log_queue_->DiscardStagedLog(reason);
219   else if (ongoing_log_queue_.has_staged_log())
220     ongoing_log_queue_.DiscardStagedLog(reason);
221 
222   DCHECK(!has_staged_log());
223 }
224 
MarkStagedLogAsSent()225 void MetricsLogStore::MarkStagedLogAsSent() {
226   DCHECK(has_staged_log());
227   if (initial_log_queue_.has_staged_log())
228     initial_log_queue_.MarkStagedLogAsSent();
229   else if (alternate_ongoing_log_store_has_staged_log())
230     alternate_ongoing_log_queue_->MarkStagedLogAsSent();
231   else if (ongoing_log_queue_.has_staged_log())
232     ongoing_log_queue_.MarkStagedLogAsSent();
233 }
234 
TrimAndPersistUnsentLogs(bool overwrite_in_memory_store)235 void MetricsLogStore::TrimAndPersistUnsentLogs(bool overwrite_in_memory_store) {
236   DCHECK(unsent_logs_loaded_);
237   if (!unsent_logs_loaded_)
238     return;
239 
240   initial_log_queue_.TrimAndPersistUnsentLogs(overwrite_in_memory_store);
241   ongoing_log_queue_.TrimAndPersistUnsentLogs(overwrite_in_memory_store);
242   if (has_alternate_ongoing_log_store())
243     alternate_ongoing_log_queue_->TrimAndPersistUnsentLogs(
244         overwrite_in_memory_store);
245 }
246 
247 }  // namespace metrics
248