Index: chrome/common/metrics/metrics_log_manager.cc |
diff --git a/chrome/common/metrics/metrics_log_manager.cc b/chrome/common/metrics/metrics_log_manager.cc |
index a917bcf9c77cac457b12f0caafd544ce4bac0534..fa304a6fd76d044f5a865857808e5285d0c4c105 100644 |
--- a/chrome/common/metrics/metrics_log_manager.cc |
+++ b/chrome/common/metrics/metrics_log_manager.cc |
@@ -22,7 +22,9 @@ const char kDiscardedLog[] = "Log discarded"; |
} // anonymous namespace |
-MetricsLogManager::MetricsLogManager() : max_ongoing_log_store_size_(0) {} |
+MetricsLogManager::MetricsLogManager() : current_log_type_(INITIAL_LOG), |
+ staged_log_type_(INITIAL_LOG), |
+ max_ongoing_log_store_size_(0) {} |
MetricsLogManager::~MetricsLogManager() {} |
@@ -31,20 +33,41 @@ bool MetricsLogManager::SerializedLog::empty() const { |
return xml.empty(); |
} |
-void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log) { |
+void MetricsLogManager::SerializedLog::swap(SerializedLog& log) { |
+ xml.swap(log.xml); |
+ proto.swap(log.proto); |
+} |
+ |
+void MetricsLogManager::BeginLoggingWithLog(MetricsLogBase* log, |
+ LogType log_type) { |
DCHECK(!current_log_.get()); |
current_log_.reset(log); |
+ current_log_type_ = log_type; |
} |
-void MetricsLogManager::StageCurrentLogForUpload() { |
+void MetricsLogManager::FinishCurrentLog() { |
DCHECK(current_log_.get()); |
current_log_->CloseLog(); |
- staged_log_.reset(current_log_.release()); |
- CompressStagedLog(); |
+ SerializedLog compressed_log; |
+ CompressCurrentLog(&compressed_log); |
+ if (!compressed_log.empty()) |
+ StoreLog(&compressed_log, current_log_type_); |
+ current_log_.reset(); |
+} |
+ |
+void MetricsLogManager::StageNextLogForUpload() { |
+ // Prioritize initial logs for uploading. |
+ std::vector<SerializedLog>* source_list = |
+ unsent_initial_logs_.empty() ? &unsent_ongoing_logs_ |
+ : &unsent_initial_logs_; |
+ DCHECK(!source_list->empty()); |
+ DCHECK(staged_log_text_.empty()); |
+ staged_log_text_.swap(source_list->back()); |
+ source_list->pop_back(); |
} |
bool MetricsLogManager::has_staged_log() const { |
- return staged_log_.get() || !staged_log_text().empty(); |
+ return !staged_log_text().empty(); |
} |
bool MetricsLogManager::has_staged_log_proto() const { |
@@ -52,7 +75,6 @@ bool MetricsLogManager::has_staged_log_proto() const { |
} |
void MetricsLogManager::DiscardStagedLog() { |
- staged_log_.reset(); |
staged_log_text_.xml.clear(); |
staged_log_text_.proto.clear(); |
} |
@@ -76,49 +98,48 @@ void MetricsLogManager::ResumePausedLog() { |
current_log_.reset(paused_log_.release()); |
} |
-void MetricsLogManager::StoreStagedLogAsUnsent(LogType log_type) { |
+void MetricsLogManager::StoreStagedLogAsUnsent() { |
DCHECK(has_staged_log()); |
// If compressing the log failed, there's nothing to store. |
- if (staged_log_text().empty()) |
+ if (staged_log_text_.empty()) |
return; |
- if (log_type == INITIAL_LOG) { |
- unsent_initial_logs_.push_back(staged_log_text_); |
- } else { |
- // If it's too large, just note that and discard it. |
- if (max_ongoing_log_store_size_ && |
- staged_log_text().xml.length() > max_ongoing_log_store_size_) { |
- // TODO(isherman): We probably want a similar check for protobufs, but we |
- // don't want to prevent XML upload just because the protobuf version is |
- // too long. In practice, I'm pretty sure the XML version should always |
- // be longer, or at least on the same order of magnitude in length. |
- UMA_HISTOGRAM_COUNTS( |
- "UMA.Large Accumulated Log Not Persisted", |
- static_cast<int>(staged_log_text().xml.length())); |
- } else { |
- unsent_ongoing_logs_.push_back(staged_log_text_); |
- } |
- } |
+ StoreLog(&staged_log_text_, staged_log_type_); |
DiscardStagedLog(); |
} |
-void MetricsLogManager::StageNextStoredLogForUpload() { |
- // Prioritize initial logs for uploading. |
- std::vector<SerializedLog>* source_list = |
- unsent_initial_logs_.empty() ? |
- &unsent_ongoing_logs_ : |
- &unsent_initial_logs_; |
- DCHECK(!source_list->empty()); |
- DCHECK(staged_log_text().empty()); |
- staged_log_text_ = source_list->back(); |
- source_list->pop_back(); |
+void MetricsLogManager::StoreLog(SerializedLog* log_text, LogType log_type) { |
+ std::vector<SerializedLog>* destination_list = |
+ (log_type == INITIAL_LOG) ? &unsent_initial_logs_ |
+ : &unsent_ongoing_logs_; |
+ destination_list->push_back(SerializedLog()); |
+ destination_list->back().swap(*log_text); |
} |
void MetricsLogManager::PersistUnsentLogs() { |
DCHECK(log_serializer_.get()); |
if (!log_serializer_.get()) |
return; |
+ // Remove any ongoing logs that are over the serialization size limit. |
+ if (max_ongoing_log_store_size_) { |
+ for (std::vector<SerializedLog>::iterator it = unsent_ongoing_logs_.begin(); |
+ it != unsent_ongoing_logs_.end();) { |
+ size_t log_size = it->xml.length(); |
+ if (log_size > max_ongoing_log_store_size_) { |
+ // TODO(isherman): We probably want a similar check for protobufs, but |
+ // we don't want to prevent XML upload just because the protobuf version |
+ // is too long. In practice, I'm pretty sure the XML version should |
+ // always be longer, or at least on the same order of magnitude in |
+ // length. |
+ UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted", |
+ static_cast<int>(log_size)); |
+ it = unsent_ongoing_logs_.erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ } |
log_serializer_->SerializeLogs(unsent_initial_logs_, INITIAL_LOG); |
log_serializer_->SerializeLogs(unsent_ongoing_logs_, ONGOING_LOG); |
} |
@@ -131,21 +152,21 @@ void MetricsLogManager::LoadPersistedUnsentLogs() { |
log_serializer_->DeserializeLogs(ONGOING_LOG, &unsent_ongoing_logs_); |
} |
-void MetricsLogManager::CompressStagedLog() { |
- int text_size = staged_log_->GetEncodedLogSizeXml(); |
- std::string staged_log_text; |
+void MetricsLogManager::CompressCurrentLog(SerializedLog* compressed_log) { |
+ int text_size = current_log_->GetEncodedLogSizeXml(); |
DCHECK_GT(text_size, 0); |
- staged_log_->GetEncodedLogXml(WriteInto(&staged_log_text, text_size + 1), |
- text_size); |
+ std::string log_text; |
+ current_log_->GetEncodedLogXml(WriteInto(&log_text, text_size + 1), |
+ text_size); |
- bool success = Bzip2Compress(staged_log_text, &staged_log_text_.xml); |
+ bool success = Bzip2Compress(log_text, &(compressed_log->xml)); |
if (success) { |
// Allow security-conscious users to see all metrics logs that we send. |
- DVLOG(1) << "METRICS LOG: " << staged_log_text; |
+ DVLOG(1) << "METRICS LOG: " << log_text; |
// Note that we only save the protobuf version if we succeeded in |
// compressing the XML, so that the two data streams are the same. |
- staged_log_->GetEncodedLogProto(&staged_log_text_.proto); |
+ current_log_->GetEncodedLogProto(&(compressed_log->proto)); |
} else { |
NOTREACHED() << "Failed to compress log for transmission."; |
} |