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

Side by Side Diff: chrome/browser/metrics/metrics_service.cc

Issue 9232071: Upload UMA data using protocol buffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 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 //------------------------------------------------------------------------------ 5 //------------------------------------------------------------------------------
6 // Description of the life cycle of a instance of MetricsService. 6 // Description of the life cycle of a instance of MetricsService.
7 // 7 //
8 // OVERVIEW 8 // OVERVIEW
9 // 9 //
10 // A MetricsService instance is typically created at application startup. It 10 // A MetricsService instance is typically created at application startup. It
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 #include "chrome/browser/chromeos/cros/cros_library.h" 193 #include "chrome/browser/chromeos/cros/cros_library.h"
194 #include "chrome/browser/chromeos/external_metrics.h" 194 #include "chrome/browser/chromeos/external_metrics.h"
195 #include "chrome/browser/chromeos/system/statistics_provider.h" 195 #include "chrome/browser/chromeos/system/statistics_provider.h"
196 #endif 196 #endif
197 197
198 using base::Time; 198 using base::Time;
199 using content::BrowserThread; 199 using content::BrowserThread;
200 using content::ChildProcessData; 200 using content::ChildProcessData;
201 using content::PluginService; 201 using content::PluginService;
202 202
203 namespace {
204
203 // Check to see that we're being called on only one thread. 205 // Check to see that we're being called on only one thread.
204 static bool IsSingleThreaded(); 206 bool IsSingleThreaded() {
207 static base::PlatformThreadId thread_id = 0;
208 if (!thread_id)
209 thread_id = base::PlatformThread::CurrentId();
210 return base::PlatformThread::CurrentId() == thread_id;
211 }
205 212
206 static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; 213 const char kMetricsTypeXml[] = "application/vnd.mozilla.metrics.bz2";
214 // TODO(isherman): What should the MIME type be?
215 const char kMetricsTypeProto[] = "application/vnd.chrome.uma";
216
217 const char kServerUrlXml[] =
218 "https://clients4.google.com/firefox/metrics/collect";
219 // TODO(isherman): Update to a real URL...
220 const char kServerUrlProto[] = "http://isherman.mtv.corp.google.com:8888/uma";
207 221
208 // The delay, in seconds, after starting recording before doing expensive 222 // The delay, in seconds, after starting recording before doing expensive
209 // initialization work. 223 // initialization work.
210 static const int kInitializationDelaySeconds = 30; 224 const int kInitializationDelaySeconds = 30;
211 225
212 // This specifies the amount of time to wait for all renderers to send their 226 // This specifies the amount of time to wait for all renderers to send their
213 // data. 227 // data.
214 static const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. 228 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds.
215 229
216 // The maximum number of events in a log uploaded to the UMA server. 230 // The maximum number of events in a log uploaded to the UMA server.
217 static const int kEventLimit = 2400; 231 const int kEventLimit = 2400;
218 232
219 // If an upload fails, and the transmission was over this byte count, then we 233 // If an upload fails, and the transmission was over this byte count, then we
220 // will discard the log, and not try to retransmit it. We also don't persist 234 // will discard the log, and not try to retransmit it. We also don't persist
221 // the log to the prefs for transmission during the next chrome session if this 235 // the log to the prefs for transmission during the next chrome session if this
222 // limit is exceeded. 236 // limit is exceeded.
223 static const int kUploadLogAvoidRetransmitSize = 50000; 237 const size_t kUploadLogAvoidRetransmitSize = 50000;
224 238
225 // Interval, in minutes, between state saves. 239 // Interval, in minutes, between state saves.
226 static const int kSaveStateIntervalMinutes = 5; 240 const int kSaveStateIntervalMinutes = 5;
241
242 }
227 243
228 // static 244 // static
229 MetricsService::ShutdownCleanliness MetricsService::clean_shutdown_status_ = 245 MetricsService::ShutdownCleanliness MetricsService::clean_shutdown_status_ =
230 MetricsService::CLEANLY_SHUTDOWN; 246 MetricsService::CLEANLY_SHUTDOWN;
231 247
232 // This is used to quickly log stats from child process related notifications in 248 // This is used to quickly log stats from child process related notifications in
233 // MetricsService::child_stats_buffer_. The buffer's contents are transferred 249 // MetricsService::child_stats_buffer_. The buffer's contents are transferred
234 // out when Local State is periodically saved. The information is then 250 // out when Local State is periodically saved. The information is then
235 // reported to the UMA server on next launch. 251 // reported to the UMA server on next launch.
236 struct MetricsService::ChildProcessStats { 252 struct MetricsService::ChildProcessStats {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 0); 332 0);
317 #endif // OS_CHROMEOS 333 #endif // OS_CHROMEOS
318 334
319 local_state->RegisterDictionaryPref(prefs::kProfileMetrics); 335 local_state->RegisterDictionaryPref(prefs::kProfileMetrics);
320 local_state->RegisterIntegerPref(prefs::kNumBookmarksOnBookmarkBar, 0); 336 local_state->RegisterIntegerPref(prefs::kNumBookmarksOnBookmarkBar, 0);
321 local_state->RegisterIntegerPref(prefs::kNumFoldersOnBookmarkBar, 0); 337 local_state->RegisterIntegerPref(prefs::kNumFoldersOnBookmarkBar, 0);
322 local_state->RegisterIntegerPref(prefs::kNumBookmarksInOtherBookmarkFolder, 338 local_state->RegisterIntegerPref(prefs::kNumBookmarksInOtherBookmarkFolder,
323 0); 339 0);
324 local_state->RegisterIntegerPref(prefs::kNumFoldersInOtherBookmarkFolder, 0); 340 local_state->RegisterIntegerPref(prefs::kNumFoldersInOtherBookmarkFolder, 0);
325 local_state->RegisterIntegerPref(prefs::kNumKeywords, 0); 341 local_state->RegisterIntegerPref(prefs::kNumKeywords, 0);
326 local_state->RegisterListPref(prefs::kMetricsInitialLogs); 342 local_state->RegisterListPref(prefs::kMetricsInitialLogsXml);
327 local_state->RegisterListPref(prefs::kMetricsOngoingLogs); 343 local_state->RegisterListPref(prefs::kMetricsOngoingLogsXml);
344 local_state->RegisterListPref(prefs::kMetricsInitialLogsProto);
345 local_state->RegisterListPref(prefs::kMetricsOngoingLogsProto);
328 346
329 local_state->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0); 347 local_state->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0);
330 local_state->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0); 348 local_state->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0);
331 local_state->RegisterInt64Pref(prefs::kUninstallMetricsInstallDate, 0); 349 local_state->RegisterInt64Pref(prefs::kUninstallMetricsInstallDate, 0);
332 local_state->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0); 350 local_state->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0);
333 local_state->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0); 351 local_state->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
334 local_state->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0); 352 local_state->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
335 } 353 }
336 354
337 // static 355 // static
(...skipping 12 matching lines...) Expand all
350 368
351 local_state->SetInteger(prefs::kStabilityPageLoadCount, 0); 369 local_state->SetInteger(prefs::kStabilityPageLoadCount, 0);
352 local_state->SetInteger(prefs::kStabilityRendererCrashCount, 0); 370 local_state->SetInteger(prefs::kStabilityRendererCrashCount, 0);
353 local_state->SetInteger(prefs::kStabilityRendererHangCount, 0); 371 local_state->SetInteger(prefs::kStabilityRendererHangCount, 0);
354 372
355 local_state->SetInt64(prefs::kStabilityLaunchTimeSec, 0); 373 local_state->SetInt64(prefs::kStabilityLaunchTimeSec, 0);
356 local_state->SetInt64(prefs::kStabilityLastTimestampSec, 0); 374 local_state->SetInt64(prefs::kStabilityLastTimestampSec, 0);
357 375
358 local_state->ClearPref(prefs::kStabilityPluginStats); 376 local_state->ClearPref(prefs::kStabilityPluginStats);
359 377
360 local_state->ClearPref(prefs::kMetricsInitialLogs); 378 local_state->ClearPref(prefs::kMetricsInitialLogsXml);
361 local_state->ClearPref(prefs::kMetricsOngoingLogs); 379 local_state->ClearPref(prefs::kMetricsOngoingLogsXml);
380 local_state->ClearPref(prefs::kMetricsInitialLogsProto);
381 local_state->ClearPref(prefs::kMetricsOngoingLogsProto);
362 } 382 }
363 383
364 MetricsService::MetricsService() 384 MetricsService::MetricsService()
365 : recording_active_(false), 385 : recording_active_(false),
366 reporting_active_(false), 386 reporting_active_(false),
367 state_(INITIALIZED), 387 state_(INITIALIZED),
368 current_fetch_(NULL),
369 io_thread_(NULL), 388 io_thread_(NULL),
370 idle_since_last_transmission_(false), 389 idle_since_last_transmission_(false),
371 next_window_id_(0), 390 next_window_id_(0),
372 ALLOW_THIS_IN_INITIALIZER_LIST(log_sender_factory_(this)), 391 ALLOW_THIS_IN_INITIALIZER_LIST(log_sender_factory_(this)),
373 ALLOW_THIS_IN_INITIALIZER_LIST(state_saver_factory_(this)), 392 ALLOW_THIS_IN_INITIALIZER_LIST(state_saver_factory_(this)),
374 waiting_for_asynchronus_reporting_step_(false) { 393 waiting_for_asynchronus_reporting_step_(false) {
375 DCHECK(IsSingleThreaded()); 394 DCHECK(IsSingleThreaded());
376 InitializeMetricsState(); 395 InitializeMetricsState();
377 396
378 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, 397 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload,
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 //------------------------------------------------------------------------------ 636 //------------------------------------------------------------------------------
618 // private methods 637 // private methods
619 //------------------------------------------------------------------------------ 638 //------------------------------------------------------------------------------
620 639
621 640
622 //------------------------------------------------------------------------------ 641 //------------------------------------------------------------------------------
623 // Initialization methods 642 // Initialization methods
624 643
625 void MetricsService::InitializeMetricsState() { 644 void MetricsService::InitializeMetricsState() {
626 #if defined(OS_POSIX) 645 #if defined(OS_POSIX)
627 server_url_ = L"https://clients4.google.com/firefox/metrics/collect"; 646 server_url_xml_ = ASCIIToUTF16(kServerUrlXml);
647 server_url_proto_ = ASCIIToUTF16(kServerUrlProto);
628 network_stats_server_ = "chrome.googleechotest.com"; 648 network_stats_server_ = "chrome.googleechotest.com";
629 #else 649 #else
630 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 650 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
631 server_url_ = dist->GetStatsServerURL(); 651 server_url_xml_ = dist->GetStatsServerURL();
652 // TODO(isherman): Hmm, do distribution channels sometimes specify other
653 // servers?
Ilya Sherman 2012/01/28 08:17:20 Jim, Ian, do you know how this works and/or whethe
654 server_url_proto_ = ASCIIToUTF16(kServerUrlProto);
632 network_stats_server_ = dist->GetNetworkStatsServer(); 655 network_stats_server_ = dist->GetNetworkStatsServer();
633 #endif 656 #endif
634 657
635 PrefService* pref = g_browser_process->local_state(); 658 PrefService* pref = g_browser_process->local_state();
636 DCHECK(pref); 659 DCHECK(pref);
637 660
638 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) 661 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime)
639 != MetricsLog::GetBuildTime()) || 662 != MetricsLog::GetBuildTime()) ||
640 (pref->GetString(prefs::kStabilityStatsVersion) 663 (pref->GetString(prefs::kStabilityStatsVersion)
641 != MetricsLog::GetVersionString())) { 664 != MetricsLog::GetVersionString())) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // Adds to ongoing logs. 851 // Adds to ongoing logs.
829 log_manager_.current_log()->set_hardware_class(hardware_class_); 852 log_manager_.current_log()->set_hardware_class(hardware_class_);
830 853
831 // Put incremental data (histogram deltas, and realtime stats deltas) at the 854 // Put incremental data (histogram deltas, and realtime stats deltas) at the
832 // end of all log transmissions (initial log handles this separately). 855 // end of all log transmissions (initial log handles this separately).
833 // RecordIncrementalStabilityElements only exists on the derived 856 // RecordIncrementalStabilityElements only exists on the derived
834 // MetricsLog class. 857 // MetricsLog class.
835 MetricsLog* current_log = 858 MetricsLog* current_log =
836 static_cast<MetricsLog*>(log_manager_.current_log()); 859 static_cast<MetricsLog*>(log_manager_.current_log());
837 DCHECK(current_log); 860 DCHECK(current_log);
838 current_log->RecordIncrementalStabilityElements(); 861 current_log->RecordIncrementalStabilityElements(plugins_);
839 RecordCurrentHistograms(); 862 RecordCurrentHistograms();
840 863
841 log_manager_.StageCurrentLogForUpload(); 864 log_manager_.StageCurrentLogForUpload();
842 } 865 }
843 866
844 void MetricsService::PushPendingLogsToPersistentStorage() { 867 void MetricsService::PushPendingLogsToPersistentStorage() {
845 if (state_ < INITIAL_LOG_READY) 868 if (state_ < INITIAL_LOG_READY)
846 return; // We didn't and still don't have time to get plugin list etc. 869 return; // We didn't and still don't have time to get plugin list etc.
847 870
848 if (log_manager_.has_staged_log()) { 871 if (log_manager_.has_staged_log()) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 MessageLoop::current(), callback, 946 MessageLoop::current(), callback,
924 kMaxHistogramGatheringWaitDuration); 947 kMaxHistogramGatheringWaitDuration);
925 } 948 }
926 949
927 void MetricsService::OnHistogramSynchronizationDone() { 950 void MetricsService::OnHistogramSynchronizationDone() {
928 DCHECK(IsSingleThreaded()); 951 DCHECK(IsSingleThreaded());
929 952
930 // If somehow there is a fetch in progress, we return and hope things work 953 // If somehow there is a fetch in progress, we return and hope things work
931 // out. The scheduler isn't informed since if this happens, the scheduler 954 // out. The scheduler isn't informed since if this happens, the scheduler
932 // will get a response from the upload. 955 // will get a response from the upload.
933 DCHECK(!current_fetch_.get()); 956 DCHECK(!current_fetch_xml_.get());
934 if (current_fetch_.get()) 957 DCHECK(!current_fetch_proto_.get());
958 if (current_fetch_xml_.get() || current_fetch_proto_.get())
935 return; 959 return;
936 960
937 // This function should only be called as the callback from an ansynchronous 961 // This function should only be called as the callback from an ansynchronous
938 // step. 962 // step.
939 DCHECK(waiting_for_asynchronus_reporting_step_); 963 DCHECK(waiting_for_asynchronus_reporting_step_);
940 waiting_for_asynchronus_reporting_step_ = false; 964 waiting_for_asynchronus_reporting_step_ = false;
941 965
942 // If we're getting no notifications, then the log won't have much in it, and 966 // If we're getting no notifications, then the log won't have much in it, and
943 // it's possible the computer is about to go to sleep, so don't upload and 967 // it's possible the computer is about to go to sleep, so don't upload and
944 // stop the scheduler. 968 // stop the scheduler.
945 // Similarly, if logs should no longer be uploaded, stop here. 969 // Similarly, if logs should no longer be uploaded, stop here.
946 if (idle_since_last_transmission_ || 970 if (idle_since_last_transmission_ ||
947 !recording_active() || !reporting_active()) { 971 !recording_active() || !reporting_active()) {
948 scheduler_->Stop(); 972 scheduler_->Stop();
949 scheduler_->UploadCancelled(); 973 scheduler_->UploadCancelled();
950 return; 974 return;
951 } 975 }
952 976
953 MakeStagedLog(); 977 MakeStagedLog();
954 978
955 // MakeStagedLog should have prepared log text; if it didn't, skip this 979 // MakeStagedLog should have prepared log text; if it didn't, skip this
956 // upload and hope things work out next time. 980 // upload and hope things work out next time.
957 if (log_manager_.staged_log_text().empty()) { 981 if (log_manager_.staged_log_text_xml().empty()) {
958 scheduler_->UploadCancelled(); 982 scheduler_->UploadCancelled();
959 return; 983 return;
960 } 984 }
961 985
962 PrepareFetchWithStagedLog(); 986 PrepareFetchWithStagedLog();
963 987
964 if (!current_fetch_.get()) { 988 if (!current_fetch_xml_.get()) {
989 DCHECK(!current_fetch_proto_.get());
965 // Compression failed, and log discarded :-/. 990 // Compression failed, and log discarded :-/.
966 log_manager_.DiscardStagedLog(); 991 log_manager_.DiscardStagedLog();
967 scheduler_->UploadCancelled(); 992 scheduler_->UploadCancelled();
968 // TODO(jar): If compression failed, we should have created a tiny log and 993 // TODO(jar): If compression failed, we should have created a tiny log and
969 // compressed that, so that we can signal that we're losing logs. 994 // compressed that, so that we can signal that we're losing logs.
970 return; 995 return;
971 } 996 }
997 DCHECK(current_fetch_proto_.get());
972 998
973 DCHECK(!waiting_for_asynchronus_reporting_step_); 999 DCHECK(!waiting_for_asynchronus_reporting_step_);
974 1000
975 waiting_for_asynchronus_reporting_step_ = true; 1001 waiting_for_asynchronus_reporting_step_ = true;
976 current_fetch_->Start(); 1002 current_fetch_xml_->Start();
1003 current_fetch_proto_->Start();
977 1004
978 HandleIdleSinceLastTransmission(true); 1005 HandleIdleSinceLastTransmission(true);
979 } 1006 }
980 1007
981 1008
982 void MetricsService::MakeStagedLog() { 1009 void MetricsService::MakeStagedLog() {
983 if (log_manager_.has_staged_log()) 1010 if (log_manager_.has_staged_log())
984 return; 1011 return;
985 1012
986 switch (state_) { 1013 switch (state_) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 } 1066 }
1040 1067
1041 void MetricsService::StoreUnsentLogs() { 1068 void MetricsService::StoreUnsentLogs() {
1042 if (state_ < INITIAL_LOG_READY) 1069 if (state_ < INITIAL_LOG_READY)
1043 return; // We never Recalled the prior unsent logs. 1070 return; // We never Recalled the prior unsent logs.
1044 1071
1045 log_manager_.PersistUnsentLogs(); 1072 log_manager_.PersistUnsentLogs();
1046 } 1073 }
1047 1074
1048 void MetricsService::PrepareFetchWithStagedLog() { 1075 void MetricsService::PrepareFetchWithStagedLog() {
1049 DCHECK(!log_manager_.staged_log_text().empty()); 1076 // Prepare the XML version.
1050 DCHECK(!current_fetch_.get()); 1077 DCHECK(!log_manager_.staged_log_text_xml().empty());
1078 DCHECK(!current_fetch_xml_.get());
1079 current_fetch_xml_.reset(content::URLFetcher::Create(
1080 GURL(server_url_xml_), content::URLFetcher::POST, this));
1081 current_fetch_xml_->SetRequestContext(
1082 g_browser_process->system_request_context());
1083 current_fetch_xml_->SetUploadData(kMetricsTypeXml,
1084 log_manager_.staged_log_text_xml());
1051 1085
1052 current_fetch_.reset(content::URLFetcher::Create( 1086 // Prepare the protobuf version.
1053 GURL(WideToUTF16(server_url_)), content::URLFetcher::POST, this)); 1087 DCHECK(!log_manager_.staged_log_text_proto().empty());
1054 current_fetch_->SetRequestContext( 1088 DCHECK(!current_fetch_proto_.get());
1089 current_fetch_proto_.reset(content::URLFetcher::Create(
1090 GURL(server_url_proto_), content::URLFetcher::POST, this));
1091 current_fetch_proto_->SetRequestContext(
1055 g_browser_process->system_request_context()); 1092 g_browser_process->system_request_context());
1056 current_fetch_->SetUploadData(kMetricsType, log_manager_.staged_log_text()); 1093 current_fetch_proto_->SetUploadData(kMetricsTypeProto,
1094 log_manager_.staged_log_text_proto());
1057 } 1095 }
1058 1096
1059 static const char* StatusToString(const net::URLRequestStatus& status) { 1097 static const char* StatusToString(const net::URLRequestStatus& status) {
1060 switch (status.status()) { 1098 switch (status.status()) {
1061 case net::URLRequestStatus::SUCCESS: 1099 case net::URLRequestStatus::SUCCESS:
1062 return "SUCCESS"; 1100 return "SUCCESS";
1063 1101
1064 case net::URLRequestStatus::IO_PENDING: 1102 case net::URLRequestStatus::IO_PENDING:
1065 return "IO_PENDING"; 1103 return "IO_PENDING";
1066 1104
1067 case net::URLRequestStatus::HANDLED_EXTERNALLY: 1105 case net::URLRequestStatus::HANDLED_EXTERNALLY:
1068 return "HANDLED_EXTERNALLY"; 1106 return "HANDLED_EXTERNALLY";
1069 1107
1070 case net::URLRequestStatus::CANCELED: 1108 case net::URLRequestStatus::CANCELED:
1071 return "CANCELED"; 1109 return "CANCELED";
1072 1110
1073 case net::URLRequestStatus::FAILED: 1111 case net::URLRequestStatus::FAILED:
1074 return "FAILED"; 1112 return "FAILED";
1075 1113
1076 default: 1114 default:
1077 NOTREACHED(); 1115 NOTREACHED();
1078 return "Unknown"; 1116 return "Unknown";
1079 } 1117 }
1080 } 1118 }
1081 1119
1120 // We need to wait for two responses: the response to the XML upload, and the
1121 // response to the protobuf upload. For now, only the XML upload's response
1122 // affects decisions like whether to retry the upload, whether to abandon the
1123 // upload because it is too large, etc. However, we still need to wait for the
1124 // protobuf upload, as we cannot reset |current_fetch_proto_| until we have
1125 // confirmation that the network request was sent; and the easiest way to do
1126 // that is to wait for the response. In case the XML upload's response arrives
1127 // first, we cache that response until the protobuf upload's response also
1128 // arrives.
Ilya Sherman 2012/01/28 08:17:20 Reviewers: Does this approach (i.e. waiting for bo
1082 void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { 1129 void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) {
1083 DCHECK(waiting_for_asynchronus_reporting_step_); 1130 DCHECK(waiting_for_asynchronus_reporting_step_);
1131
1132 // We're not allowed to re-use the existing |URLFetcher|s, so free them here.
1133 scoped_ptr<content::URLFetcher> s;
1134 if (source == current_fetch_xml_.get()) {
1135 s.reset(current_fetch_xml_.release());
1136
1137 // Cache the XML responses, in case we still need to wait for the protobuf
1138 // response.
1139 response_code_ = source->GetResponseCode();
1140 response_status_ = StatusToString(source->GetStatus());
1141 source->GetResponseAsString(&response_data_);
1142 } else if (source == current_fetch_proto_.get()) {
1143 s.reset(current_fetch_proto_.release());
1144 } else {
1145 NOTREACHED();
1146 return;
1147 }
1148
1149 // If we're still waiting for one of the responses, keep waiting...
1150 if (current_fetch_xml_.get() || current_fetch_proto_.get())
1151 return;
1152
1153 // We should only be able to reach here once we've received responses to both
1154 // the XML and the protobuf requests. We should always have the response code
1155 // available.
1156 DCHECK_NE(response_code_, content::URLFetcher::RESPONSE_CODE_INVALID);
1084 waiting_for_asynchronus_reporting_step_ = false; 1157 waiting_for_asynchronus_reporting_step_ = false;
1085 DCHECK(current_fetch_.get()); 1158
1086 // We're not allowed to re-use it. Delete it on function exit since we use it.
1087 scoped_ptr<content::URLFetcher> s(current_fetch_.release());
1088 1159
1089 // Confirm send so that we can move on. 1160 // Confirm send so that we can move on.
1090 VLOG(1) << "METRICS RESPONSE CODE: " << source->GetResponseCode() 1161 VLOG(1) << "METRICS RESPONSE CODE: " << response_code_
1091 << " status=" << StatusToString(source->GetStatus()); 1162 << " status=" << response_status_;
1092 1163
1093 bool upload_succeeded = source->GetResponseCode() == 200; 1164 bool upload_succeeded = response_code_ == 200;
1094 1165
1095 // Provide boolean for error recovery (allow us to ignore response_code). 1166 // Provide boolean for error recovery (allow us to ignore response_code).
1096 bool discard_log = false; 1167 bool discard_log = false;
1097 1168
1098 if (!upload_succeeded && 1169 if (!upload_succeeded &&
1099 (log_manager_.staged_log_text().length() > 1170 log_manager_.staged_log_text_xml().length() >
1100 static_cast<size_t>(kUploadLogAvoidRetransmitSize))) { 1171 kUploadLogAvoidRetransmitSize) {
1101 UMA_HISTOGRAM_COUNTS( 1172 UMA_HISTOGRAM_COUNTS(
1102 "UMA.Large Rejected Log was Discarded", 1173 "UMA.Large Rejected Log was Discarded",
1103 static_cast<int>(log_manager_.staged_log_text().length())); 1174 static_cast<int>(log_manager_.staged_log_text_xml().length()));
1104 discard_log = true; 1175 discard_log = true;
1105 } else if (source->GetResponseCode() == 400) { 1176 } else if (response_code_ == 400) {
1106 // Bad syntax. Retransmission won't work. 1177 // Bad syntax. Retransmission won't work.
1107 UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_); 1178 UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_);
1108 discard_log = true; 1179 discard_log = true;
1109 } 1180 }
1110 1181
1111 if (!upload_succeeded && !discard_log) { 1182 if (!upload_succeeded && !discard_log) {
1112 VLOG(1) << "METRICS: transmission attempt returned a failure code: " 1183 VLOG(1) << "METRICS: transmission attempt returned a failure code: "
1113 << source->GetResponseCode() << ". Verify network connectivity"; 1184 << response_code_ << ". Verify network connectivity";
1114 LogBadResponseCode(); 1185 LogBadResponseCode();
1115 } else { // Successful receipt (or we are discarding log). 1186 } else { // Successful receipt (or we are discarding log).
1116 std::string data; 1187 VLOG(1) << "METRICS RESPONSE DATA: " << response_data_;
1117 source->GetResponseAsString(&data);
1118 VLOG(1) << "METRICS RESPONSE DATA: " << data;
1119 switch (state_) { 1188 switch (state_) {
1120 case INITIAL_LOG_READY: 1189 case INITIAL_LOG_READY:
1121 state_ = SENDING_OLD_LOGS; 1190 state_ = SENDING_OLD_LOGS;
1122 break; 1191 break;
1123 1192
1124 case SENDING_OLD_LOGS: 1193 case SENDING_OLD_LOGS:
1125 // Store the updated list to disk now that the removed log is uploaded. 1194 // Store the updated list to disk now that the removed log is uploaded.
1126 StoreUnsentLogs(); 1195 StoreUnsentLogs();
1127 break; 1196 break;
1128 1197
1129 case SENDING_CURRENT_LOGS: 1198 case SENDING_CURRENT_LOGS:
1130 break; 1199 break;
1131 1200
1132 default: 1201 default:
1133 NOTREACHED(); 1202 NOTREACHED();
1134 break; 1203 break;
1135 } 1204 }
1136 1205
1137 log_manager_.DiscardStagedLog(); 1206 log_manager_.DiscardStagedLog();
1138 1207
1139 if (log_manager_.has_unsent_logs()) 1208 if (log_manager_.has_unsent_logs())
1140 DCHECK(state_ < SENDING_CURRENT_LOGS); 1209 DCHECK(state_ < SENDING_CURRENT_LOGS);
1141 } 1210 }
1142 1211
1143 // Error 400 indicates a problem with the log, not with the server, so 1212 // Error 400 indicates a problem with the log, not with the server, so
1144 // don't consider that a sign that the server is in trouble. 1213 // don't consider that a sign that the server is in trouble.
1145 bool server_is_healthy = upload_succeeded || source->GetResponseCode() == 400; 1214 bool server_is_healthy = upload_succeeded || response_code_ == 400;
1146 1215
1147 scheduler_->UploadFinished(server_is_healthy, 1216 scheduler_->UploadFinished(server_is_healthy,
1148 log_manager_.has_unsent_logs()); 1217 log_manager_.has_unsent_logs());
1149 1218
1150 // Collect network stats if UMA upload succeeded. 1219 // Collect network stats if UMA upload succeeded.
1151 if (server_is_healthy && io_thread_) 1220 if (server_is_healthy && io_thread_)
1152 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread_); 1221 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread_);
1222
1223 // Reset the cached response data.
1224 response_code_ = content::URLFetcher::RESPONSE_CODE_INVALID;
1225 response_data_ = std::string();
1226 response_status_ = std::string();
1153 } 1227 }
1154 1228
1155 void MetricsService::LogBadResponseCode() { 1229 void MetricsService::LogBadResponseCode() {
1156 VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server " 1230 VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server "
1157 "is active at " << server_url_; 1231 "is active at " << server_url_xml_;
1158 if (!log_manager_.has_staged_log()) { 1232 if (!log_manager_.has_staged_log()) {
1159 VLOG(1) << "METRICS: Recorder shutdown during log transmission."; 1233 VLOG(1) << "METRICS: Recorder shutdown during log transmission.";
1160 } else { 1234 } else {
1161 VLOG(1) << "METRICS: transmission retry being scheduled for " 1235 VLOG(1) << "METRICS: transmission retry being scheduled for "
1162 << log_manager_.staged_log_text(); 1236 << log_manager_.staged_log_text_xml();
1163 } 1237 }
1164 } 1238 }
1165 1239
1166 void MetricsService::LogWindowChange( 1240 void MetricsService::LogWindowChange(
1167 int type, 1241 int type,
1168 const content::NotificationSource& source, 1242 const content::NotificationSource& source,
1169 const content::NotificationDetails& details) { 1243 const content::NotificationDetails& details) {
1170 int controller_id = -1; 1244 int controller_id = -1;
1171 uintptr_t window_or_tab = source.map_key(); 1245 uintptr_t window_or_tab = source.map_key();
1172 MetricsLog::WindowEventType window_type; 1246 MetricsLog::WindowEventType window_type;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 1598
1525 RecordPluginChanges(pref); 1599 RecordPluginChanges(pref);
1526 } 1600 }
1527 1601
1528 // static 1602 // static
1529 bool MetricsService::IsPluginProcess(content::ProcessType type) { 1603 bool MetricsService::IsPluginProcess(content::ProcessType type) {
1530 return (type == content::PROCESS_TYPE_PLUGIN|| 1604 return (type == content::PROCESS_TYPE_PLUGIN||
1531 type == content::PROCESS_TYPE_PPAPI_PLUGIN); 1605 type == content::PROCESS_TYPE_PPAPI_PLUGIN);
1532 } 1606 }
1533 1607
1534 static bool IsSingleThreaded() {
1535 static base::PlatformThreadId thread_id = 0;
1536 if (!thread_id)
1537 thread_id = base::PlatformThread::CurrentId();
1538 return base::PlatformThread::CurrentId() == thread_id;
1539 }
1540
1541 #if defined(OS_CHROMEOS) 1608 #if defined(OS_CHROMEOS)
1542 void MetricsService::StartExternalMetrics() { 1609 void MetricsService::StartExternalMetrics() {
1543 external_metrics_ = new chromeos::ExternalMetrics; 1610 external_metrics_ = new chromeos::ExternalMetrics;
1544 external_metrics_->Start(); 1611 external_metrics_->Start();
1545 } 1612 }
1546 #endif 1613 #endif
1547 1614
1548 // static 1615 // static
1549 bool MetricsServiceHelper::IsMetricsReportingEnabled() { 1616 bool MetricsServiceHelper::IsMetricsReportingEnabled() {
1550 bool result = false; 1617 bool result = false;
1551 const PrefService* local_state = g_browser_process->local_state(); 1618 const PrefService* local_state = g_browser_process->local_state();
1552 if (local_state) { 1619 if (local_state) {
1553 const PrefService::Preference* uma_pref = 1620 const PrefService::Preference* uma_pref =
1554 local_state->FindPreference(prefs::kMetricsReportingEnabled); 1621 local_state->FindPreference(prefs::kMetricsReportingEnabled);
1555 if (uma_pref) { 1622 if (uma_pref) {
1556 bool success = uma_pref->GetValue()->GetAsBoolean(&result); 1623 bool success = uma_pref->GetValue()->GetAsBoolean(&result);
1557 DCHECK(success); 1624 DCHECK(success);
1558 } 1625 }
1559 } 1626 }
1560 return result; 1627 return result;
1561 } 1628 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698