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

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: Rebase Created 8 years, 10 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://rhennthyl.mtv.corp.google.com:8888/uma";
ian fette 2012/02/23 00:23:16 https://clients4.google.com/uma/v2
Ilya Sherman 2012/02/23 00:51:21 Done.
jar (doing other things) 2012/02/23 01:59:18 I think the URLs are put into resources, and not d
Ilya Sherman 2012/02/24 02:10:06 So, the "kServerUrlXML" constant I pulled up from
jar (doing other things) 2012/02/27 20:35:34 I think the most common build (no proof here :-/ )
Ilya Sherman 2012/02/28 00:23:10 I'm still not following how embedding the URL in a
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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 //------------------------------------------------------------------------------ 640 //------------------------------------------------------------------------------
622 // private methods 641 // private methods
623 //------------------------------------------------------------------------------ 642 //------------------------------------------------------------------------------
624 643
625 644
626 //------------------------------------------------------------------------------ 645 //------------------------------------------------------------------------------
627 // Initialization methods 646 // Initialization methods
628 647
629 void MetricsService::InitializeMetricsState() { 648 void MetricsService::InitializeMetricsState() {
630 #if defined(OS_POSIX) 649 #if defined(OS_POSIX)
631 server_url_ = L"https://clients4.google.com/firefox/metrics/collect"; 650 server_url_xml_ = ASCIIToUTF16(kServerUrlXml);
651 server_url_proto_ = ASCIIToUTF16(kServerUrlProto);
632 network_stats_server_ = "chrome.googleechotest.com"; 652 network_stats_server_ = "chrome.googleechotest.com";
633 #else 653 #else
634 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 654 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
635 server_url_ = dist->GetStatsServerURL(); 655 server_url_xml_ = dist->GetStatsServerURL();
656 // TODO(isherman): Hmm, do distribution channels sometimes specify other
657 // servers?
jar (doing other things) 2012/02/23 01:59:18 no... but the URLs are kept in resources, specific
Ilya Sherman 2012/02/24 02:10:06 Unless I'm misreading the pre-existing code, we we
jar (doing other things) 2012/02/27 20:35:34 I *think* the issue was that a) on windows we coul
658 server_url_proto_ = ASCIIToUTF16(kServerUrlProto);
636 network_stats_server_ = dist->GetNetworkStatsServer(); 659 network_stats_server_ = dist->GetNetworkStatsServer();
637 #endif 660 #endif
638 661
639 PrefService* pref = g_browser_process->local_state(); 662 PrefService* pref = g_browser_process->local_state();
640 DCHECK(pref); 663 DCHECK(pref);
641 664
642 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) 665 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime)
643 != MetricsLog::GetBuildTime()) || 666 != MetricsLog::GetBuildTime()) ||
644 (pref->GetString(prefs::kStabilityStatsVersion) 667 (pref->GetString(prefs::kStabilityStatsVersion)
645 != MetricsLog::GetVersionString())) { 668 != MetricsLog::GetVersionString())) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 // Adds to ongoing logs. 855 // Adds to ongoing logs.
833 log_manager_.current_log()->set_hardware_class(hardware_class_); 856 log_manager_.current_log()->set_hardware_class(hardware_class_);
834 857
835 // Put incremental data (histogram deltas, and realtime stats deltas) at the 858 // Put incremental data (histogram deltas, and realtime stats deltas) at the
836 // end of all log transmissions (initial log handles this separately). 859 // end of all log transmissions (initial log handles this separately).
837 // RecordIncrementalStabilityElements only exists on the derived 860 // RecordIncrementalStabilityElements only exists on the derived
838 // MetricsLog class. 861 // MetricsLog class.
839 MetricsLog* current_log = 862 MetricsLog* current_log =
840 static_cast<MetricsLog*>(log_manager_.current_log()); 863 static_cast<MetricsLog*>(log_manager_.current_log());
841 DCHECK(current_log); 864 DCHECK(current_log);
842 current_log->RecordIncrementalStabilityElements(); 865 current_log->RecordIncrementalStabilityElements(plugins_);
843 RecordCurrentHistograms(); 866 RecordCurrentHistograms();
844 867
845 log_manager_.StageCurrentLogForUpload(); 868 log_manager_.StageCurrentLogForUpload();
846 } 869 }
847 870
848 void MetricsService::PushPendingLogsToPersistentStorage() { 871 void MetricsService::PushPendingLogsToPersistentStorage() {
849 if (state_ < INITIAL_LOG_READY) 872 if (state_ < INITIAL_LOG_READY)
850 return; // We didn't and still don't have time to get plugin list etc. 873 return; // We didn't and still don't have time to get plugin list etc.
851 874
852 if (log_manager_.has_staged_log()) { 875 if (log_manager_.has_staged_log()) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 MessageLoop::current(), callback, 950 MessageLoop::current(), callback,
928 kMaxHistogramGatheringWaitDuration); 951 kMaxHistogramGatheringWaitDuration);
929 } 952 }
930 953
931 void MetricsService::OnHistogramSynchronizationDone() { 954 void MetricsService::OnHistogramSynchronizationDone() {
932 DCHECK(IsSingleThreaded()); 955 DCHECK(IsSingleThreaded());
933 956
934 // If somehow there is a fetch in progress, we return and hope things work 957 // If somehow there is a fetch in progress, we return and hope things work
935 // out. The scheduler isn't informed since if this happens, the scheduler 958 // out. The scheduler isn't informed since if this happens, the scheduler
936 // will get a response from the upload. 959 // will get a response from the upload.
937 DCHECK(!current_fetch_.get()); 960 DCHECK(!current_fetch_xml_.get());
938 if (current_fetch_.get()) 961 DCHECK(!current_fetch_proto_.get());
962 if (current_fetch_xml_.get() || current_fetch_proto_.get())
jar (doing other things) 2012/02/23 01:59:18 I think you're going to have to handle the sending
Ilya Sherman 2012/02/24 02:10:06 I'd really prefer to avoid decoupling the sending,
jar (doing other things) 2012/02/27 20:35:34 I think you've settled on avoiding dup-uploads of
939 return; 963 return;
940 964
941 // This function should only be called as the callback from an ansynchronous 965 // This function should only be called as the callback from an ansynchronous
942 // step. 966 // step.
943 DCHECK(waiting_for_asynchronus_reporting_step_); 967 DCHECK(waiting_for_asynchronus_reporting_step_);
944 waiting_for_asynchronus_reporting_step_ = false; 968 waiting_for_asynchronus_reporting_step_ = false;
945 969
946 // If we're getting no notifications, then the log won't have much in it, and 970 // If we're getting no notifications, then the log won't have much in it, and
947 // it's possible the computer is about to go to sleep, so don't upload and 971 // it's possible the computer is about to go to sleep, so don't upload and
948 // stop the scheduler. 972 // stop the scheduler.
949 // Similarly, if logs should no longer be uploaded, stop here. 973 // Similarly, if logs should no longer be uploaded, stop here.
950 if (idle_since_last_transmission_ || 974 if (idle_since_last_transmission_ ||
951 !recording_active() || !reporting_active()) { 975 !recording_active() || !reporting_active()) {
952 scheduler_->Stop(); 976 scheduler_->Stop();
953 scheduler_->UploadCancelled(); 977 scheduler_->UploadCancelled();
954 return; 978 return;
955 } 979 }
956 980
957 MakeStagedLog(); 981 MakeStagedLog();
958 982
959 // MakeStagedLog should have prepared log text; if it didn't, skip this 983 // MakeStagedLog should have prepared log text; if it didn't, skip this
960 // upload and hope things work out next time. 984 // upload and hope things work out next time.
961 if (log_manager_.staged_log_text().empty()) { 985 if (log_manager_.staged_log_text_xml().empty()) {
962 scheduler_->UploadCancelled(); 986 scheduler_->UploadCancelled();
963 return; 987 return;
964 } 988 }
965 989
966 PrepareFetchWithStagedLog(); 990 PrepareFetchWithStagedLog();
967 991
968 if (!current_fetch_.get()) { 992 if (!current_fetch_xml_.get()) {
993 DCHECK(!current_fetch_proto_.get());
969 // Compression failed, and log discarded :-/. 994 // Compression failed, and log discarded :-/.
970 log_manager_.DiscardStagedLog(); 995 log_manager_.DiscardStagedLog();
971 scheduler_->UploadCancelled(); 996 scheduler_->UploadCancelled();
972 // TODO(jar): If compression failed, we should have created a tiny log and 997 // TODO(jar): If compression failed, we should have created a tiny log and
973 // compressed that, so that we can signal that we're losing logs. 998 // compressed that, so that we can signal that we're losing logs.
974 return; 999 return;
975 } 1000 }
1001 DCHECK(current_fetch_proto_.get());
976 1002
977 DCHECK(!waiting_for_asynchronus_reporting_step_); 1003 DCHECK(!waiting_for_asynchronus_reporting_step_);
978 1004
979 waiting_for_asynchronus_reporting_step_ = true; 1005 waiting_for_asynchronus_reporting_step_ = true;
980 current_fetch_->Start(); 1006 current_fetch_xml_->Start();
1007 current_fetch_proto_->Start();
981 1008
982 HandleIdleSinceLastTransmission(true); 1009 HandleIdleSinceLastTransmission(true);
983 } 1010 }
984 1011
985 1012
986 void MetricsService::MakeStagedLog() { 1013 void MetricsService::MakeStagedLog() {
987 if (log_manager_.has_staged_log()) 1014 if (log_manager_.has_staged_log())
988 return; 1015 return;
989 1016
990 switch (state_) { 1017 switch (state_) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 } 1070 }
1044 1071
1045 void MetricsService::StoreUnsentLogs() { 1072 void MetricsService::StoreUnsentLogs() {
1046 if (state_ < INITIAL_LOG_READY) 1073 if (state_ < INITIAL_LOG_READY)
1047 return; // We never Recalled the prior unsent logs. 1074 return; // We never Recalled the prior unsent logs.
1048 1075
1049 log_manager_.PersistUnsentLogs(); 1076 log_manager_.PersistUnsentLogs();
1050 } 1077 }
1051 1078
1052 void MetricsService::PrepareFetchWithStagedLog() { 1079 void MetricsService::PrepareFetchWithStagedLog() {
1053 DCHECK(!log_manager_.staged_log_text().empty()); 1080 // Prepare the XML version.
1054 DCHECK(!current_fetch_.get()); 1081 DCHECK(!log_manager_.staged_log_text_xml().empty());
1082 DCHECK(!current_fetch_xml_.get());
1083 current_fetch_xml_.reset(content::URLFetcher::Create(
1084 GURL(server_url_xml_), content::URLFetcher::POST, this));
1085 current_fetch_xml_->SetRequestContext(
1086 g_browser_process->system_request_context());
1087 current_fetch_xml_->SetUploadData(kMetricsTypeXml,
1088 log_manager_.staged_log_text_xml());
1055 1089
1056 current_fetch_.reset(content::URLFetcher::Create( 1090 // Prepare the protobuf version.
1057 GURL(WideToUTF16(server_url_)), content::URLFetcher::POST, this)); 1091 DCHECK(!log_manager_.staged_log_text_proto().empty());
1058 current_fetch_->SetRequestContext( 1092 DCHECK(!current_fetch_proto_.get());
1093 current_fetch_proto_.reset(content::URLFetcher::Create(
1094 GURL(server_url_proto_), content::URLFetcher::POST, this));
1095 current_fetch_proto_->SetRequestContext(
1059 g_browser_process->system_request_context()); 1096 g_browser_process->system_request_context());
1060 current_fetch_->SetUploadData(kMetricsType, log_manager_.staged_log_text()); 1097 current_fetch_proto_->SetUploadData(kMetricsTypeProto,
1098 log_manager_.staged_log_text_proto());
1061 } 1099 }
1062 1100
1063 static const char* StatusToString(const net::URLRequestStatus& status) { 1101 static const char* StatusToString(const net::URLRequestStatus& status) {
1064 switch (status.status()) { 1102 switch (status.status()) {
1065 case net::URLRequestStatus::SUCCESS: 1103 case net::URLRequestStatus::SUCCESS:
1066 return "SUCCESS"; 1104 return "SUCCESS";
1067 1105
1068 case net::URLRequestStatus::IO_PENDING: 1106 case net::URLRequestStatus::IO_PENDING:
1069 return "IO_PENDING"; 1107 return "IO_PENDING";
1070 1108
1071 case net::URLRequestStatus::HANDLED_EXTERNALLY: 1109 case net::URLRequestStatus::HANDLED_EXTERNALLY:
1072 return "HANDLED_EXTERNALLY"; 1110 return "HANDLED_EXTERNALLY";
1073 1111
1074 case net::URLRequestStatus::CANCELED: 1112 case net::URLRequestStatus::CANCELED:
1075 return "CANCELED"; 1113 return "CANCELED";
1076 1114
1077 case net::URLRequestStatus::FAILED: 1115 case net::URLRequestStatus::FAILED:
1078 return "FAILED"; 1116 return "FAILED";
1079 1117
1080 default: 1118 default:
1081 NOTREACHED(); 1119 NOTREACHED();
1082 return "Unknown"; 1120 return "Unknown";
1083 } 1121 }
1084 } 1122 }
1085 1123
1124 // We need to wait for two responses: the response to the XML upload, and the
1125 // response to the protobuf upload. For now, only the XML upload's response
1126 // affects decisions like whether to retry the upload, whether to abandon the
1127 // upload because it is too large, etc. However, we still need to wait for the
1128 // protobuf upload, as we cannot reset |current_fetch_proto_| until we have
1129 // confirmation that the network request was sent; and the easiest way to do
1130 // that is to wait for the response. In case the XML upload's response arrives
1131 // first, we cache that response until the protobuf upload's response also
1132 // arrives.
jar (doing other things) 2012/02/23 01:59:18 What do you do if one provides an ack, and the oth
Ilya Sherman 2012/02/24 02:10:06 I tried to describe that: "For now, only the XML u
jar (doing other things) 2012/02/27 20:35:34 Wording changes are great. Thanks! On 2012/02/24
1086 void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { 1133 void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) {
1087 DCHECK(waiting_for_asynchronus_reporting_step_); 1134 DCHECK(waiting_for_asynchronus_reporting_step_);
1135
1136 // We're not allowed to re-use the existing |URLFetcher|s, so free them here.
1137 scoped_ptr<content::URLFetcher> s;
1138 if (source == current_fetch_xml_.get()) {
1139 s.reset(current_fetch_xml_.release());
1140
1141 // Cache the XML responses, in case we still need to wait for the protobuf
1142 // response.
1143 response_code_ = source->GetResponseCode();
1144 response_status_ = StatusToString(source->GetStatus());
1145 source->GetResponseAsString(&response_data_);
1146 } else if (source == current_fetch_proto_.get()) {
1147 s.reset(current_fetch_proto_.release());
1148 } else {
1149 NOTREACHED();
1150 return;
1151 }
1152
1153 // If we're still waiting for one of the responses, keep waiting...
1154 if (current_fetch_xml_.get() || current_fetch_proto_.get())
1155 return;
1156
1157 // We should only be able to reach here once we've received responses to both
1158 // the XML and the protobuf requests. We should always have the response code
1159 // available.
1160 DCHECK_NE(response_code_, content::URLFetcher::RESPONSE_CODE_INVALID);
1088 waiting_for_asynchronus_reporting_step_ = false; 1161 waiting_for_asynchronus_reporting_step_ = false;
1089 DCHECK(current_fetch_.get()); 1162
1090 // We're not allowed to re-use it. Delete it on function exit since we use it.
1091 scoped_ptr<content::URLFetcher> s(current_fetch_.release());
1092 1163
1093 // Confirm send so that we can move on. 1164 // Confirm send so that we can move on.
1094 VLOG(1) << "METRICS RESPONSE CODE: " << source->GetResponseCode() 1165 VLOG(1) << "METRICS RESPONSE CODE: " << response_code_
1095 << " status=" << StatusToString(source->GetStatus()); 1166 << " status=" << response_status_;
1096 1167
1097 bool upload_succeeded = source->GetResponseCode() == 200; 1168 bool upload_succeeded = response_code_ == 200;
1098 1169
1099 // Provide boolean for error recovery (allow us to ignore response_code). 1170 // Provide boolean for error recovery (allow us to ignore response_code).
1100 bool discard_log = false; 1171 bool discard_log = false;
1101 1172
1102 if (!upload_succeeded && 1173 if (!upload_succeeded &&
1103 (log_manager_.staged_log_text().length() > 1174 log_manager_.staged_log_text_xml().length() >
1104 static_cast<size_t>(kUploadLogAvoidRetransmitSize))) { 1175 kUploadLogAvoidRetransmitSize) {
1105 UMA_HISTOGRAM_COUNTS( 1176 UMA_HISTOGRAM_COUNTS(
jar (doing other things) 2012/02/23 01:59:18 nit: indent for body of if should only be 2 charac
Ilya Sherman 2012/02/24 02:10:06 Done.
1106 "UMA.Large Rejected Log was Discarded", 1177 "UMA.Large Rejected Log was Discarded",
1107 static_cast<int>(log_manager_.staged_log_text().length())); 1178 static_cast<int>(log_manager_.staged_log_text_xml().length()));
1108 discard_log = true; 1179 discard_log = true;
1109 } else if (source->GetResponseCode() == 400) { 1180 } else if (response_code_ == 400) {
1110 // Bad syntax. Retransmission won't work. 1181 // Bad syntax. Retransmission won't work.
1111 UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_); 1182 UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_);
1112 discard_log = true; 1183 discard_log = true;
1113 } 1184 }
1114 1185
1115 if (!upload_succeeded && !discard_log) { 1186 if (!upload_succeeded && !discard_log) {
1116 VLOG(1) << "METRICS: transmission attempt returned a failure code: " 1187 VLOG(1) << "METRICS: transmission attempt returned a failure code: "
1117 << source->GetResponseCode() << ". Verify network connectivity"; 1188 << response_code_ << ". Verify network connectivity";
1118 LogBadResponseCode(); 1189 LogBadResponseCode();
1119 } else { // Successful receipt (or we are discarding log). 1190 } else { // Successful receipt (or we are discarding log).
1120 std::string data; 1191 VLOG(1) << "METRICS RESPONSE DATA: " << response_data_;
1121 source->GetResponseAsString(&data);
1122 VLOG(1) << "METRICS RESPONSE DATA: " << data;
1123 switch (state_) { 1192 switch (state_) {
1124 case INITIAL_LOG_READY: 1193 case INITIAL_LOG_READY:
1125 state_ = SENDING_OLD_LOGS; 1194 state_ = SENDING_OLD_LOGS;
1126 break; 1195 break;
1127 1196
1128 case SENDING_OLD_LOGS: 1197 case SENDING_OLD_LOGS:
1129 // Store the updated list to disk now that the removed log is uploaded. 1198 // Store the updated list to disk now that the removed log is uploaded.
1130 StoreUnsentLogs(); 1199 StoreUnsentLogs();
1131 break; 1200 break;
1132 1201
1133 case SENDING_CURRENT_LOGS: 1202 case SENDING_CURRENT_LOGS:
1134 break; 1203 break;
1135 1204
1136 default: 1205 default:
1137 NOTREACHED(); 1206 NOTREACHED();
1138 break; 1207 break;
1139 } 1208 }
1140 1209
1141 log_manager_.DiscardStagedLog(); 1210 log_manager_.DiscardStagedLog();
1142 1211
1143 if (log_manager_.has_unsent_logs()) 1212 if (log_manager_.has_unsent_logs())
1144 DCHECK(state_ < SENDING_CURRENT_LOGS); 1213 DCHECK(state_ < SENDING_CURRENT_LOGS);
1145 } 1214 }
1146 1215
1147 // Error 400 indicates a problem with the log, not with the server, so 1216 // Error 400 indicates a problem with the log, not with the server, so
1148 // don't consider that a sign that the server is in trouble. 1217 // don't consider that a sign that the server is in trouble.
1149 bool server_is_healthy = upload_succeeded || source->GetResponseCode() == 400; 1218 bool server_is_healthy = upload_succeeded || response_code_ == 400;
1150 1219
1151 scheduler_->UploadFinished(server_is_healthy, 1220 scheduler_->UploadFinished(server_is_healthy,
1152 log_manager_.has_unsent_logs()); 1221 log_manager_.has_unsent_logs());
1153 1222
1154 // Collect network stats if UMA upload succeeded. 1223 // Collect network stats if UMA upload succeeded.
1155 if (server_is_healthy && io_thread_) 1224 if (server_is_healthy && io_thread_)
1156 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread_); 1225 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread_);
1226
1227 // Reset the cached response data.
1228 response_code_ = content::URLFetcher::RESPONSE_CODE_INVALID;
1229 response_data_ = std::string();
1230 response_status_ = std::string();
1157 } 1231 }
1158 1232
1159 void MetricsService::LogBadResponseCode() { 1233 void MetricsService::LogBadResponseCode() {
1160 VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server " 1234 VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server "
1161 "is active at " << server_url_; 1235 "is active at " << server_url_xml_;
1162 if (!log_manager_.has_staged_log()) { 1236 if (!log_manager_.has_staged_log()) {
1163 VLOG(1) << "METRICS: Recorder shutdown during log transmission."; 1237 VLOG(1) << "METRICS: Recorder shutdown during log transmission.";
1164 } else { 1238 } else {
1165 VLOG(1) << "METRICS: transmission retry being scheduled for " 1239 VLOG(1) << "METRICS: transmission retry being scheduled for "
1166 << log_manager_.staged_log_text(); 1240 << log_manager_.staged_log_text_xml();
1167 } 1241 }
1168 } 1242 }
1169 1243
1170 void MetricsService::LogWindowChange( 1244 void MetricsService::LogWindowChange(
1171 int type, 1245 int type,
1172 const content::NotificationSource& source, 1246 const content::NotificationSource& source,
1173 const content::NotificationDetails& details) { 1247 const content::NotificationDetails& details) {
1174 int controller_id = -1; 1248 int controller_id = -1;
1175 uintptr_t window_or_tab = source.map_key(); 1249 uintptr_t window_or_tab = source.map_key();
1176 MetricsLog::WindowEventType window_type; 1250 MetricsLog::WindowEventType window_type;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 1602
1529 RecordPluginChanges(pref); 1603 RecordPluginChanges(pref);
1530 } 1604 }
1531 1605
1532 // static 1606 // static
1533 bool MetricsService::IsPluginProcess(content::ProcessType type) { 1607 bool MetricsService::IsPluginProcess(content::ProcessType type) {
1534 return (type == content::PROCESS_TYPE_PLUGIN|| 1608 return (type == content::PROCESS_TYPE_PLUGIN||
1535 type == content::PROCESS_TYPE_PPAPI_PLUGIN); 1609 type == content::PROCESS_TYPE_PPAPI_PLUGIN);
1536 } 1610 }
1537 1611
1538 static bool IsSingleThreaded() {
1539 static base::PlatformThreadId thread_id = 0;
1540 if (!thread_id)
1541 thread_id = base::PlatformThread::CurrentId();
1542 return base::PlatformThread::CurrentId() == thread_id;
1543 }
1544
1545 #if defined(OS_CHROMEOS) 1612 #if defined(OS_CHROMEOS)
1546 void MetricsService::StartExternalMetrics() { 1613 void MetricsService::StartExternalMetrics() {
1547 external_metrics_ = new chromeos::ExternalMetrics; 1614 external_metrics_ = new chromeos::ExternalMetrics;
1548 external_metrics_->Start(); 1615 external_metrics_->Start();
1549 } 1616 }
1550 #endif 1617 #endif
1551 1618
1552 // static 1619 // static
1553 bool MetricsServiceHelper::IsMetricsReportingEnabled() { 1620 bool MetricsServiceHelper::IsMetricsReportingEnabled() {
1554 bool result = false; 1621 bool result = false;
1555 const PrefService* local_state = g_browser_process->local_state(); 1622 const PrefService* local_state = g_browser_process->local_state();
1556 if (local_state) { 1623 if (local_state) {
1557 const PrefService::Preference* uma_pref = 1624 const PrefService::Preference* uma_pref =
1558 local_state->FindPreference(prefs::kMetricsReportingEnabled); 1625 local_state->FindPreference(prefs::kMetricsReportingEnabled);
1559 if (uma_pref) { 1626 if (uma_pref) {
1560 bool success = uma_pref->GetValue()->GetAsBoolean(&result); 1627 bool success = uma_pref->GetValue()->GetAsBoolean(&result);
1561 DCHECK(success); 1628 DCHECK(success);
1562 } 1629 }
1563 } 1630 }
1564 return result; 1631 return result;
1565 } 1632 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698