• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_(std::make_unique<UnsentLogStoreMetricsImpl>(),
29                          local_state,
30                          prefs::kMetricsInitialLogs,
31                          prefs::kMetricsInitialLogsMetadata,
32                          storage_limits.min_initial_log_queue_count,
33                          storage_limits.min_initial_log_queue_size,
34                          0,  // Each individual initial log can be any size.
35                          signing_key,
36                          logs_event_manager),
37       ongoing_log_queue_(std::make_unique<UnsentLogStoreMetricsImpl>(),
38                          local_state,
39                          prefs::kMetricsOngoingLogs,
40                          prefs::kMetricsOngoingLogsMetadata,
41                          storage_limits.min_ongoing_log_queue_count,
42                          storage_limits.min_ongoing_log_queue_size,
43                          storage_limits.max_ongoing_log_size,
44                          signing_key,
45                          logs_event_manager) {}
46 
~MetricsLogStore()47 MetricsLogStore::~MetricsLogStore() {}
48 
LoadPersistedUnsentLogs()49 void MetricsLogStore::LoadPersistedUnsentLogs() {
50   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
51 
52   {
53     MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
54         logs_event_manager_, MetricsLog::LogType::INITIAL_STABILITY_LOG);
55     initial_log_queue_.LoadPersistedUnsentLogs();
56   }
57 
58   {
59     // Note that we assume that logs loaded from the persistent storage for
60     // |ongoing_log_queue_| are of type "ongoing". They could, however, be
61     // independent logs, but we unfortunately cannot determine this since we
62     // don't persist the type of log.
63     MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
64         logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
65     ongoing_log_queue_.LoadPersistedUnsentLogs();
66   }
67 
68   unsent_logs_loaded_ = true;
69 }
70 
StoreLog(const std::string & log_data,MetricsLog::LogType log_type,const LogMetadata & log_metadata,MetricsLogsEventManager::CreateReason reason)71 void MetricsLogStore::StoreLog(const std::string& log_data,
72                                MetricsLog::LogType log_type,
73                                const LogMetadata& log_metadata,
74                                MetricsLogsEventManager::CreateReason reason) {
75   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76 
77   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
78       logs_event_manager_, log_type);
79   GetLogStoreForLogType(log_type)->StoreLog(log_data, log_metadata, reason);
80 }
81 
StoreLogInfo(std::unique_ptr<UnsentLogStore::LogInfo> log_info,size_t uncompressed_log_size,MetricsLog::LogType log_type,MetricsLogsEventManager::CreateReason reason)82 void MetricsLogStore::StoreLogInfo(
83     std::unique_ptr<UnsentLogStore::LogInfo> log_info,
84     size_t uncompressed_log_size,
85     MetricsLog::LogType log_type,
86     MetricsLogsEventManager::CreateReason reason) {
87   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
88       logs_event_manager_, log_type);
89   GetLogStoreForLogType(log_type)->StoreLogInfo(std::move(log_info),
90                                                 uncompressed_log_size, reason);
91 }
92 
Purge()93 void MetricsLogStore::Purge() {
94   initial_log_queue_.Purge();
95   ongoing_log_queue_.Purge();
96   if (has_alternate_ongoing_log_store()) {
97     alternate_ongoing_log_queue_->Purge();
98   }
99 }
100 
GetSigningKeyForLogType(MetricsLog::LogType log_type)101 const std::string& MetricsLogStore::GetSigningKeyForLogType(
102     MetricsLog::LogType log_type) {
103   return GetLogStoreForLogType(log_type)->signing_key();
104 }
105 
SetAlternateOngoingLogStore(std::unique_ptr<UnsentLogStore> log_store)106 void MetricsLogStore::SetAlternateOngoingLogStore(
107     std::unique_ptr<UnsentLogStore> log_store) {
108   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
109 
110   DCHECK(!has_alternate_ongoing_log_store());
111   DCHECK(unsent_logs_loaded_);
112   alternate_ongoing_log_queue_ = std::move(log_store);
113   alternate_ongoing_log_queue_->SetLogsEventManager(logs_event_manager_);
114 
115   // Note that we assume that logs loaded from the persistent storage for
116   // |alternate_ongoing_log_queue_| are of type "ongoing". They could, however,
117   // be independent logs, but we unfortunately cannot determine this since we
118   // don't persist the type of log.
119   MetricsLogsEventManager::ScopedNotifyLogType scoped_log_type(
120       logs_event_manager_, MetricsLog::LogType::ONGOING_LOG);
121   alternate_ongoing_log_queue_->LoadPersistedUnsentLogs();
122 }
123 
UnsetAlternateOngoingLogStore()124 void MetricsLogStore::UnsetAlternateOngoingLogStore() {
125   DCHECK(has_alternate_ongoing_log_store());
126   alternate_ongoing_log_queue_->TrimAndPersistUnsentLogs(
127       /*overwrite_in_memory_store=*/true);
128   alternate_ongoing_log_queue_.reset();
129 }
130 
has_unsent_logs() const131 bool MetricsLogStore::has_unsent_logs() const {
132   return initial_log_queue_.has_unsent_logs() ||
133          ongoing_log_queue_.has_unsent_logs() ||
134          alternate_ongoing_log_store_has_unsent_logs();
135 }
136 
has_staged_log() const137 bool MetricsLogStore::has_staged_log() const {
138   return initial_log_queue_.has_staged_log() ||
139          ongoing_log_queue_.has_staged_log() ||
140          alternate_ongoing_log_store_has_staged_log();
141 }
142 
staged_log() const143 const std::string& MetricsLogStore::staged_log() const {
144   return get_staged_log_queue()->staged_log();
145 }
146 
staged_log_hash() const147 const std::string& MetricsLogStore::staged_log_hash() const {
148   return get_staged_log_queue()->staged_log_hash();
149 }
150 
staged_log_signature() const151 const std::string& MetricsLogStore::staged_log_signature() const {
152   return get_staged_log_queue()->staged_log_signature();
153 }
154 
staged_log_user_id() const155 absl::optional<uint64_t> MetricsLogStore::staged_log_user_id() const {
156   return get_staged_log_queue()->staged_log_user_id();
157 }
158 
has_alternate_ongoing_log_store() const159 bool MetricsLogStore::has_alternate_ongoing_log_store() const {
160   return alternate_ongoing_log_queue_ != nullptr;
161 }
162 
get_staged_log_queue() const163 const UnsentLogStore* MetricsLogStore::get_staged_log_queue() const {
164   DCHECK(has_staged_log());
165 
166   // This is the order in which logs should be staged. Should be consistent with
167   // StageNextLog.
168   if (initial_log_queue_.has_staged_log())
169     return &initial_log_queue_;
170   else if (alternate_ongoing_log_store_has_staged_log())
171     return alternate_ongoing_log_queue_.get();
172   return &ongoing_log_queue_;
173 }
174 
alternate_ongoing_log_store_has_unsent_logs() const175 bool MetricsLogStore::alternate_ongoing_log_store_has_unsent_logs() const {
176   return has_alternate_ongoing_log_store() &&
177          alternate_ongoing_log_queue_->has_unsent_logs();
178 }
179 
alternate_ongoing_log_store_has_staged_log() const180 bool MetricsLogStore::alternate_ongoing_log_store_has_staged_log() const {
181   return has_alternate_ongoing_log_store() &&
182          alternate_ongoing_log_queue_->has_staged_log();
183 }
184 
GetLogStoreForLogType(MetricsLog::LogType log_type)185 UnsentLogStore* MetricsLogStore::GetLogStoreForLogType(
186     MetricsLog::LogType log_type) {
187   switch (log_type) {
188     case MetricsLog::INITIAL_STABILITY_LOG:
189       return &initial_log_queue_;
190     case MetricsLog::ONGOING_LOG:
191     case MetricsLog::INDEPENDENT_LOG:
192       return has_alternate_ongoing_log_store()
193                  ? alternate_ongoing_log_queue_.get()
194                  : &ongoing_log_queue_;
195   }
196 }
197 
StageNextLog()198 void MetricsLogStore::StageNextLog() {
199   DCHECK(!has_staged_log());
200   if (initial_log_queue_.has_unsent_logs())
201     initial_log_queue_.StageNextLog();
202   else if (alternate_ongoing_log_store_has_unsent_logs())
203     alternate_ongoing_log_queue_->StageNextLog();
204   else if (ongoing_log_queue_.has_unsent_logs())
205     ongoing_log_queue_.StageNextLog();
206 }
207 
DiscardStagedLog(base::StringPiece reason)208 void MetricsLogStore::DiscardStagedLog(base::StringPiece reason) {
209   DCHECK(has_staged_log());
210   if (initial_log_queue_.has_staged_log())
211     initial_log_queue_.DiscardStagedLog(reason);
212   else if (alternate_ongoing_log_store_has_staged_log())
213     alternate_ongoing_log_queue_->DiscardStagedLog(reason);
214   else if (ongoing_log_queue_.has_staged_log())
215     ongoing_log_queue_.DiscardStagedLog(reason);
216 
217   DCHECK(!has_staged_log());
218 }
219 
MarkStagedLogAsSent()220 void MetricsLogStore::MarkStagedLogAsSent() {
221   DCHECK(has_staged_log());
222   if (initial_log_queue_.has_staged_log())
223     initial_log_queue_.MarkStagedLogAsSent();
224   else if (alternate_ongoing_log_store_has_staged_log())
225     alternate_ongoing_log_queue_->MarkStagedLogAsSent();
226   else if (ongoing_log_queue_.has_staged_log())
227     ongoing_log_queue_.MarkStagedLogAsSent();
228 }
229 
TrimAndPersistUnsentLogs(bool overwrite_in_memory_store)230 void MetricsLogStore::TrimAndPersistUnsentLogs(bool overwrite_in_memory_store) {
231   DCHECK(unsent_logs_loaded_);
232   if (!unsent_logs_loaded_)
233     return;
234 
235   initial_log_queue_.TrimAndPersistUnsentLogs(overwrite_in_memory_store);
236   ongoing_log_queue_.TrimAndPersistUnsentLogs(overwrite_in_memory_store);
237   if (has_alternate_ongoing_log_store())
238     alternate_ongoing_log_queue_->TrimAndPersistUnsentLogs(
239         overwrite_in_memory_store);
240 }
241 
242 }  // namespace metrics
243