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

Side by Side Diff: components/metrics/persisted_logs.cc

Issue 397443004: Skip oversized logs when persisting logs instead of discarding them. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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
« no previous file with comments | « components/metrics/persisted_logs.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/persisted_logs.h" 5 #include "components/metrics/persisted_logs.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/md5.h" 10 #include "base/md5.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 const char* pref_name, 79 const char* pref_name,
80 const char* old_pref_name, 80 const char* old_pref_name,
81 size_t min_log_count, 81 size_t min_log_count,
82 size_t min_log_bytes, 82 size_t min_log_bytes,
83 size_t max_log_size) 83 size_t max_log_size)
84 : local_state_(local_state), 84 : local_state_(local_state),
85 pref_name_(pref_name), 85 pref_name_(pref_name),
86 old_pref_name_(old_pref_name), 86 old_pref_name_(old_pref_name),
87 min_log_count_(min_log_count), 87 min_log_count_(min_log_count),
88 min_log_bytes_(min_log_bytes), 88 min_log_bytes_(min_log_bytes),
89 max_log_size_(max_log_size), 89 max_log_size_(max_log_size ? max_log_size : static_cast<size_t>(-1)),
Alexei Svitkine (slow) 2014/07/15 18:52:59 Can you use SIZE_MAX instead of casting -1 to a si
Steven Holte 2014/07/15 20:23:03 Done.
90 last_provisional_store_index_(-1) { 90 last_provisional_store_index_(-1) {
91 DCHECK(local_state_); 91 DCHECK(local_state_);
92 // One of the limit arguments must be non-zero. 92 // One of the limit arguments must be non-zero.
93 DCHECK(min_log_count_ > 0 || min_log_bytes_ > 0); 93 DCHECK(min_log_count_ > 0 || min_log_bytes_ > 0);
94 } 94 }
95 95
96 PersistedLogs::~PersistedLogs() {} 96 PersistedLogs::~PersistedLogs() {}
97 97
98 void PersistedLogs::SerializeLogs() { 98 void PersistedLogs::SerializeLogs() const {
99 // Remove any logs that are over the serialization size limit.
100 if (max_log_size_) {
101 for (std::vector<LogHashPair>::iterator it = list_.begin();
102 it != list_.end();) {
103 size_t log_size = it->compressed_log_data.length();
104 if (log_size > max_log_size_) {
105 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
106 static_cast<int>(log_size));
107 it = list_.erase(it);
108 } else {
109 ++it;
110 }
111 }
112 }
113
114 ListPrefUpdate update(local_state_, pref_name_); 99 ListPrefUpdate update(local_state_, pref_name_);
115 WriteLogsToPrefList(update.Get()); 100 WriteLogsToPrefList(update.Get());
116 101
117 // Clear the old pref now that we've written to the new one. 102 // Clear the old pref now that we've written to the new one.
118 // TODO(asvitkine): Remove the old pref in M39. 103 // TODO(asvitkine): Remove the old pref in M39.
119 local_state_->ClearPref(old_pref_name_); 104 local_state_->ClearPref(old_pref_name_);
120 } 105 }
121 106
122 PersistedLogs::LogReadStatus PersistedLogs::DeserializeLogs() { 107 PersistedLogs::LogReadStatus PersistedLogs::DeserializeLogs() {
123 // First, try reading from old pref. If it's empty, read from the new one. 108 // First, try reading from old pref. If it's empty, read from the new one.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 147 }
163 148
164 void PersistedLogs::DiscardLastProvisionalStore() { 149 void PersistedLogs::DiscardLastProvisionalStore() {
165 if (last_provisional_store_index_ == -1) 150 if (last_provisional_store_index_ == -1)
166 return; 151 return;
167 DCHECK_LT(static_cast<size_t>(last_provisional_store_index_), list_.size()); 152 DCHECK_LT(static_cast<size_t>(last_provisional_store_index_), list_.size());
168 list_.erase(list_.begin() + last_provisional_store_index_); 153 list_.erase(list_.begin() + last_provisional_store_index_);
169 last_provisional_store_index_ = -1; 154 last_provisional_store_index_ = -1;
170 } 155 }
171 156
172 void PersistedLogs::WriteLogsToPrefList(base::ListValue* list_value) { 157 void PersistedLogs::WriteLogsToPrefList(base::ListValue* list_value) const {
173 list_value->Clear(); 158 list_value->Clear();
159
160 // Keep the most recent logs which are smaller than max_log_size_.
Alexei Svitkine (slow) 2014/07/15 18:52:59 Nit: Surround variable names in |'s.
Steven Holte 2014/07/15 20:23:03 Done.
161 // We keep at least min_log_bytes_ and min_log_count_ of logs before
162 // discarding older logs.
163 size_t start = list_.size();
164 size_t saved_log_count = 0;
165 size_t bytes_used = 0;
166 for (; start > 0; --start) {
167 size_t log_size = list_[start-1].compressed_log_data.length();
Alexei Svitkine (slow) 2014/07/15 18:52:59 Nit: spaces around the minus.
Steven Holte 2014/07/15 20:23:03 Done.
168 if (bytes_used >= min_log_bytes_ &&
169 saved_log_count >= min_log_count_) {
170 break;
171 }
172 // Oversized logs won't be persisted, so don't count them.
Alexei Svitkine (slow) 2014/07/15 18:52:59 I don't think the piece of code is needed, since t
Steven Holte 2014/07/15 20:23:03 The second loop iterates in the reverse direction
Steven Holte 2014/07/15 20:25:47 Also, I've now removed the early return below, sin
173 if (log_size <= max_log_size_) {
174 bytes_used += log_size;
175 ++saved_log_count;
176 }
177 }
178
174 // Leave the list completely empty if there are no storable values. 179 // Leave the list completely empty if there are no storable values.
175 if (list_.empty()) 180 if (saved_log_count == 0)
176 return; 181 return;
177 182
178 size_t start = 0; 183 for (size_t i = start; i < list_.size(); ++i) {
179 // If there are too many logs, keep the most recent logs up to the length 184 size_t log_size = list_[i].compressed_log_data.length();
180 // limit, and at least to the minimum number of bytes. 185 if (log_size > max_log_size_) {
181 if (list_.size() > min_log_count_) { 186 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
182 start = list_.size(); 187 static_cast<int>(log_size));
183 size_t bytes_used = 0; 188 continue;
184 std::vector<LogHashPair>::const_reverse_iterator end = list_.rend();
185 for (std::vector<LogHashPair>::const_reverse_iterator it = list_.rbegin();
186 it != end; ++it) {
187 const size_t log_size = it->compressed_log_data.length();
188 if (bytes_used >= min_log_bytes_ &&
189 (list_.size() - start) >= min_log_count_) {
190 break;
191 }
192 bytes_used += log_size;
193 --start;
194 } 189 }
195 }
196 DCHECK_LT(start, list_.size());
197
198 for (size_t i = start; i < list_.size(); ++i) {
199 AppendBase64String(list_[i].compressed_log_data, list_value); 190 AppendBase64String(list_[i].compressed_log_data, list_value);
200 AppendBase64String(list_[i].hash, list_value); 191 AppendBase64String(list_[i].hash, list_value);
201 } 192 }
202 } 193 }
203 194
204 PersistedLogs::LogReadStatus PersistedLogs::ReadLogsFromPrefList( 195 PersistedLogs::LogReadStatus PersistedLogs::ReadLogsFromPrefList(
205 const base::ListValue& list_value) { 196 const base::ListValue& list_value) {
206 if (list_value.empty()) 197 if (list_value.empty())
207 return MakeRecallStatusHistogram(LIST_EMPTY); 198 return MakeRecallStatusHistogram(LIST_EMPTY);
208 199
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION); 280 return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION);
290 } 281 }
291 if (recovered_md5 != base::MD5DigestToBase16(digest)) { 282 if (recovered_md5 != base::MD5DigestToBase16(digest)) {
292 list_.clear(); 283 list_.clear();
293 return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION); 284 return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION);
294 } 285 }
295 return MakeRecallStatusHistogram(RECALL_SUCCESS); 286 return MakeRecallStatusHistogram(RECALL_SUCCESS);
296 } 287 }
297 288
298 } // namespace metrics 289 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/persisted_logs.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698