Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: chrome/common/metrics/metrics_log_manager.cc

Issue 239093004: Move part of metrics from chrome/common to components (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding TBR section for owners of minor changes. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/common/metrics/metrics_log_manager.h"
6
7 #include <algorithm>
8
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 "chrome/common/metrics/metrics_log_base.h"
14
15 MetricsLogManager::SerializedLog::SerializedLog() {}
16 MetricsLogManager::SerializedLog::~SerializedLog() {}
17
18 bool MetricsLogManager::SerializedLog::IsEmpty() const {
19 return log_text_.empty();
20 }
21
22 void MetricsLogManager::SerializedLog::SwapLogText(std::string* log_text) {
23 log_text_.swap(*log_text);
24 if (log_text_.empty())
25 log_hash_.clear();
26 else
27 log_hash_ = base::SHA1HashString(log_text_);
28 }
29
30 void MetricsLogManager::SerializedLog::Clear() {
31 log_text_.clear();
32 log_hash_.clear();
33 }
34
35 void MetricsLogManager::SerializedLog::Swap(
36 MetricsLogManager::SerializedLog* other) {
37 log_text_.swap(other->log_text_);
38 log_hash_.swap(other->log_hash_);
39 }
40
41 MetricsLogManager::MetricsLogManager()
42 : unsent_logs_loaded_(false),
43 staged_log_type_(MetricsLogBase::NO_LOG),
44 max_ongoing_log_store_size_(0),
45 last_provisional_store_index_(-1),
46 last_provisional_store_type_(MetricsLogBase::INITIAL_STABILITY_LOG) {}
47
48 MetricsLogManager::~MetricsLogManager() {}
49
50 void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log) {
51 DCHECK(!current_log_.get());
52 current_log_.reset(log);
53 }
54
55 void MetricsLogManager::FinishCurrentLog() {
56 DCHECK(current_log_.get());
57 current_log_->CloseLog();
58 SerializedLog compressed_log;
59 CompressCurrentLog(&compressed_log);
60 if (!compressed_log.IsEmpty())
61 StoreLog(&compressed_log, current_log_->log_type(), NORMAL_STORE);
62 current_log_.reset();
63 }
64
65 void MetricsLogManager::StageNextLogForUpload() {
66 // Prioritize initial logs for uploading.
67 std::vector<SerializedLog>* source_list =
68 unsent_initial_logs_.empty() ? &unsent_ongoing_logs_
69 : &unsent_initial_logs_;
70 LogType source_type = (source_list == &unsent_ongoing_logs_) ?
71 MetricsLogBase::ONGOING_LOG : MetricsLogBase::INITIAL_STABILITY_LOG;
72 // CHECK, rather than DCHECK, because swap()ing with an empty list causes
73 // hard-to-identify crashes much later.
74 CHECK(!source_list->empty());
75 DCHECK(staged_log_.IsEmpty());
76 DCHECK_EQ(MetricsLogBase::NO_LOG, staged_log_type_);
77 staged_log_.Swap(&source_list->back());
78 staged_log_type_ = source_type;
79 source_list->pop_back();
80
81 // If the staged log was the last provisional store, clear that.
82 if (last_provisional_store_index_ != -1) {
83 if (source_type == last_provisional_store_type_ &&
84 static_cast<unsigned int>(last_provisional_store_index_) ==
85 source_list->size()) {
86 last_provisional_store_index_ = -1;
87 }
88 }
89 }
90
91 bool MetricsLogManager::has_staged_log() const {
92 return !staged_log_.IsEmpty();
93 }
94
95 void MetricsLogManager::DiscardStagedLog() {
96 staged_log_.Clear();
97 staged_log_type_ = MetricsLogBase::NO_LOG;
98 }
99
100 void MetricsLogManager::DiscardCurrentLog() {
101 current_log_->CloseLog();
102 current_log_.reset();
103 }
104
105 void MetricsLogManager::PauseCurrentLog() {
106 DCHECK(!paused_log_.get());
107 paused_log_.reset(current_log_.release());
108 }
109
110 void MetricsLogManager::ResumePausedLog() {
111 DCHECK(!current_log_.get());
112 current_log_.reset(paused_log_.release());
113 }
114
115 void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) {
116 DCHECK(has_staged_log());
117
118 // If compressing the log failed, there's nothing to store.
119 if (staged_log_.IsEmpty())
120 return;
121
122 StoreLog(&staged_log_, staged_log_type_, store_type);
123 DiscardStagedLog();
124 }
125
126 void MetricsLogManager::StoreLog(SerializedLog* log,
127 LogType log_type,
128 StoreType store_type) {
129 DCHECK_NE(MetricsLogBase::NO_LOG, log_type);
130 std::vector<SerializedLog>* destination_list =
131 (log_type == MetricsLogBase::INITIAL_STABILITY_LOG) ?
132 &unsent_initial_logs_ : &unsent_ongoing_logs_;
133 destination_list->push_back(SerializedLog());
134 destination_list->back().Swap(log);
135
136 if (store_type == PROVISIONAL_STORE) {
137 last_provisional_store_index_ = destination_list->size() - 1;
138 last_provisional_store_type_ = log_type;
139 }
140 }
141
142 void MetricsLogManager::DiscardLastProvisionalStore() {
143 if (last_provisional_store_index_ == -1)
144 return;
145 std::vector<SerializedLog>* source_list =
146 (last_provisional_store_type_ == MetricsLogBase::ONGOING_LOG) ?
147 &unsent_ongoing_logs_ : &unsent_initial_logs_;
148 DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_),
149 source_list->size());
150 source_list->erase(source_list->begin() + last_provisional_store_index_);
151 last_provisional_store_index_ = -1;
152 }
153
154 void MetricsLogManager::PersistUnsentLogs() {
155 DCHECK(log_serializer_.get());
156 if (!log_serializer_.get())
157 return;
158 DCHECK(unsent_logs_loaded_);
159 if (!unsent_logs_loaded_)
160 return;
161
162 base::ElapsedTimer timer;
163 // Remove any ongoing logs that are over the serialization size limit.
164 if (max_ongoing_log_store_size_) {
165 for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin();
166 it != unsent_ongoing_logs_.end();) {
167 size_t log_size = it->log_text().length();
168 if (log_size > max_ongoing_log_store_size_) {
169 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
170 static_cast<int>(log_size));
171 it = unsent_ongoing_logs_.erase(it);
172 } else {
173 ++it;
174 }
175 }
176 }
177 log_serializer_->SerializeLogs(unsent_initial_logs_,
178 MetricsLogBase::INITIAL_STABILITY_LOG);
179 log_serializer_->SerializeLogs(unsent_ongoing_logs_,
180 MetricsLogBase::ONGOING_LOG);
181 UMA_HISTOGRAM_TIMES("UMA.StoreLogsTime", timer.Elapsed());
182 }
183
184 void MetricsLogManager::LoadPersistedUnsentLogs() {
185 DCHECK(log_serializer_.get());
186 if (!log_serializer_.get())
187 return;
188
189 base::ElapsedTimer timer;
190 log_serializer_->DeserializeLogs(MetricsLogBase::INITIAL_STABILITY_LOG,
191 &unsent_initial_logs_);
192 log_serializer_->DeserializeLogs(MetricsLogBase::ONGOING_LOG,
193 &unsent_ongoing_logs_);
194 UMA_HISTOGRAM_TIMES("UMA.LoadLogsTime", timer.Elapsed());
195
196 unsent_logs_loaded_ = true;
197 }
198
199 void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) {
200 std::string log_text;
201 current_log_->GetEncodedLog(&log_text);
202 compressed_log->SwapLogText(&log_text);
203 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698