| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/metrics/metrics_log_manager.h" | 5 #include "components/metrics/metrics_log_store.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/strings/string_util.h" | |
| 11 #include "components/metrics/metrics_log.h" | |
| 12 #include "components/metrics/metrics_pref_names.h" | 7 #include "components/metrics/metrics_pref_names.h" |
| 13 #include "components/metrics/persisted_logs_metrics_impl.h" | 8 #include "components/metrics/persisted_logs_metrics_impl.h" |
| 9 #include "components/prefs/pref_registry_simple.h" |
| 14 | 10 |
| 15 namespace metrics { | 11 namespace metrics { |
| 16 | 12 |
| 17 namespace { | 13 namespace { |
| 18 | 14 |
| 19 // The number of "initial" logs to save, and hope to send during a future Chrome | 15 // The number of "initial" logs to save, and hope to send during a future Chrome |
| 20 // session. Initial logs contain crash stats, and are pretty small. | 16 // session. Initial logs contain crash stats, and are pretty small. |
| 21 const size_t kInitialLogsPersistLimit = 20; | 17 const size_t kInitialLogsPersistLimit = 20; |
| 22 | 18 |
| 23 // The number of ongoing logs to save persistently, and hope to | 19 // The number of ongoing logs to save persistently, and hope to |
| 24 // send during a this or future sessions. Note that each log may be pretty | 20 // send during a this or future sessions. Note that each log may be pretty |
| 25 // large, as presumably the related "initial" log wasn't sent (probably nothing | 21 // large, as presumably the related "initial" log wasn't sent (probably nothing |
| 26 // was, as the user was probably off-line). As a result, the log probably kept | 22 // was, as the user was probably off-line). As a result, the log probably kept |
| 27 // accumulating while the "initial" log was stalled, and couldn't be sent. As a | 23 // accumulating while the "initial" log was stalled, and couldn't be sent. As a |
| 28 // result, we don't want to save too many of these mega-logs. | 24 // result, we don't want to save too many of these mega-logs. |
| 29 // A "standard shutdown" will create a small log, including just the data that | 25 // A "standard shutdown" will create a small log, including just the data that |
| 30 // was not yet been transmitted, and that is normal (to have exactly one | 26 // was not yet been transmitted, and that is normal (to have exactly one |
| 31 // ongoing_log_ at startup). | 27 // ongoing_log_ at startup). |
| 32 const size_t kOngoingLogsPersistLimit = 8; | 28 const size_t kOngoingLogsPersistLimit = 8; |
| 33 | 29 |
| 34 // The number of bytes each of initial and ongoing logs that must be stored. | 30 // The number of bytes of logs to save of each type (initial/ongoing). |
| 35 // This ensures that a reasonable amount of history will be stored even if there | 31 // This ensures that a reasonable amount of history will be stored even if there |
| 36 // is a long series of very small logs. | 32 // is a long series of very small logs. |
| 37 const size_t kStorageByteLimitPerLogType = 300000; | 33 const size_t kStorageByteLimitPerLogType = 300 * 1000; // ~300kB |
| 38 | 34 |
| 39 } // namespace | 35 } // namespace |
| 40 | 36 |
| 41 MetricsLogManager::MetricsLogManager(PrefService* local_state, | 37 // static |
| 42 size_t max_ongoing_log_size) | 38 void MetricsLogStore::RegisterPrefs(PrefRegistrySimple* registry) { |
| 39 registry->RegisterListPref(prefs::kMetricsInitialLogs); |
| 40 registry->RegisterListPref(prefs::kMetricsOngoingLogs); |
| 41 } |
| 42 |
| 43 MetricsLogStore::MetricsLogStore(PrefService* local_state, |
| 44 size_t max_ongoing_log_size) |
| 43 : unsent_logs_loaded_(false), | 45 : unsent_logs_loaded_(false), |
| 44 initial_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>( | 46 initial_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>( |
| 45 new PersistedLogsMetricsImpl()), | 47 new PersistedLogsMetricsImpl()), |
| 46 local_state, | 48 local_state, |
| 47 prefs::kMetricsInitialLogs, | 49 prefs::kMetricsInitialLogs, |
| 48 kInitialLogsPersistLimit, | 50 kInitialLogsPersistLimit, |
| 49 kStorageByteLimitPerLogType, | 51 kStorageByteLimitPerLogType, |
| 50 0), | 52 0), |
| 51 ongoing_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>( | 53 ongoing_log_queue_(std::unique_ptr<PersistedLogsMetricsImpl>( |
| 52 new PersistedLogsMetricsImpl()), | 54 new PersistedLogsMetricsImpl()), |
| 53 local_state, | 55 local_state, |
| 54 prefs::kMetricsOngoingLogs, | 56 prefs::kMetricsOngoingLogs, |
| 55 kOngoingLogsPersistLimit, | 57 kOngoingLogsPersistLimit, |
| 56 kStorageByteLimitPerLogType, | 58 kStorageByteLimitPerLogType, |
| 57 max_ongoing_log_size) {} | 59 max_ongoing_log_size) {} |
| 58 | 60 |
| 59 MetricsLogManager::~MetricsLogManager() {} | 61 MetricsLogStore::~MetricsLogStore() {} |
| 60 | 62 |
| 61 void MetricsLogManager::BeginLoggingWithLog(std::unique_ptr<MetricsLog> log) { | 63 void MetricsLogStore::LoadPersistedUnsentLogs() { |
| 62 DCHECK(!current_log_); | 64 initial_log_queue_.LoadPersistedUnsentLogs(); |
| 63 current_log_ = std::move(log); | 65 ongoing_log_queue_.LoadPersistedUnsentLogs(); |
| 66 unsent_logs_loaded_ = true; |
| 64 } | 67 } |
| 65 | 68 |
| 66 void MetricsLogManager::FinishCurrentLog() { | 69 void MetricsLogStore::StoreLog(const std::string& log_data, |
| 67 DCHECK(current_log_.get()); | 70 MetricsLog::LogType log_type) { |
| 68 current_log_->CloseLog(); | |
| 69 std::string log_data; | |
| 70 current_log_->GetEncodedLog(&log_data); | |
| 71 if (!log_data.empty()) | |
| 72 StoreLog(log_data, current_log_->log_type()); | |
| 73 current_log_.reset(); | |
| 74 } | |
| 75 | |
| 76 void MetricsLogManager::StageNextLogForUpload() { | |
| 77 DCHECK(!has_staged_log()); | |
| 78 if (!initial_log_queue_.empty()) | |
| 79 initial_log_queue_.StageLog(); | |
| 80 else | |
| 81 ongoing_log_queue_.StageLog(); | |
| 82 } | |
| 83 | |
| 84 void MetricsLogManager::DiscardStagedLog() { | |
| 85 DCHECK(has_staged_log()); | |
| 86 if (initial_log_queue_.has_staged_log()) | |
| 87 initial_log_queue_.DiscardStagedLog(); | |
| 88 else | |
| 89 ongoing_log_queue_.DiscardStagedLog(); | |
| 90 DCHECK(!has_staged_log()); | |
| 91 } | |
| 92 | |
| 93 void MetricsLogManager::DiscardCurrentLog() { | |
| 94 current_log_->CloseLog(); | |
| 95 current_log_.reset(); | |
| 96 } | |
| 97 | |
| 98 void MetricsLogManager::PauseCurrentLog() { | |
| 99 DCHECK(!paused_log_.get()); | |
| 100 paused_log_ = std::move(current_log_); | |
| 101 } | |
| 102 | |
| 103 void MetricsLogManager::ResumePausedLog() { | |
| 104 DCHECK(!current_log_.get()); | |
| 105 current_log_ = std::move(paused_log_); | |
| 106 } | |
| 107 | |
| 108 void MetricsLogManager::StoreLog(const std::string& log_data, | |
| 109 MetricsLog::LogType log_type) { | |
| 110 switch (log_type) { | 71 switch (log_type) { |
| 111 case MetricsLog::INITIAL_STABILITY_LOG: | 72 case MetricsLog::INITIAL_STABILITY_LOG: |
| 112 initial_log_queue_.StoreLog(log_data); | 73 initial_log_queue_.StoreLog(log_data); |
| 113 break; | 74 break; |
| 114 case MetricsLog::ONGOING_LOG: | 75 case MetricsLog::ONGOING_LOG: |
| 115 ongoing_log_queue_.StoreLog(log_data); | 76 ongoing_log_queue_.StoreLog(log_data); |
| 116 break; | 77 break; |
| 117 } | 78 } |
| 118 } | 79 } |
| 119 | 80 |
| 120 void MetricsLogManager::PersistUnsentLogs() { | 81 bool MetricsLogStore::has_unsent_logs() const { |
| 82 return initial_log_queue_.has_unsent_logs() || |
| 83 ongoing_log_queue_.has_unsent_logs(); |
| 84 } |
| 85 |
| 86 bool MetricsLogStore::has_staged_log() const { |
| 87 return initial_log_queue_.has_staged_log() || |
| 88 ongoing_log_queue_.has_staged_log(); |
| 89 } |
| 90 |
| 91 const std::string& MetricsLogStore::staged_log() const { |
| 92 return initial_log_queue_.has_staged_log() ? initial_log_queue_.staged_log() |
| 93 : ongoing_log_queue_.staged_log(); |
| 94 } |
| 95 |
| 96 const std::string& MetricsLogStore::staged_log_hash() const { |
| 97 return initial_log_queue_.has_staged_log() |
| 98 ? initial_log_queue_.staged_log_hash() |
| 99 : ongoing_log_queue_.staged_log_hash(); |
| 100 } |
| 101 |
| 102 void MetricsLogStore::StageNextLog() { |
| 103 DCHECK(!has_staged_log()); |
| 104 if (initial_log_queue_.has_unsent_logs()) |
| 105 initial_log_queue_.StageNextLog(); |
| 106 else |
| 107 ongoing_log_queue_.StageNextLog(); |
| 108 } |
| 109 |
| 110 void MetricsLogStore::DiscardStagedLog() { |
| 111 DCHECK(has_staged_log()); |
| 112 if (initial_log_queue_.has_staged_log()) |
| 113 initial_log_queue_.DiscardStagedLog(); |
| 114 else |
| 115 ongoing_log_queue_.DiscardStagedLog(); |
| 116 DCHECK(!has_staged_log()); |
| 117 } |
| 118 |
| 119 void MetricsLogStore::PersistUnsentLogs() const { |
| 121 DCHECK(unsent_logs_loaded_); | 120 DCHECK(unsent_logs_loaded_); |
| 122 if (!unsent_logs_loaded_) | 121 if (!unsent_logs_loaded_) |
| 123 return; | 122 return; |
| 124 | 123 |
| 125 initial_log_queue_.SerializeLogs(); | 124 initial_log_queue_.PersistUnsentLogs(); |
| 126 ongoing_log_queue_.SerializeLogs(); | 125 ongoing_log_queue_.PersistUnsentLogs(); |
| 127 } | |
| 128 | |
| 129 void MetricsLogManager::LoadPersistedUnsentLogs() { | |
| 130 initial_log_queue_.DeserializeLogs(); | |
| 131 ongoing_log_queue_.DeserializeLogs(); | |
| 132 unsent_logs_loaded_ = true; | |
| 133 } | 126 } |
| 134 | 127 |
| 135 } // namespace metrics | 128 } // namespace metrics |
| OLD | NEW |