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

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

Issue 293023005: Move MetricsService final log collection tasks to client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 6 years, 7 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 is 10 // A MetricsService instance is typically created at application startup. It is
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 #include "base/strings/string_number_conversions.h" 177 #include "base/strings/string_number_conversions.h"
178 #include "base/strings/utf_string_conversions.h" 178 #include "base/strings/utf_string_conversions.h"
179 #include "base/threading/platform_thread.h" 179 #include "base/threading/platform_thread.h"
180 #include "base/threading/thread.h" 180 #include "base/threading/thread.h"
181 #include "base/threading/thread_restrictions.h" 181 #include "base/threading/thread_restrictions.h"
182 #include "base/tracked_objects.h" 182 #include "base/tracked_objects.h"
183 #include "base/values.h" 183 #include "base/values.h"
184 #include "chrome/browser/browser_process.h" 184 #include "chrome/browser/browser_process.h"
185 #include "chrome/browser/chrome_notification_types.h" 185 #include "chrome/browser/chrome_notification_types.h"
186 #include "chrome/browser/io_thread.h" 186 #include "chrome/browser/io_thread.h"
187 #include "chrome/browser/memory_details.h"
188 #include "chrome/browser/metrics/compression_utils.h" 187 #include "chrome/browser/metrics/compression_utils.h"
189 #include "chrome/browser/metrics/metrics_log.h" 188 #include "chrome/browser/metrics/metrics_log.h"
190 #include "chrome/browser/metrics/metrics_state_manager.h" 189 #include "chrome/browser/metrics/metrics_state_manager.h"
191 #include "chrome/browser/metrics/omnibox_metrics_provider.h" 190 #include "chrome/browser/metrics/omnibox_metrics_provider.h"
192 #include "chrome/browser/metrics/time_ticks_experiment_win.h" 191 #include "chrome/browser/metrics/time_ticks_experiment_win.h"
193 #include "chrome/browser/metrics/tracking_synchronizer.h" 192 #include "chrome/browser/metrics/tracking_synchronizer.h"
194 #include "chrome/browser/net/http_pipelining_compatibility_client.h" 193 #include "chrome/browser/net/http_pipelining_compatibility_client.h"
195 #include "chrome/browser/net/network_stats.h" 194 #include "chrome/browser/net/network_stats.h"
196 #include "chrome/browser/ui/browser_otr_state.h" 195 #include "chrome/browser/ui/browser_otr_state.h"
197 #include "chrome/common/chrome_constants.h" 196 #include "chrome/common/chrome_constants.h"
198 #include "chrome/common/chrome_switches.h" 197 #include "chrome/common/chrome_switches.h"
199 #include "chrome/common/crash_keys.h" 198 #include "chrome/common/crash_keys.h"
200 #include "chrome/common/metrics/variations/variations_util.h" 199 #include "chrome/common/metrics/variations/variations_util.h"
201 #include "chrome/common/net/test_server_locations.h" 200 #include "chrome/common/net/test_server_locations.h"
202 #include "chrome/common/pref_names.h" 201 #include "chrome/common/pref_names.h"
203 #include "chrome/common/render_messages.h"
204 #include "components/metrics/metrics_log_manager.h" 202 #include "components/metrics/metrics_log_manager.h"
205 #include "components/metrics/metrics_pref_names.h" 203 #include "components/metrics/metrics_pref_names.h"
206 #include "components/metrics/metrics_reporting_scheduler.h" 204 #include "components/metrics/metrics_reporting_scheduler.h"
205 #include "components/metrics/metrics_service_client.h"
207 #include "components/variations/entropy_provider.h" 206 #include "components/variations/entropy_provider.h"
208 #include "components/variations/metrics_util.h" 207 #include "components/variations/metrics_util.h"
209 #include "content/public/browser/child_process_data.h" 208 #include "content/public/browser/child_process_data.h"
210 #include "content/public/browser/histogram_fetcher.h"
211 #include "content/public/browser/load_notification_details.h" 209 #include "content/public/browser/load_notification_details.h"
212 #include "content/public/browser/notification_service.h" 210 #include "content/public/browser/notification_service.h"
213 #include "content/public/browser/plugin_service.h" 211 #include "content/public/browser/plugin_service.h"
214 #include "content/public/browser/render_process_host.h" 212 #include "content/public/browser/render_process_host.h"
215 #include "content/public/browser/user_metrics.h" 213 #include "content/public/browser/user_metrics.h"
216 #include "content/public/browser/web_contents.h" 214 #include "content/public/browser/web_contents.h"
217 #include "content/public/common/process_type.h" 215 #include "content/public/common/process_type.h"
218 #include "content/public/common/webplugininfo.h" 216 #include "content/public/common/webplugininfo.h"
219 #include "extensions/browser/process_map.h" 217 #include "extensions/browser/process_map.h"
220 #include "net/base/load_flags.h" 218 #include "net/base/load_flags.h"
221 #include "net/url_request/url_fetcher.h" 219 #include "net/url_request/url_fetcher.h"
222 220
223 // TODO(port): port browser_distribution.h. 221 // TODO(port): port browser_distribution.h.
224 #if !defined(OS_POSIX) 222 #if !defined(OS_POSIX)
225 #include "chrome/installer/util/browser_distribution.h" 223 #include "chrome/installer/util/browser_distribution.h"
226 #endif 224 #endif
227 225
228 #if defined(OS_CHROMEOS) 226 #if defined(OS_CHROMEOS)
229 #include "chrome/browser/chromeos/settings/cros_settings.h" 227 #include "chrome/browser/chromeos/settings/cros_settings.h"
230 #include "chromeos/system/statistics_provider.h" 228 #include "chromeos/system/statistics_provider.h"
231 #endif 229 #endif
232 230
233 #if defined(OS_WIN) 231 #if defined(OS_WIN)
234 #include <windows.h> // Needed for STATUS_* codes 232 #include <windows.h> // Needed for STATUS_* codes
235 #include "base/win/registry.h" 233 #include "base/win/registry.h"
236 #endif 234 #endif
237 235
238 #if !defined(OS_ANDROID)
239 #include "chrome/browser/service_process/service_process_control.h"
240 #endif
241
242 using base::Time; 236 using base::Time;
243 using content::BrowserThread; 237 using content::BrowserThread;
244 using content::ChildProcessData; 238 using content::ChildProcessData;
245 using content::LoadNotificationDetails; 239 using content::LoadNotificationDetails;
246 using content::PluginService; 240 using content::PluginService;
247 using metrics::MetricsLogManager; 241 using metrics::MetricsLogManager;
248 242
249 namespace { 243 namespace {
250 244
251 // Check to see that we're being called on only one thread. 245 // Check to see that we're being called on only one thread.
252 bool IsSingleThreaded() { 246 bool IsSingleThreaded() {
253 static base::PlatformThreadId thread_id = 0; 247 static base::PlatformThreadId thread_id = 0;
254 if (!thread_id) 248 if (!thread_id)
255 thread_id = base::PlatformThread::CurrentId(); 249 thread_id = base::PlatformThread::CurrentId();
256 return base::PlatformThread::CurrentId() == thread_id; 250 return base::PlatformThread::CurrentId() == thread_id;
257 } 251 }
258 252
259 // The delay, in seconds, after starting recording before doing expensive 253 // The delay, in seconds, after starting recording before doing expensive
260 // initialization work. 254 // initialization work.
261 #if defined(OS_ANDROID) || defined(OS_IOS) 255 #if defined(OS_ANDROID) || defined(OS_IOS)
262 // On mobile devices, a significant portion of sessions last less than a minute. 256 // On mobile devices, a significant portion of sessions last less than a minute.
263 // Use a shorter timer on these platforms to avoid losing data. 257 // Use a shorter timer on these platforms to avoid losing data.
264 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so 258 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so
265 // that it occurs after the user gets their initial page. 259 // that it occurs after the user gets their initial page.
266 const int kInitializationDelaySeconds = 5; 260 const int kInitializationDelaySeconds = 5;
267 #else 261 #else
268 const int kInitializationDelaySeconds = 30; 262 const int kInitializationDelaySeconds = 30;
269 #endif 263 #endif
270 264
271 // This specifies the amount of time to wait for all renderers to send their
272 // data.
273 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds.
274
275 // The maximum number of events in a log uploaded to the UMA server. 265 // The maximum number of events in a log uploaded to the UMA server.
276 const int kEventLimit = 2400; 266 const int kEventLimit = 2400;
277 267
278 // If an upload fails, and the transmission was over this byte count, then we 268 // If an upload fails, and the transmission was over this byte count, then we
279 // will discard the log, and not try to retransmit it. We also don't persist 269 // will discard the log, and not try to retransmit it. We also don't persist
280 // the log to the prefs for transmission during the next chrome session if this 270 // the log to the prefs for transmission during the next chrome session if this
281 // limit is exceeded. 271 // limit is exceeded.
282 const size_t kUploadLogAvoidRetransmitSize = 50000; 272 const size_t kUploadLogAvoidRetransmitSize = 50000;
283 273
284 // Interval, in minutes, between state saves. 274 // Interval, in minutes, between state saves.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 // load. 369 // load.
380 int instances; 370 int instances;
381 371
382 // The number of times there was an error loading an instance of this child 372 // The number of times there was an error loading an instance of this child
383 // process. 373 // process.
384 int loading_errors; 374 int loading_errors;
385 375
386 int process_type; 376 int process_type;
387 }; 377 };
388 378
389 // Handles asynchronous fetching of memory details.
390 // Will run the provided task after finished.
391 class MetricsMemoryDetails : public MemoryDetails {
392 public:
393 explicit MetricsMemoryDetails(const base::Closure& callback)
394 : callback_(callback) {}
395
396 virtual void OnDetailsAvailable() OVERRIDE {
397 base::MessageLoop::current()->PostTask(FROM_HERE, callback_);
398 }
399
400 private:
401 virtual ~MetricsMemoryDetails() {}
402
403 base::Closure callback_;
404 DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails);
405 };
406
407 // static 379 // static
408 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { 380 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
409 DCHECK(IsSingleThreaded()); 381 DCHECK(IsSingleThreaded());
410 metrics::MetricsStateManager::RegisterPrefs(registry); 382 metrics::MetricsStateManager::RegisterPrefs(registry);
411 383
412 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); 384 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0);
413 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); 385 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0);
414 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); 386 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string());
415 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); 387 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0);
416 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); 388 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 recording_active_(false), 439 recording_active_(false),
468 reporting_active_(false), 440 reporting_active_(false),
469 test_mode_active_(false), 441 test_mode_active_(false),
470 state_(INITIALIZED), 442 state_(INITIALIZED),
471 has_initial_stability_log_(false), 443 has_initial_stability_log_(false),
472 idle_since_last_transmission_(false), 444 idle_since_last_transmission_(false),
473 session_id_(-1), 445 session_id_(-1),
474 next_window_id_(0), 446 next_window_id_(0),
475 self_ptr_factory_(this), 447 self_ptr_factory_(this),
476 state_saver_factory_(this), 448 state_saver_factory_(this),
477 waiting_for_asynchronous_reporting_step_(false), 449 waiting_for_asynchronous_reporting_step_(false) {
478 num_async_histogram_fetches_in_progress_(0) {
479 DCHECK(IsSingleThreaded()); 450 DCHECK(IsSingleThreaded());
480 DCHECK(state_manager_); 451 DCHECK(state_manager_);
481 DCHECK(client_); 452 DCHECK(client_);
482 453
483 // TODO(asvitkine): Move this out of MetricsService. 454 // TODO(asvitkine): Move this out of MetricsService.
484 RegisterMetricsProvider( 455 RegisterMetricsProvider(
485 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider)); 456 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
486 457
487 BrowserChildProcessObserver::Add(this); 458 BrowserChildProcessObserver::Add(this);
488 } 459 }
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */); 1208 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */);
1238 return; 1209 return;
1239 } 1210 }
1240 // If there are unsent logs, send the next one. If not, start the asynchronous 1211 // If there are unsent logs, send the next one. If not, start the asynchronous
1241 // process of finalizing the current log for upload. 1212 // process of finalizing the current log for upload.
1242 if (state_ == SENDING_OLD_LOGS) { 1213 if (state_ == SENDING_OLD_LOGS) {
1243 DCHECK(log_manager_.has_unsent_logs()); 1214 DCHECK(log_manager_.has_unsent_logs());
1244 log_manager_.StageNextLogForUpload(); 1215 log_manager_.StageNextLogForUpload();
1245 SendStagedLog(); 1216 SendStagedLog();
1246 } else { 1217 } else {
1247 StartFinalLogInfoCollection(); 1218 client_->OnFinalLogCollection(
1219 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone,
1220 self_ptr_factory_.GetWeakPtr()));
1248 } 1221 }
1249 } 1222 }
1250 1223
1251 void MetricsService::StartFinalLogInfoCollection() {
1252 // Begin the multi-step process of collecting memory usage histograms:
1253 // First spawn a task to collect the memory details; when that task is
1254 // finished, it will call OnMemoryDetailCollectionDone. That will in turn
1255 // call HistogramSynchronization to collect histograms from all renderers and
1256 // then call OnHistogramSynchronizationDone to continue processing.
1257 DCHECK(!waiting_for_asynchronous_reporting_step_);
1258 waiting_for_asynchronous_reporting_step_ = true;
1259
1260 base::Closure callback =
1261 base::Bind(&MetricsService::OnMemoryDetailCollectionDone,
1262 self_ptr_factory_.GetWeakPtr());
1263
1264 scoped_refptr<MetricsMemoryDetails> details(
1265 new MetricsMemoryDetails(callback));
1266 details->StartFetch(MemoryDetails::UPDATE_USER_METRICS);
1267
1268 // Collect WebCore cache information to put into a histogram.
1269 for (content::RenderProcessHost::iterator i(
1270 content::RenderProcessHost::AllHostsIterator());
1271 !i.IsAtEnd(); i.Advance())
1272 i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats());
1273 }
1274
1275 void MetricsService::OnMemoryDetailCollectionDone() {
1276 DCHECK(IsSingleThreaded());
Ilya Sherman 2014/05/21 13:37:07 Hmm, why did you drop this DCHECK?
Alexei Svitkine (slow) 2014/05/21 14:20:15 I didn't drop it in so much as I didn't re-create
1277 // This function should only be called as the callback from an ansynchronous
1278 // step.
1279 DCHECK(waiting_for_asynchronous_reporting_step_);
1280
1281 // Create a callback_task for OnHistogramSynchronizationDone.
1282 base::Closure callback = base::Bind(
1283 &MetricsService::OnHistogramSynchronizationDone,
1284 self_ptr_factory_.GetWeakPtr());
1285
1286 base::TimeDelta timeout =
1287 base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);
1288
1289 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);
1290
1291 #if defined(OS_ANDROID)
1292 // Android has no service process.
1293 num_async_histogram_fetches_in_progress_ = 1;
1294 #else // OS_ANDROID
1295 num_async_histogram_fetches_in_progress_ = 2;
1296 // Run requests to service and content in parallel.
1297 if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
1298 // Assume |num_async_histogram_fetches_in_progress_| is not changed by
1299 // |GetHistograms()|.
1300 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
1301 // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
1302 // here to make code work even if |GetHistograms()| fired |callback|.
1303 --num_async_histogram_fetches_in_progress_;
1304 }
1305 #endif // OS_ANDROID
1306
1307 // Set up the callback to task to call after we receive histograms from all
1308 // child processes. Wait time specifies how long to wait before absolutely
1309 // calling us back on the task.
1310 content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
1311 timeout);
1312 }
1313
1314 void MetricsService::OnHistogramSynchronizationDone() {
1315 DCHECK(IsSingleThreaded());
1316 // This function should only be called as the callback from an ansynchronous
1317 // step.
1318 DCHECK(waiting_for_asynchronous_reporting_step_);
1319 DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);
1320
1321 // Check if all expected requests finished.
1322 if (--num_async_histogram_fetches_in_progress_ > 0)
1323 return;
1324
1325 waiting_for_asynchronous_reporting_step_ = false;
1326 OnFinalLogInfoCollectionDone();
1327 }
1328
1329 void MetricsService::OnFinalLogInfoCollectionDone() { 1224 void MetricsService::OnFinalLogInfoCollectionDone() {
1330 // If somehow there is a fetch in progress, we return and hope things work 1225 // If somehow there is a fetch in progress, we return and hope things work
1331 // out. The scheduler isn't informed since if this happens, the scheduler 1226 // out. The scheduler isn't informed since if this happens, the scheduler
1332 // will get a response from the upload. 1227 // will get a response from the upload.
1333 DCHECK(!current_fetch_.get()); 1228 DCHECK(!current_fetch_.get());
1334 if (current_fetch_.get()) 1229 if (current_fetch_.get())
1335 return; 1230 return;
1336 1231
1337 // Abort if metrics were turned off during the final info gathering. 1232 // Abort if metrics were turned off during the final info gathering.
1338 if (!recording_active()) { 1233 if (!recording_active()) {
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 if (metrics_service) 1867 if (metrics_service)
1973 metrics_service->AddObserver(observer); 1868 metrics_service->AddObserver(observer);
1974 } 1869 }
1975 1870
1976 void MetricsServiceHelper::RemoveMetricsServiceObserver( 1871 void MetricsServiceHelper::RemoveMetricsServiceObserver(
1977 MetricsServiceObserver* observer) { 1872 MetricsServiceObserver* observer) {
1978 MetricsService* metrics_service = g_browser_process->metrics_service(); 1873 MetricsService* metrics_service = g_browser_process->metrics_service();
1979 if (metrics_service) 1874 if (metrics_service)
1980 metrics_service->RemoveObserver(observer); 1875 metrics_service->RemoveObserver(observer);
1981 } 1876 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698