Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / components / metrics / metrics_log_manager.cc
blobe537eefb35c72b94df3b5642422c4ab11c9c8feb
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/metrics/metrics_log_manager.h"
7 #include <algorithm>
9 #include "base/metrics/histogram.h"
10 #include "base/sha1.h"
11 #include "base/strings/string_util.h"
12 #include "base/timer/elapsed_timer.h"
13 #include "components/metrics/metrics_log_base.h"
15 namespace metrics {
17 MetricsLogManager::SerializedLog::SerializedLog() {}
18 MetricsLogManager::SerializedLog::~SerializedLog() {}
20 bool MetricsLogManager::SerializedLog::IsEmpty() const {
21 return log_text_.empty();
24 void MetricsLogManager::SerializedLog::SwapLogText(std::string* log_text) {
25 log_text_.swap(*log_text);
26 if (log_text_.empty())
27 log_hash_.clear();
28 else
29 log_hash_ = base::SHA1HashString(log_text_);
32 void MetricsLogManager::SerializedLog::Clear() {
33 log_text_.clear();
34 log_hash_.clear();
37 void MetricsLogManager::SerializedLog::Swap(
38 MetricsLogManager::SerializedLog* other) {
39 log_text_.swap(other->log_text_);
40 log_hash_.swap(other->log_hash_);
43 MetricsLogManager::MetricsLogManager()
44 : unsent_logs_loaded_(false),
45 staged_log_type_(MetricsLogBase::NO_LOG),
46 max_ongoing_log_store_size_(0),
47 last_provisional_store_index_(-1),
48 last_provisional_store_type_(MetricsLogBase::INITIAL_STABILITY_LOG) {}
50 MetricsLogManager::~MetricsLogManager() {}
52 void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log) {
53 DCHECK(!current_log_.get());
54 current_log_.reset(log);
57 void MetricsLogManager::FinishCurrentLog() {
58 DCHECK(current_log_.get());
59 current_log_->CloseLog();
60 SerializedLog compressed_log;
61 CompressCurrentLog(&compressed_log);
62 if (!compressed_log.IsEmpty())
63 StoreLog(&compressed_log, current_log_->log_type(), NORMAL_STORE);
64 current_log_.reset();
67 void MetricsLogManager::StageNextLogForUpload() {
68 // Prioritize initial logs for uploading.
69 std::vector<SerializedLog>* source_list =
70 unsent_initial_logs_.empty() ? &unsent_ongoing_logs_
71 : &unsent_initial_logs_;
72 LogType source_type = (source_list == &unsent_ongoing_logs_) ?
73 MetricsLogBase::ONGOING_LOG : MetricsLogBase::INITIAL_STABILITY_LOG;
74 // CHECK, rather than DCHECK, because swap()ing with an empty list causes
75 // hard-to-identify crashes much later.
76 CHECK(!source_list->empty());
77 DCHECK(staged_log_.IsEmpty());
78 DCHECK_EQ(MetricsLogBase::NO_LOG, staged_log_type_);
79 staged_log_.Swap(&source_list->back());
80 staged_log_type_ = source_type;
81 source_list->pop_back();
83 // If the staged log was the last provisional store, clear that.
84 if (last_provisional_store_index_ != -1) {
85 if (source_type == last_provisional_store_type_ &&
86 static_cast<unsigned int>(last_provisional_store_index_) ==
87 source_list->size()) {
88 last_provisional_store_index_ = -1;
93 bool MetricsLogManager::has_staged_log() const {
94 return !staged_log_.IsEmpty();
97 void MetricsLogManager::DiscardStagedLog() {
98 staged_log_.Clear();
99 staged_log_type_ = MetricsLogBase::NO_LOG;
102 void MetricsLogManager::DiscardCurrentLog() {
103 current_log_->CloseLog();
104 current_log_.reset();
107 void MetricsLogManager::PauseCurrentLog() {
108 DCHECK(!paused_log_.get());
109 paused_log_.reset(current_log_.release());
112 void MetricsLogManager::ResumePausedLog() {
113 DCHECK(!current_log_.get());
114 current_log_.reset(paused_log_.release());
117 void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) {
118 DCHECK(has_staged_log());
120 // If compressing the log failed, there's nothing to store.
121 if (staged_log_.IsEmpty())
122 return;
124 StoreLog(&staged_log_, staged_log_type_, store_type);
125 DiscardStagedLog();
128 void MetricsLogManager::StoreLog(SerializedLog* log,
129 LogType log_type,
130 StoreType store_type) {
131 DCHECK_NE(MetricsLogBase::NO_LOG, log_type);
132 std::vector<SerializedLog>* destination_list =
133 (log_type == MetricsLogBase::INITIAL_STABILITY_LOG) ?
134 &unsent_initial_logs_ : &unsent_ongoing_logs_;
135 destination_list->push_back(SerializedLog());
136 destination_list->back().Swap(log);
138 if (store_type == PROVISIONAL_STORE) {
139 last_provisional_store_index_ = destination_list->size() - 1;
140 last_provisional_store_type_ = log_type;
144 void MetricsLogManager::DiscardLastProvisionalStore() {
145 if (last_provisional_store_index_ == -1)
146 return;
147 std::vector<SerializedLog>* source_list =
148 (last_provisional_store_type_ == MetricsLogBase::ONGOING_LOG)
149 ? &unsent_ongoing_logs_
150 : &unsent_initial_logs_;
151 DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_),
152 source_list->size());
153 source_list->erase(source_list->begin() + last_provisional_store_index_);
154 last_provisional_store_index_ = -1;
157 void MetricsLogManager::PersistUnsentLogs() {
158 DCHECK(log_serializer_.get());
159 if (!log_serializer_.get())
160 return;
161 DCHECK(unsent_logs_loaded_);
162 if (!unsent_logs_loaded_)
163 return;
165 base::ElapsedTimer timer;
166 // Remove any ongoing logs that are over the serialization size limit.
167 if (max_ongoing_log_store_size_) {
168 for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin();
169 it != unsent_ongoing_logs_.end();) {
170 size_t log_size = it->log_text().length();
171 if (log_size > max_ongoing_log_store_size_) {
172 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
173 static_cast<int>(log_size));
174 it = unsent_ongoing_logs_.erase(it);
175 } else {
176 ++it;
180 log_serializer_->SerializeLogs(unsent_initial_logs_,
181 MetricsLogBase::INITIAL_STABILITY_LOG);
182 log_serializer_->SerializeLogs(unsent_ongoing_logs_,
183 MetricsLogBase::ONGOING_LOG);
184 UMA_HISTOGRAM_TIMES("UMA.StoreLogsTime", timer.Elapsed());
187 void MetricsLogManager::LoadPersistedUnsentLogs() {
188 DCHECK(log_serializer_.get());
189 if (!log_serializer_.get())
190 return;
192 base::ElapsedTimer timer;
193 log_serializer_->DeserializeLogs(MetricsLogBase::INITIAL_STABILITY_LOG,
194 &unsent_initial_logs_);
195 log_serializer_->DeserializeLogs(MetricsLogBase::ONGOING_LOG,
196 &unsent_ongoing_logs_);
197 UMA_HISTOGRAM_TIMES("UMA.LoadLogsTime", timer.Elapsed());
199 unsent_logs_loaded_ = true;
202 void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) {
203 std::string log_text;
204 current_log_->GetEncodedLog(&log_text);
205 compressed_log->SwapLogText(&log_text);
208 } // namespace metrics