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

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"
Ilya Sherman 2013/10/16 18:26:14 It's probably not a big deal, but I wonder if some
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 bool MetricsLogManager::SerializedLog::IsEmpty() const {
15 return log_text.empty();
16 }
17
18 void MetricsLogManager::SerializedLog::Clear() {
19 log_text.clear();
20 log_hash.clear();
21 }
22
23 void MetricsLogManager::SerializedLog::Swap(
24 MetricsLogManager::SerializedLog* other) {
25 log_text.swap(other->log_text);
26 log_hash.swap(other->log_hash);
27 }
28
29 void MetricsLogManager::SerializedLog::UpdateHash() {
30 if (log_text.empty())
31 log_hash.clear();
32 else
33 log_hash = base::SHA1HashString(log_text);
34 }
Ilya Sherman 2013/10/16 18:26:14 It would be nice if the struct guaranteed that the
Alexei Svitkine (slow) 2013/10/16 19:31:46 Done.
35
13 MetricsLogManager::MetricsLogManager() 36 MetricsLogManager::MetricsLogManager()
14 : current_log_type_(NO_LOG), 37 : current_log_type_(NO_LOG),
15 paused_log_type_(NO_LOG), 38 paused_log_type_(NO_LOG),
16 staged_log_type_(NO_LOG), 39 staged_log_type_(NO_LOG),
17 max_ongoing_log_store_size_(0), 40 max_ongoing_log_store_size_(0),
18 last_provisional_store_index_(-1), 41 last_provisional_store_index_(-1),
19 last_provisional_store_type_(INITIAL_LOG) {} 42 last_provisional_store_type_(INITIAL_LOG) {}
20 43
21 MetricsLogManager::~MetricsLogManager() {} 44 MetricsLogManager::~MetricsLogManager() {}
22 45
23 void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log, 46 void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log,
24 LogType log_type) { 47 LogType log_type) {
25 DCHECK(log_type != NO_LOG); 48 DCHECK(log_type != NO_LOG);
26 DCHECK(!current_log_.get()); 49 DCHECK(!current_log_.get());
27 current_log_.reset(log); 50 current_log_.reset(log);
28 current_log_type_ = log_type; 51 current_log_type_ = log_type;
29 } 52 }
30 53
31 void MetricsLogManager::FinishCurrentLog() { 54 void MetricsLogManager::FinishCurrentLog() {
32 DCHECK(current_log_.get()); 55 DCHECK(current_log_.get());
33 DCHECK(current_log_type_ != NO_LOG); 56 DCHECK(current_log_type_ != NO_LOG);
34 current_log_->CloseLog(); 57 current_log_->CloseLog();
35 std::string compressed_log; 58 SerializedLog compressed_log;
36 CompressCurrentLog(&compressed_log); 59 CompressCurrentLog(&compressed_log);
37 if (!compressed_log.empty()) 60 if (!compressed_log.IsEmpty())
38 StoreLog(&compressed_log, current_log_type_, NORMAL_STORE); 61 StoreLog(&compressed_log, current_log_type_, NORMAL_STORE);
39 current_log_.reset(); 62 current_log_.reset();
40 current_log_type_ = NO_LOG; 63 current_log_type_ = NO_LOG;
41 } 64 }
42 65
43 void MetricsLogManager::StageNextLogForUpload() { 66 void MetricsLogManager::StageNextLogForUpload() {
44 // Prioritize initial logs for uploading. 67 // Prioritize initial logs for uploading.
45 std::vector<std::string>* source_list = 68 std::vector<SerializedLog>* source_list =
46 unsent_initial_logs_.empty() ? &unsent_ongoing_logs_ 69 unsent_initial_logs_.empty() ? &unsent_ongoing_logs_
47 : &unsent_initial_logs_; 70 : &unsent_initial_logs_;
48 LogType source_type = (source_list == &unsent_ongoing_logs_) ? ONGOING_LOG 71 LogType source_type = (source_list == &unsent_ongoing_logs_) ? ONGOING_LOG
49 : INITIAL_LOG; 72 : INITIAL_LOG;
50 // CHECK, rather than DCHECK, because swap()ing with an empty list causes 73 // CHECK, rather than DCHECK, because swap()ing with an empty list causes
51 // hard-to-identify crashes much later. 74 // hard-to-identify crashes much later.
52 CHECK(!source_list->empty()); 75 CHECK(!source_list->empty());
53 DCHECK(staged_log_text_.empty()); 76 DCHECK(staged_log_.IsEmpty());
54 DCHECK(staged_log_type_ == NO_LOG); 77 DCHECK(staged_log_type_ == NO_LOG);
55 staged_log_text_.swap(source_list->back()); 78 staged_log_.Swap(&source_list->back());
56 staged_log_type_ = source_type; 79 staged_log_type_ = source_type;
57 source_list->pop_back(); 80 source_list->pop_back();
58 81
59 // If the staged log was the last provisional store, clear that. 82 // If the staged log was the last provisional store, clear that.
60 if (last_provisional_store_index_ != -1) { 83 if (last_provisional_store_index_ != -1) {
61 if (source_type == last_provisional_store_type_ && 84 if (source_type == last_provisional_store_type_ &&
62 static_cast<unsigned int>(last_provisional_store_index_) == 85 static_cast<unsigned int>(last_provisional_store_index_) ==
63 source_list->size()) { 86 source_list->size()) {
64 last_provisional_store_index_ = -1; 87 last_provisional_store_index_ = -1;
65 } 88 }
66 } 89 }
67 } 90 }
68 91
69 bool MetricsLogManager::has_staged_log() const { 92 bool MetricsLogManager::has_staged_log() const {
70 return !staged_log_text().empty(); 93 return !staged_log_.IsEmpty();
71 } 94 }
72 95
73 void MetricsLogManager::DiscardStagedLog() { 96 void MetricsLogManager::DiscardStagedLog() {
74 staged_log_text_.clear(); 97 staged_log_.Clear();
75 staged_log_type_ = NO_LOG; 98 staged_log_type_ = NO_LOG;
76 } 99 }
77 100
78 void MetricsLogManager::DiscardCurrentLog() { 101 void MetricsLogManager::DiscardCurrentLog() {
79 current_log_->CloseLog(); 102 current_log_->CloseLog();
80 current_log_.reset(); 103 current_log_.reset();
81 current_log_type_ = NO_LOG; 104 current_log_type_ = NO_LOG;
82 } 105 }
83 106
84 void MetricsLogManager::PauseCurrentLog() { 107 void MetricsLogManager::PauseCurrentLog() {
85 DCHECK(!paused_log_.get()); 108 DCHECK(!paused_log_.get());
86 DCHECK(paused_log_type_ == NO_LOG); 109 DCHECK(paused_log_type_ == NO_LOG);
87 paused_log_.reset(current_log_.release()); 110 paused_log_.reset(current_log_.release());
88 paused_log_type_ = current_log_type_; 111 paused_log_type_ = current_log_type_;
89 current_log_type_ = NO_LOG; 112 current_log_type_ = NO_LOG;
90 } 113 }
91 114
92 void MetricsLogManager::ResumePausedLog() { 115 void MetricsLogManager::ResumePausedLog() {
93 DCHECK(!current_log_.get()); 116 DCHECK(!current_log_.get());
94 DCHECK(current_log_type_ == NO_LOG); 117 DCHECK(current_log_type_ == NO_LOG);
95 current_log_.reset(paused_log_.release()); 118 current_log_.reset(paused_log_.release());
96 current_log_type_ = paused_log_type_; 119 current_log_type_ = paused_log_type_;
97 paused_log_type_ = NO_LOG; 120 paused_log_type_ = NO_LOG;
98 } 121 }
99 122
100 void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) { 123 void MetricsLogManager::StoreStagedLogAsUnsent(StoreType store_type) {
101 DCHECK(has_staged_log()); 124 DCHECK(has_staged_log());
102 125
103 // If compressing the log failed, there's nothing to store. 126 // If compressing the log failed, there's nothing to store.
104 if (staged_log_text_.empty()) 127 if (staged_log_.IsEmpty())
105 return; 128 return;
106 129
107 StoreLog(&staged_log_text_, staged_log_type_, store_type); 130 StoreLog(&staged_log_, staged_log_type_, store_type);
108 DiscardStagedLog(); 131 DiscardStagedLog();
109 } 132 }
110 133
111 void MetricsLogManager::StoreLog(std::string* log_text, 134 void MetricsLogManager::StoreLog(SerializedLog* log,
112 LogType log_type, 135 LogType log_type,
113 StoreType store_type) { 136 StoreType store_type) {
114 DCHECK(log_type != NO_LOG); 137 DCHECK(log_type != NO_LOG);
115 std::vector<std::string>* destination_list = 138 std::vector<SerializedLog>* destination_list =
116 (log_type == INITIAL_LOG) ? &unsent_initial_logs_ 139 (log_type == INITIAL_LOG) ? &unsent_initial_logs_
117 : &unsent_ongoing_logs_; 140 : &unsent_ongoing_logs_;
118 destination_list->push_back(std::string()); 141 destination_list->push_back(SerializedLog());
119 destination_list->back().swap(*log_text); 142 destination_list->back().Swap(log);
120 143
121 if (store_type == PROVISIONAL_STORE) { 144 if (store_type == PROVISIONAL_STORE) {
122 last_provisional_store_index_ = destination_list->size() - 1; 145 last_provisional_store_index_ = destination_list->size() - 1;
123 last_provisional_store_type_ = log_type; 146 last_provisional_store_type_ = log_type;
124 } 147 }
125 } 148 }
126 149
127 void MetricsLogManager::DiscardLastProvisionalStore() { 150 void MetricsLogManager::DiscardLastProvisionalStore() {
128 if (last_provisional_store_index_ == -1) 151 if (last_provisional_store_index_ == -1)
129 return; 152 return;
130 std::vector<std::string>* source_list = 153 std::vector<SerializedLog>* source_list =
131 (last_provisional_store_type_ == ONGOING_LOG) ? &unsent_ongoing_logs_ 154 (last_provisional_store_type_ == ONGOING_LOG) ? &unsent_ongoing_logs_
132 : &unsent_initial_logs_; 155 : &unsent_initial_logs_;
133 DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_), 156 DCHECK_LT(static_cast<unsigned int>(last_provisional_store_index_),
134 source_list->size()); 157 source_list->size());
135 source_list->erase(source_list->begin() + last_provisional_store_index_); 158 source_list->erase(source_list->begin() + last_provisional_store_index_);
136 last_provisional_store_index_ = -1; 159 last_provisional_store_index_ = -1;
137 } 160 }
138 161
139 void MetricsLogManager::PersistUnsentLogs() { 162 void MetricsLogManager::PersistUnsentLogs() {
140 DCHECK(log_serializer_.get()); 163 DCHECK(log_serializer_.get());
141 if (!log_serializer_.get()) 164 if (!log_serializer_.get())
142 return; 165 return;
143 // Remove any ongoing logs that are over the serialization size limit. 166 // Remove any ongoing logs that are over the serialization size limit.
144 if (max_ongoing_log_store_size_) { 167 if (max_ongoing_log_store_size_) {
145 for (std::vector<std::string>::iterator it = unsent_ongoing_logs_.begin(); 168 for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin();
146 it != unsent_ongoing_logs_.end();) { 169 it != unsent_ongoing_logs_.end();) {
147 size_t log_size = it->length(); 170 size_t log_size = it->log_text.length();
148 if (log_size > max_ongoing_log_store_size_) { 171 if (log_size > max_ongoing_log_store_size_) {
149 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted", 172 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted",
150 static_cast<int>(log_size)); 173 static_cast<int>(log_size));
151 it = unsent_ongoing_logs_.erase(it); 174 it = unsent_ongoing_logs_.erase(it);
152 } else { 175 } else {
153 ++it; 176 ++it;
154 } 177 }
155 } 178 }
156 } 179 }
157 log_serializer_->SerializeLogs(unsent_initial_logs_, INITIAL_LOG); 180 log_serializer_->SerializeLogs(unsent_initial_logs_, INITIAL_LOG);
158 log_serializer_->SerializeLogs(unsent_ongoing_logs_, ONGOING_LOG); 181 log_serializer_->SerializeLogs(unsent_ongoing_logs_, ONGOING_LOG);
159 } 182 }
160 183
161 void MetricsLogManager::LoadPersistedUnsentLogs() { 184 void MetricsLogManager::LoadPersistedUnsentLogs() {
162 DCHECK(log_serializer_.get()); 185 DCHECK(log_serializer_.get());
163 if (!log_serializer_.get()) 186 if (!log_serializer_.get())
164 return; 187 return;
165 log_serializer_->DeserializeLogs(INITIAL_LOG, &unsent_initial_logs_); 188 log_serializer_->DeserializeLogs(INITIAL_LOG, &unsent_initial_logs_);
166 log_serializer_->DeserializeLogs(ONGOING_LOG, &unsent_ongoing_logs_); 189 log_serializer_->DeserializeLogs(ONGOING_LOG, &unsent_ongoing_logs_);
167 } 190 }
168 191
169 void MetricsLogManager::CompressCurrentLog(std::string* compressed_log) { 192 void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) {
170 current_log_->GetEncodedLog(compressed_log); 193 current_log_->GetEncodedLog(&compressed_log->log_text);
194 compressed_log->UpdateHash();
171 } 195 }
OLDNEW
« chrome/common/metrics/metrics_log_manager.h ('K') | « chrome/common/metrics/metrics_log_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698