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

Side by Side Diff: chrome/browser/metrics/perf/perf_provider_chromeos.cc

Issue 1399703002: PerfProvider: Restructure collection parameters into a struct (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Remove unused include used for debugging Created 5 years, 2 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
« no previous file with comments | « chrome/browser/metrics/perf/perf_provider_chromeos.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" 5 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/threading/sequenced_worker_pool.h" 14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" 15 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h"
16 #include "chrome/browser/ui/browser_list.h" 16 #include "chrome/browser/ui/browser_list.h"
17 #include "chromeos/dbus/dbus_thread_manager.h" 17 #include "chromeos/dbus/dbus_thread_manager.h"
18 #include "chromeos/dbus/debug_daemon_client.h" 18 #include "chromeos/dbus/debug_daemon_client.h"
19 19
20 namespace metrics {
21
20 namespace { 22 namespace {
21 23
22 // Partition time since login into successive intervals of this size. In each
23 // interval, pick a random time to collect a profile.
24 const size_t kPerfProfilingIntervalMs = 3 * 60 * 60 * 1000;
25
26 // Default time in seconds perf is run for.
27 const size_t kPerfCommandDurationDefaultSeconds = 2;
28
29 // Limit the total size of protobufs that can be cached, so they don't take up 24 // Limit the total size of protobufs that can be cached, so they don't take up
30 // too much memory. If the size of cached protobufs exceeds this value, stop 25 // too much memory. If the size of cached protobufs exceeds this value, stop
31 // collecting further perf data. The current value is 4 MB. 26 // collecting further perf data. The current value is 4 MB.
32 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024; 27 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024;
33 28
34 // There may be too many suspends to collect a profile each time there is a
35 // resume. To limit the number of profiles, collect one for 1 in 10 resumes.
36 // Adjust this number as needed.
37 const int kResumeSamplingFactor = 10;
38
39 // There may be too many session restores to collect a profile each time. Limit
40 // the collection rate by collecting one per 10 restores. Adjust this number as
41 // needed.
42 const int kRestoreSessionSamplingFactor = 10;
43
44 // This is used to space out session restore collections in the face of several 29 // This is used to space out session restore collections in the face of several
45 // notifications in a short period of time. There should be no less than this 30 // notifications in a short period of time. There should be no less than this
46 // much time between collections. The current value is 30 seconds. 31 // much time between collections.
47 const int kMinIntervalBetweenSessionRestoreCollectionsMs = 30 * 1000; 32 const int kMinIntervalBetweenSessionRestoreCollectionsInSec = 30;
48
49 // If collecting after a resume, add a random delay before collecting. The delay
50 // should be randomly selected between 0 and this value. Currently the value is
51 // equal to 5 seconds.
52 const int kMaxResumeCollectionDelayMs = 5 * 1000;
53
54 // If collecting after a session restore, add a random delay before collecting.
55 // The delay should be randomly selected between 0 and this value. Currently the
56 // value is equal to 10 seconds.
57 const int kMaxRestoreSessionCollectionDelayMs = 10 * 1000;
58 33
59 // Enumeration representing success and various failure modes for collecting and 34 // Enumeration representing success and various failure modes for collecting and
60 // sending perf data. 35 // sending perf data.
61 enum GetPerfDataOutcome { 36 enum GetPerfDataOutcome {
62 SUCCESS, 37 SUCCESS,
63 NOT_READY_TO_UPLOAD, 38 NOT_READY_TO_UPLOAD,
64 NOT_READY_TO_COLLECT, 39 NOT_READY_TO_COLLECT,
65 INCOGNITO_ACTIVE, 40 INCOGNITO_ACTIVE,
66 INCOGNITO_LAUNCHED, 41 INCOGNITO_LAUNCHED,
67 PROTOBUF_NOT_PARSED, 42 PROTOBUF_NOT_PARSED,
(...skipping 10 matching lines...) Expand all
78 outcome, 53 outcome,
79 NUM_OUTCOMES); 54 NUM_OUTCOMES);
80 } 55 }
81 56
82 // Returns true if a normal user is logged in. Returns false otherwise (e.g. if 57 // Returns true if a normal user is logged in. Returns false otherwise (e.g. if
83 // logged in as a guest or as a kiosk app). 58 // logged in as a guest or as a kiosk app).
84 bool IsNormalUserLoggedIn() { 59 bool IsNormalUserLoggedIn() {
85 return chromeos::LoginState::Get()->IsUserAuthenticated(); 60 return chromeos::LoginState::Get()->IsUserAuthenticated();
86 } 61 }
87 62
63 // Returns a random TimeDelta between zero and |max|.
64 base::TimeDelta RandomTimeDelta(base::TimeDelta max) {
65 return base::TimeDelta::FromMicroseconds(
66 base::RandGenerator(max.InMicroseconds()));
67 }
68
88 } // namespace 69 } // namespace
89 70
90 namespace metrics { 71 PerfProvider::CollectionParams::CollectionParams(
72 base::TimeDelta collection_duration,
73 base::TimeDelta periodic_interval,
74 TriggerParams resume_from_suspend,
75 TriggerParams restore_session)
76 : collection_duration_(collection_duration.ToInternalValue()),
77 periodic_interval_(periodic_interval.ToInternalValue()),
78 resume_from_suspend_(resume_from_suspend),
79 restore_session_(restore_session) {
80 }
81
82 PerfProvider::CollectionParams::TriggerParams::TriggerParams(
83 int64 sampling_factor,
84 base::TimeDelta max_collection_delay)
85 : sampling_factor_(sampling_factor),
86 max_collection_delay_(max_collection_delay.ToInternalValue()) {
87 }
88
89 const PerfProvider::CollectionParams PerfProvider::kDefaultParameters(
90 /* collection_duration = */ base::TimeDelta::FromSeconds(2),
91 /* periodic_interval = */ base::TimeDelta::FromHours(3),
92 /* resume_from_suspend = */ PerfProvider::CollectionParams::TriggerParams(
93 /* sampling_factor = */ 10,
94 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)),
95 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams(
96 /* sampling_factor = */ 10,
97 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10)));
91 98
92 PerfProvider::PerfProvider() 99 PerfProvider::PerfProvider()
93 : login_observer_(this), 100 : collection_params_(kDefaultParameters),
94 next_profiling_interval_start_(base::TimeTicks::Now()), 101 login_observer_(this),
95 weak_factory_(this) { 102 next_profiling_interval_start_(base::TimeTicks::Now()),
103 weak_factory_(this) {
96 // Register the login observer with LoginState. 104 // Register the login observer with LoginState.
97 chromeos::LoginState::Get()->AddObserver(&login_observer_); 105 chromeos::LoginState::Get()->AddObserver(&login_observer_);
98 106
99 // Register as an observer of power manager events. 107 // Register as an observer of power manager events.
100 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> 108 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
101 AddObserver(this); 109 AddObserver(this);
102 110
103 // Register as an observer of session restore. 111 // Register as an observer of session restore.
104 on_session_restored_callback_subscription_ = 112 on_session_restored_callback_subscription_ =
105 SessionRestore::RegisterOnSessionRestoredCallback( 113 SessionRestore::RegisterOnSessionRestoredCallback(
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // canceled. Do not collect anything if that's the case. 207 // canceled. Do not collect anything if that's the case.
200 if (sleep_duration == base::TimeDelta()) 208 if (sleep_duration == base::TimeDelta())
201 return; 209 return;
202 210
203 // Do not collect a profile unless logged in. The system behavior when closing 211 // Do not collect a profile unless logged in. The system behavior when closing
204 // the lid or idling when not logged in is currently to shut down instead of 212 // the lid or idling when not logged in is currently to shut down instead of
205 // suspending. But it's good to enforce the rule here in case that changes. 213 // suspending. But it's good to enforce the rule here in case that changes.
206 if (!IsNormalUserLoggedIn()) 214 if (!IsNormalUserLoggedIn())
207 return; 215 return;
208 216
209 // Collect a profile only 1/|kResumeSamplingFactor| of the time, to avoid 217 // Collect a profile only 1/|sampling_factor| of the time, to avoid
210 // collecting too much data. 218 // collecting too much data.
211 if (base::RandGenerator(kResumeSamplingFactor) != 0) 219 const auto& resume_params = collection_params_.resume_from_suspend();
220 if (base::RandGenerator(resume_params.sampling_factor()) != 0)
212 return; 221 return;
213 222
214 // Override any existing profiling. 223 // Override any existing profiling.
215 if (timer_.IsRunning()) 224 if (timer_.IsRunning())
216 timer_.Stop(); 225 timer_.Stop();
217 226
218 // Randomly pick a delay before doing the collection. 227 // Randomly pick a delay before doing the collection.
219 base::TimeDelta collection_delay = 228 base::TimeDelta collection_delay = RandomTimeDelta(
220 base::TimeDelta::FromMilliseconds( 229 resume_params.max_collection_delay());
221 base::RandGenerator(kMaxResumeCollectionDelayMs));
222 timer_.Start(FROM_HERE, 230 timer_.Start(FROM_HERE,
223 collection_delay, 231 collection_delay,
224 base::Bind(&PerfProvider::CollectPerfDataAfterResume, 232 base::Bind(&PerfProvider::CollectPerfDataAfterResume,
225 weak_factory_.GetWeakPtr(), 233 weak_factory_.GetWeakPtr(),
226 sleep_duration, 234 sleep_duration,
227 collection_delay)); 235 collection_delay));
228 } 236 }
229 237
230 void PerfProvider::OnSessionRestoreDone(int num_tabs_restored) { 238 void PerfProvider::OnSessionRestoreDone(int num_tabs_restored) {
231 // Do not collect a profile unless logged in as a normal user. 239 // Do not collect a profile unless logged in as a normal user.
232 if (!IsNormalUserLoggedIn()) 240 if (!IsNormalUserLoggedIn())
233 return; 241 return;
234 242
235 // Collect a profile only 1/|kRestoreSessionSamplingFactor| of the time, to 243 // Collect a profile only 1/|sampling_factor| of the time, to
236 // avoid collecting too much data and potentially causing UI latency. 244 // avoid collecting too much data and potentially causing UI latency.
237 if (base::RandGenerator(kRestoreSessionSamplingFactor) != 0) 245 const auto& restore_params = collection_params_.restore_session();
246 if (base::RandGenerator(restore_params.sampling_factor()) != 0)
238 return; 247 return;
239 248
240 const base::TimeDelta min_interval = 249 const auto min_interval = base::TimeDelta::FromSeconds(
241 base::TimeDelta::FromMilliseconds( 250 kMinIntervalBetweenSessionRestoreCollectionsInSec);
242 kMinIntervalBetweenSessionRestoreCollectionsMs);
243 const base::TimeDelta time_since_last_collection = 251 const base::TimeDelta time_since_last_collection =
244 (base::TimeTicks::Now() - last_session_restore_collection_time_); 252 (base::TimeTicks::Now() - last_session_restore_collection_time_);
245 // Do not collect if there hasn't been enough elapsed time since the last 253 // Do not collect if there hasn't been enough elapsed time since the last
246 // collection. 254 // collection.
247 if (!last_session_restore_collection_time_.is_null() && 255 if (!last_session_restore_collection_time_.is_null() &&
248 time_since_last_collection < min_interval) { 256 time_since_last_collection < min_interval) {
249 return; 257 return;
250 } 258 }
251 259
252 // Stop any existing scheduled collection. 260 // Stop any existing scheduled collection.
253 if (timer_.IsRunning()) 261 if (timer_.IsRunning())
254 timer_.Stop(); 262 timer_.Stop();
255 263
256 // Randomly pick a delay before doing the collection. 264 // Randomly pick a delay before doing the collection.
257 base::TimeDelta collection_delay = 265 base::TimeDelta collection_delay = RandomTimeDelta(
258 base::TimeDelta::FromMilliseconds( 266 restore_params.max_collection_delay());
259 base::RandGenerator(kMaxRestoreSessionCollectionDelayMs));
260 timer_.Start( 267 timer_.Start(
261 FROM_HERE, 268 FROM_HERE,
262 collection_delay, 269 collection_delay,
263 base::Bind(&PerfProvider::CollectPerfDataAfterSessionRestore, 270 base::Bind(&PerfProvider::CollectPerfDataAfterSessionRestore,
264 weak_factory_.GetWeakPtr(), 271 weak_factory_.GetWeakPtr(),
265 collection_delay, 272 collection_delay,
266 num_tabs_restored)); 273 num_tabs_restored));
267 } 274 }
268 275
269 void PerfProvider::OnUserLoggedIn() { 276 void PerfProvider::OnUserLoggedIn() {
270 login_time_ = base::TimeTicks::Now(); 277 login_time_ = base::TimeTicks::Now();
271 ScheduleIntervalCollection(); 278 ScheduleIntervalCollection();
272 } 279 }
273 280
274 void PerfProvider::Deactivate() { 281 void PerfProvider::Deactivate() {
275 // Stop the timer, but leave |cached_perf_data_| intact. 282 // Stop the timer, but leave |cached_perf_data_| intact.
276 timer_.Stop(); 283 timer_.Stop();
277 } 284 }
278 285
279 void PerfProvider::ScheduleIntervalCollection() { 286 void PerfProvider::ScheduleIntervalCollection() {
280 DCHECK(CalledOnValidThread()); 287 DCHECK(CalledOnValidThread());
281 if (timer_.IsRunning()) 288 if (timer_.IsRunning())
282 return; 289 return;
283 290
284 // Pick a random time in the current interval. 291 // Pick a random time in the current interval.
285 base::TimeTicks scheduled_time = 292 base::TimeTicks scheduled_time =
286 next_profiling_interval_start_ + 293 next_profiling_interval_start_ +
287 base::TimeDelta::FromMilliseconds( 294 RandomTimeDelta(collection_params_.periodic_interval());
288 base::RandGenerator(kPerfProfilingIntervalMs));
289 295
290 // If the scheduled time has already passed in the time it took to make the 296 // If the scheduled time has already passed in the time it took to make the
291 // above calculations, trigger the collection event immediately. 297 // above calculations, trigger the collection event immediately.
292 base::TimeTicks now = base::TimeTicks::Now(); 298 base::TimeTicks now = base::TimeTicks::Now();
293 if (scheduled_time < now) 299 if (scheduled_time < now)
294 scheduled_time = now; 300 scheduled_time = now;
295 301
296 timer_.Start(FROM_HERE, scheduled_time - now, this, 302 timer_.Start(FROM_HERE, scheduled_time - now, this,
297 &PerfProvider::DoPeriodicCollection); 303 &PerfProvider::DoPeriodicCollection);
298 304
299 // Update the profiling interval tracker to the start of the next interval. 305 // Update the profiling interval tracker to the start of the next interval.
300 next_profiling_interval_start_ += 306 next_profiling_interval_start_ += collection_params_.periodic_interval();
301 base::TimeDelta::FromMilliseconds(kPerfProfilingIntervalMs);
302 } 307 }
303 308
304 void PerfProvider::CollectIfNecessary( 309 void PerfProvider::CollectIfNecessary(
305 scoped_ptr<SampledProfile> sampled_profile) { 310 scoped_ptr<SampledProfile> sampled_profile) {
306 DCHECK(CalledOnValidThread()); 311 DCHECK(CalledOnValidThread());
307 312
308 // Schedule another interval collection. This call makes sense regardless of 313 // Schedule another interval collection. This call makes sense regardless of
309 // whether or not the current collection was interval-triggered. If it had 314 // whether or not the current collection was interval-triggered. If it had
310 // been another type of trigger event, the interval timer would have been 315 // been another type of trigger event, the interval timer would have been
311 // halted, so it makes sense to reschedule a new interval collection. 316 // halted, so it makes sense to reschedule a new interval collection.
(...skipping 16 matching lines...) Expand all
328 AddToPerfHistogram(INCOGNITO_ACTIVE); 333 AddToPerfHistogram(INCOGNITO_ACTIVE);
329 return; 334 return;
330 } 335 }
331 336
332 scoped_ptr<WindowedIncognitoObserver> incognito_observer( 337 scoped_ptr<WindowedIncognitoObserver> incognito_observer(
333 new WindowedIncognitoObserver); 338 new WindowedIncognitoObserver);
334 339
335 chromeos::DebugDaemonClient* client = 340 chromeos::DebugDaemonClient* client =
336 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); 341 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
337 342
338 base::TimeDelta collection_duration = base::TimeDelta::FromSeconds(
339 kPerfCommandDurationDefaultSeconds);
340
341 client->GetPerfOutput( 343 client->GetPerfOutput(
342 collection_duration.InSeconds(), 344 collection_params_.collection_duration().InSeconds(),
343 base::Bind(&PerfProvider::ParseOutputProtoIfValid, 345 base::Bind(&PerfProvider::ParseOutputProtoIfValid,
344 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer), 346 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer),
345 base::Passed(&sampled_profile))); 347 base::Passed(&sampled_profile)));
346 } 348 }
347 349
348 void PerfProvider::DoPeriodicCollection() { 350 void PerfProvider::DoPeriodicCollection() {
349 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 351 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
350 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); 352 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION);
351 353
352 CollectIfNecessary(sampled_profile.Pass()); 354 CollectIfNecessary(sampled_profile.Pass());
(...skipping 18 matching lines...) Expand all
371 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 373 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
372 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); 374 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION);
373 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); 375 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds());
374 sampled_profile->set_num_tabs_restored(num_tabs_restored); 376 sampled_profile->set_num_tabs_restored(num_tabs_restored);
375 377
376 CollectIfNecessary(sampled_profile.Pass()); 378 CollectIfNecessary(sampled_profile.Pass());
377 last_session_restore_collection_time_ = base::TimeTicks::Now(); 379 last_session_restore_collection_time_ = base::TimeTicks::Now();
378 } 380 }
379 381
380 } // namespace metrics 382 } // namespace metrics
OLDNEW
« no previous file with comments | « chrome/browser/metrics/perf/perf_provider_chromeos.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698