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

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

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

Powered by Google App Engine
This is Rietveld 408576698