OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |