| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/metrics/call_stack_profile_metrics_provider.h" | 5 #include "components/metrics/call_stack_profile_metrics_provider.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cstring> | 11 #include <cstring> |
| 12 #include <map> | 12 #include <map> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/bind.h" | 17 #include "base/bind.h" |
| 18 #include "base/location.h" | 18 #include "base/location.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/memory/singleton.h" | 21 #include "base/memory/singleton.h" |
| 22 #include "base/metrics/field_trial.h" | 22 #include "base/metrics/field_trial_params.h" |
| 23 #include "base/metrics/metrics_hashes.h" | 23 #include "base/metrics/metrics_hashes.h" |
| 24 #include "base/process/process_info.h" |
| 24 #include "base/profiler/stack_sampling_profiler.h" | 25 #include "base/profiler/stack_sampling_profiler.h" |
| 25 #include "base/single_thread_task_runner.h" | 26 #include "base/single_thread_task_runner.h" |
| 26 #include "base/synchronization/lock.h" | 27 #include "base/synchronization/lock.h" |
| 27 #include "base/threading/thread_task_runner_handle.h" | 28 #include "base/threading/thread_task_runner_handle.h" |
| 28 #include "base/time/time.h" | 29 #include "base/time/time.h" |
| 30 #include "build/build_config.h" |
| 29 #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" | 31 #include "components/metrics/proto/chrome_user_metrics_extension.pb.h" |
| 30 | 32 |
| 31 using base::StackSamplingProfiler; | 33 using base::StackSamplingProfiler; |
| 32 | 34 |
| 33 namespace metrics { | 35 namespace metrics { |
| 34 | 36 |
| 37 namespace internal { |
| 38 |
| 39 base::TimeDelta GetUptime() { |
| 40 static base::Time process_creation_time; |
| 41 // base::CurrentProcessInfo::CreationTime() is only defined on some platforms. |
| 42 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) |
| 43 if (process_creation_time.is_null()) |
| 44 process_creation_time = base::CurrentProcessInfo::CreationTime(); |
| 45 #else |
| 46 NOTREACHED(); |
| 47 #endif |
| 48 DCHECK(!process_creation_time.is_null()); |
| 49 return base::Time::Now() - process_creation_time; |
| 50 } |
| 51 |
| 52 } // namespace internal |
| 53 |
| 35 namespace { | 54 namespace { |
| 36 | 55 |
| 56 // Interval for periodic (post-startup) sampling, when enabled. |
| 57 constexpr base::TimeDelta kPeriodicSamplingInterval = |
| 58 base::TimeDelta::FromSeconds(1); |
| 59 |
| 37 // Provide a mapping from the C++ "enum" definition of various process mile- | 60 // Provide a mapping from the C++ "enum" definition of various process mile- |
| 38 // stones to the equivalent protobuf "enum" definition. This table-lookup | 61 // stones to the equivalent protobuf "enum" definition. This table-lookup |
| 39 // conversion allows for the implementation to evolve and still be compatible | 62 // conversion allows for the implementation to evolve and still be compatible |
| 40 // with the protobuf -- even if there are ever more than 32 defined proto | 63 // with the protobuf -- even if there are ever more than 32 defined proto |
| 41 // values, though never more than 32 could be in-use in a given C++ version | 64 // values, though never more than 32 could be in-use in a given C++ version |
| 42 // of the code. | 65 // of the code. |
| 43 const ProcessPhase | 66 const ProcessPhase |
| 44 kProtoPhases[CallStackProfileMetricsProvider::MILESTONES_MAX_VALUE] = { | 67 kProtoPhases[CallStackProfileMetricsProvider::MILESTONES_MAX_VALUE] = { |
| 45 ProcessPhase::MAIN_LOOP_START, | 68 ProcessPhase::MAIN_LOOP_START, |
| 46 ProcessPhase::MAIN_NAVIGATION_START, | 69 ProcessPhase::MAIN_NAVIGATION_START, |
| 47 ProcessPhase::MAIN_NAVIGATION_FINISHED, | 70 ProcessPhase::MAIN_NAVIGATION_FINISHED, |
| 48 ProcessPhase::FIRST_NONEMPTY_PAINT, | 71 ProcessPhase::FIRST_NONEMPTY_PAINT, |
| 49 | 72 |
| 50 ProcessPhase::SHUTDOWN_START, | 73 ProcessPhase::SHUTDOWN_START, |
| 51 }; | 74 }; |
| 52 | 75 |
| 76 // Parameters for browser process sampling. Not const since these may be |
| 77 // changed when transitioning from start-up profiling to periodic profiling. |
| 78 CallStackProfileParams g_browser_process_sampling_params( |
| 79 metrics::CallStackProfileParams::BROWSER_PROCESS, |
| 80 metrics::CallStackProfileParams::UI_THREAD, |
| 81 metrics::CallStackProfileParams::PROCESS_STARTUP, |
| 82 metrics::CallStackProfileParams::MAY_SHUFFLE); |
| 83 |
| 53 // ProfilesState -------------------------------------------------------------- | 84 // ProfilesState -------------------------------------------------------------- |
| 54 | 85 |
| 55 // A set of profiles and the CallStackProfileMetricsProvider state associated | 86 // A set of profiles and the CallStackProfileMetricsProvider state associated |
| 56 // with them. | 87 // with them. |
| 57 struct ProfilesState { | 88 struct ProfilesState { |
| 58 ProfilesState(const CallStackProfileParams& params, | 89 ProfilesState(const CallStackProfileParams& params, |
| 59 StackSamplingProfiler::CallStackProfiles profiles, | 90 StackSamplingProfiler::CallStackProfiles profiles); |
| 60 base::TimeTicks start_timestamp); | |
| 61 ProfilesState(ProfilesState&&); | 91 ProfilesState(ProfilesState&&); |
| 62 ProfilesState& operator=(ProfilesState&&); | 92 ProfilesState& operator=(ProfilesState&&); |
| 63 | 93 |
| 64 // The metrics-related parameters provided to | 94 // The metrics-related parameters provided to |
| 65 // CallStackProfileMetricsProvider::GetProfilerCallback(). | 95 // CallStackProfileMetricsProvider::GetProfilerCallback(). |
| 66 CallStackProfileParams params; | 96 CallStackProfileParams params; |
| 67 | 97 |
| 68 // The call stack profiles collected by the profiler. | 98 // The call stack profiles collected by the profiler. |
| 69 StackSamplingProfiler::CallStackProfiles profiles; | 99 StackSamplingProfiler::CallStackProfiles profiles; |
| 70 | 100 |
| 71 // The time at which the CallStackProfileMetricsProvider became aware of the | |
| 72 // request for profiling. In particular, this is when callback was requested | |
| 73 // via CallStackProfileMetricsProvider::GetProfilerCallback(). Used to | |
| 74 // determine if collection was disabled during the collection of the profile. | |
| 75 base::TimeTicks start_timestamp; | |
| 76 | |
| 77 private: | 101 private: |
| 78 DISALLOW_COPY_AND_ASSIGN(ProfilesState); | 102 DISALLOW_COPY_AND_ASSIGN(ProfilesState); |
| 79 }; | 103 }; |
| 80 | 104 |
| 81 ProfilesState::ProfilesState(const CallStackProfileParams& params, | 105 ProfilesState::ProfilesState(const CallStackProfileParams& params, |
| 82 StackSamplingProfiler::CallStackProfiles profiles, | 106 StackSamplingProfiler::CallStackProfiles profiles) |
| 83 base::TimeTicks start_timestamp) | 107 : params(params), profiles(std::move(profiles)) {} |
| 84 : params(params), | |
| 85 profiles(std::move(profiles)), | |
| 86 start_timestamp(start_timestamp) {} | |
| 87 | 108 |
| 88 ProfilesState::ProfilesState(ProfilesState&&) = default; | 109 ProfilesState::ProfilesState(ProfilesState&&) = default; |
| 89 | 110 |
| 90 // Some versions of GCC need this for push_back to work with std::move. | 111 // Some versions of GCC need this for push_back to work with std::move. |
| 91 ProfilesState& ProfilesState::operator=(ProfilesState&&) = default; | 112 ProfilesState& ProfilesState::operator=(ProfilesState&&) = default; |
| 92 | 113 |
| 93 // PendingProfiles ------------------------------------------------------------ | 114 // PendingProfiles ------------------------------------------------------------ |
| 94 | 115 |
| 95 // Singleton class responsible for retaining profiles received via the callback | 116 // Singleton class responsible for retaining profiles received via the callback |
| 96 // created by CallStackProfileMetricsProvider::GetProfilerCallback(). These are | 117 // created by CallStackProfileMetricsProvider::GetProfilerCallback(). These are |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 194 } |
| 174 | 195 |
| 175 void PendingProfiles::CollectProfilesIfCollectionEnabled( | 196 void PendingProfiles::CollectProfilesIfCollectionEnabled( |
| 176 ProfilesState profiles) { | 197 ProfilesState profiles) { |
| 177 base::AutoLock scoped_lock(lock_); | 198 base::AutoLock scoped_lock(lock_); |
| 178 | 199 |
| 179 // Only collect if collection is not disabled and hasn't been disabled | 200 // Only collect if collection is not disabled and hasn't been disabled |
| 180 // since the start of collection for this profile. | 201 // since the start of collection for this profile. |
| 181 if (!collection_enabled_ || | 202 if (!collection_enabled_ || |
| 182 (!last_collection_disable_time_.is_null() && | 203 (!last_collection_disable_time_.is_null() && |
| 183 last_collection_disable_time_ >= profiles.start_timestamp)) { | 204 last_collection_disable_time_ >= profiles.params.start_timestamp)) { |
| 184 return; | 205 return; |
| 185 } | 206 } |
| 186 | 207 |
| 208 if (profiles.params.trigger == CallStackProfileParams::PERIODIC_COLLECTION) { |
| 209 DCHECK_EQ(1U, profiles.profiles.size()); |
| 210 profiles.profiles[0].sampling_period = kPeriodicSamplingInterval; |
| 211 // Use the process uptime as the collection time to indicate when this |
| 212 // profile was collected. This is useful to account for uptime bias during |
| 213 // analysis. |
| 214 profiles.profiles[0].profile_duration = internal::GetUptime(); |
| 215 } |
| 216 |
| 187 profiles_.push_back(std::move(profiles)); | 217 profiles_.push_back(std::move(profiles)); |
| 188 } | 218 } |
| 189 | 219 |
| 190 void PendingProfiles::ResetToDefaultStateForTesting() { | 220 void PendingProfiles::ResetToDefaultStateForTesting() { |
| 191 base::AutoLock scoped_lock(lock_); | 221 base::AutoLock scoped_lock(lock_); |
| 192 | 222 |
| 193 collection_enabled_ = true; | 223 collection_enabled_ = true; |
| 194 last_collection_disable_time_ = base::TimeTicks(); | 224 last_collection_disable_time_ = base::TimeTicks(); |
| 195 profiles_.clear(); | 225 profiles_.clear(); |
| 196 } | 226 } |
| 197 | 227 |
| 198 // |collection_enabled_| is initialized to true to collect any profiles that are | 228 // |collection_enabled_| is initialized to true to collect any profiles that are |
| 199 // generated prior to creation of the CallStackProfileMetricsProvider. The | 229 // generated prior to creation of the CallStackProfileMetricsProvider. The |
| 200 // ultimate disposition of these pre-creation collected profiles will be | 230 // ultimate disposition of these pre-creation collected profiles will be |
| 201 // determined by the initial recording state provided to | 231 // determined by the initial recording state provided to |
| 202 // CallStackProfileMetricsProvider. | 232 // CallStackProfileMetricsProvider. |
| 203 PendingProfiles::PendingProfiles() : collection_enabled_(true) {} | 233 PendingProfiles::PendingProfiles() : collection_enabled_(true) {} |
| 204 | 234 |
| 205 PendingProfiles::~PendingProfiles() {} | 235 PendingProfiles::~PendingProfiles() {} |
| 206 | 236 |
| 207 // Functions to process completed profiles ------------------------------------ | 237 // Functions to process completed profiles ------------------------------------ |
| 208 | 238 |
| 209 // Will be invoked on either the main thread or the profiler's thread. Provides | 239 // Will be invoked on either the main thread or the profiler's thread. Provides |
| 210 // the profiles to PendingProfiles to append, if the collecting state allows. | 240 // the profiles to PendingProfiles to append, if the collecting state allows. |
| 211 void ReceiveCompletedProfilesImpl( | 241 base::Optional<StackSamplingProfiler::SamplingParams> |
| 212 const CallStackProfileParams& params, | 242 ReceiveCompletedProfilesImpl( |
| 213 base::TimeTicks start_timestamp, | 243 CallStackProfileParams* params, |
| 214 StackSamplingProfiler::CallStackProfiles profiles) { | 244 StackSamplingProfiler::CallStackProfiles profiles) { |
| 215 PendingProfiles::GetInstance()->CollectProfilesIfCollectionEnabled( | 245 PendingProfiles::GetInstance()->CollectProfilesIfCollectionEnabled( |
| 216 ProfilesState(params, std::move(profiles), start_timestamp)); | 246 ProfilesState(*params, std::move(profiles))); |
| 247 |
| 248 // Now, schedule periodic sampling every 1s, if enabled by trial. |
| 249 // TODO(asvitkine): Support periodic sampling for non-browser processes. |
| 250 // TODO(asvitkine): In the future, we may want to have finer grained control |
| 251 // over this, for example ending sampling after some amount of time. |
| 252 if (CallStackProfileMetricsProvider::IsPeriodicSamplingEnabled() && |
| 253 params->process == CallStackProfileParams::BROWSER_PROCESS && |
| 254 params->thread == CallStackProfileParams::UI_THREAD) { |
| 255 params->trigger = metrics::CallStackProfileParams::PERIODIC_COLLECTION; |
| 256 params->start_timestamp = base::TimeTicks::Now(); |
| 257 |
| 258 StackSamplingProfiler::SamplingParams sampling_params; |
| 259 sampling_params.initial_delay = kPeriodicSamplingInterval; |
| 260 sampling_params.bursts = 1; |
| 261 sampling_params.samples_per_burst = 1; |
| 262 // Below are unused: |
| 263 sampling_params.burst_interval = base::TimeDelta::FromMilliseconds(0); |
| 264 sampling_params.sampling_interval = base::TimeDelta::FromMilliseconds(0); |
| 265 return sampling_params; |
| 266 } |
| 267 return base::Optional<StackSamplingProfiler::SamplingParams>(); |
| 217 } | 268 } |
| 218 | 269 |
| 219 // Invoked on an arbitrary thread. Ignores the provided profiles. | 270 // Invoked on an arbitrary thread. Ignores the provided profiles. |
| 220 void IgnoreCompletedProfiles( | 271 base::Optional<StackSamplingProfiler::SamplingParams> IgnoreCompletedProfiles( |
| 221 StackSamplingProfiler::CallStackProfiles profiles) {} | 272 StackSamplingProfiler::CallStackProfiles profiles) { |
| 273 return base::Optional<StackSamplingProfiler::SamplingParams>(); |
| 274 } |
| 222 | 275 |
| 223 // Functions to encode protobufs ---------------------------------------------- | 276 // Functions to encode protobufs ---------------------------------------------- |
| 224 | 277 |
| 225 // The protobuf expects the MD5 checksum prefix of the module name. | 278 // The protobuf expects the MD5 checksum prefix of the module name. |
| 226 uint64_t HashModuleFilename(const base::FilePath& filename) { | 279 uint64_t HashModuleFilename(const base::FilePath& filename) { |
| 227 const base::FilePath::StringType basename = filename.BaseName().value(); | 280 const base::FilePath::StringType basename = filename.BaseName().value(); |
| 228 // Copy the bytes in basename into a string buffer. | 281 // Copy the bytes in basename into a string buffer. |
| 229 size_t basename_length_in_bytes = | 282 size_t basename_length_in_bytes = |
| 230 basename.size() * sizeof(base::FilePath::CharType); | 283 basename.size() * sizeof(base::FilePath::CharType); |
| 231 std::string name_bytes(basename_length_in_bytes, '\0'); | 284 std::string name_bytes(basename_length_in_bytes, '\0'); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 CallStackProfileParams::Trigger trigger) { | 451 CallStackProfileParams::Trigger trigger) { |
| 399 switch (trigger) { | 452 switch (trigger) { |
| 400 case CallStackProfileParams::UNKNOWN: | 453 case CallStackProfileParams::UNKNOWN: |
| 401 return SampledProfile::UNKNOWN_TRIGGER_EVENT; | 454 return SampledProfile::UNKNOWN_TRIGGER_EVENT; |
| 402 case CallStackProfileParams::PROCESS_STARTUP: | 455 case CallStackProfileParams::PROCESS_STARTUP: |
| 403 return SampledProfile::PROCESS_STARTUP; | 456 return SampledProfile::PROCESS_STARTUP; |
| 404 case CallStackProfileParams::JANKY_TASK: | 457 case CallStackProfileParams::JANKY_TASK: |
| 405 return SampledProfile::JANKY_TASK; | 458 return SampledProfile::JANKY_TASK; |
| 406 case CallStackProfileParams::THREAD_HUNG: | 459 case CallStackProfileParams::THREAD_HUNG: |
| 407 return SampledProfile::THREAD_HUNG; | 460 return SampledProfile::THREAD_HUNG; |
| 461 case CallStackProfileParams::PERIODIC_COLLECTION: |
| 462 return SampledProfile::PERIODIC_COLLECTION; |
| 408 } | 463 } |
| 409 NOTREACHED(); | 464 NOTREACHED(); |
| 410 return SampledProfile::UNKNOWN_TRIGGER_EVENT; | 465 return SampledProfile::UNKNOWN_TRIGGER_EVENT; |
| 411 } | 466 } |
| 412 | 467 |
| 413 } // namespace | 468 } // namespace |
| 414 | 469 |
| 415 // CallStackProfileMetricsProvider -------------------------------------------- | 470 // CallStackProfileMetricsProvider -------------------------------------------- |
| 416 | 471 |
| 417 const char CallStackProfileMetricsProvider::kFieldTrialName[] = | 472 const base::Feature CallStackProfileMetricsProvider::kEnableReporting = { |
| 418 "StackProfiling"; | 473 "SamplingProfilerReporting", base::FEATURE_DISABLED_BY_DEFAULT}; |
| 419 const char CallStackProfileMetricsProvider::kReportProfilesGroupName[] = | |
| 420 "Report profiles"; | |
| 421 | 474 |
| 422 CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() { | 475 CallStackProfileMetricsProvider::CallStackProfileMetricsProvider() { |
| 423 } | 476 } |
| 424 | 477 |
| 425 CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() { | 478 CallStackProfileMetricsProvider::~CallStackProfileMetricsProvider() { |
| 426 } | 479 } |
| 427 | 480 |
| 428 // This function can be invoked on an abitrary thread. | 481 // This function can be invoked on an abitrary thread. |
| 429 StackSamplingProfiler::CompletedCallback | 482 StackSamplingProfiler::CompletedCallback |
| 430 CallStackProfileMetricsProvider::GetProfilerCallback( | 483 CallStackProfileMetricsProvider::GetProfilerCallback( |
| 431 const CallStackProfileParams& params) { | 484 CallStackProfileParams* params) { |
| 432 // Ignore the profiles if the collection is disabled. If the collection state | 485 // Ignore the profiles if the collection is disabled. If the collection state |
| 433 // changes while collecting, this will be detected by the callback and | 486 // changes while collecting, this will be detected by the callback and |
| 434 // profiles will be ignored at that point. | 487 // profiles will be ignored at that point. |
| 435 if (!PendingProfiles::GetInstance()->IsCollectionEnabled()) | 488 if (!PendingProfiles::GetInstance()->IsCollectionEnabled()) |
| 436 return base::Bind(&IgnoreCompletedProfiles); | 489 return base::Bind(&IgnoreCompletedProfiles); |
| 437 | 490 |
| 438 return base::Bind(&ReceiveCompletedProfilesImpl, params, | 491 params->start_timestamp = base::TimeTicks::Now(); |
| 439 base::TimeTicks::Now()); | 492 return base::Bind(&ReceiveCompletedProfilesImpl, params); |
| 493 } |
| 494 |
| 495 StackSamplingProfiler::CompletedCallback |
| 496 CallStackProfileMetricsProvider::GetProfilerCallbackForBrowserProcessStartup() { |
| 497 return GetProfilerCallback(&g_browser_process_sampling_params); |
| 440 } | 498 } |
| 441 | 499 |
| 442 // static | 500 // static |
| 443 void CallStackProfileMetricsProvider::ReceiveCompletedProfiles( | 501 void CallStackProfileMetricsProvider::ReceiveCompletedProfiles( |
| 444 const CallStackProfileParams& params, | 502 CallStackProfileParams* params, |
| 445 base::TimeTicks start_timestamp, | 503 base::StackSamplingProfiler::CallStackProfiles profiles) { |
| 446 StackSamplingProfiler::CallStackProfiles profiles) { | 504 ReceiveCompletedProfilesImpl(params, std::move(profiles)); |
| 447 ReceiveCompletedProfilesImpl(params, start_timestamp, std::move(profiles)); | 505 } |
| 506 |
| 507 // static |
| 508 bool CallStackProfileMetricsProvider::IsPeriodicSamplingEnabled() { |
| 509 // Ensure FeatureList has been initialized before calling into an API that |
| 510 // calls base::FeatureList::IsEnabled() internally. While extremely unlikely, |
| 511 // it is possible that the profiler callback and therefore this function get |
| 512 // called before FeatureList initialization (e.g. if machine was suspended). |
| 513 return base::FeatureList::GetInstance() != nullptr && |
| 514 base::GetFieldTrialParamByFeatureAsBool(kEnableReporting, "periodic", |
| 515 false); |
| 448 } | 516 } |
| 449 | 517 |
| 450 void CallStackProfileMetricsProvider::OnRecordingEnabled() { | 518 void CallStackProfileMetricsProvider::OnRecordingEnabled() { |
| 451 PendingProfiles::GetInstance()->SetCollectionEnabled(true); | 519 PendingProfiles::GetInstance()->SetCollectionEnabled(true); |
| 452 } | 520 } |
| 453 | 521 |
| 454 void CallStackProfileMetricsProvider::OnRecordingDisabled() { | 522 void CallStackProfileMetricsProvider::OnRecordingDisabled() { |
| 455 PendingProfiles::GetInstance()->SetCollectionEnabled(false); | 523 PendingProfiles::GetInstance()->SetCollectionEnabled(false); |
| 456 } | 524 } |
| 457 | 525 |
| 458 void CallStackProfileMetricsProvider::ProvideGeneralMetrics( | 526 void CallStackProfileMetricsProvider::ProvideGeneralMetrics( |
| 459 ChromeUserMetricsExtension* uma_proto) { | 527 ChromeUserMetricsExtension* uma_proto) { |
| 460 std::vector<ProfilesState> pending_profiles; | 528 std::vector<ProfilesState> pending_profiles; |
| 461 PendingProfiles::GetInstance()->Swap(&pending_profiles); | 529 PendingProfiles::GetInstance()->Swap(&pending_profiles); |
| 462 | 530 |
| 463 DCHECK(IsReportingEnabledByFieldTrial() || pending_profiles.empty()); | 531 DCHECK(IsReportingEnabledByFieldTrial() || pending_profiles.empty()); |
| 464 | 532 |
| 533 // TODO(asvitkine): For post-startup periodic samples, this is currently |
| 534 // wasteful as each sample is reported in its own profile. We should attempt |
| 535 // to merge profiles to save bandwidth. |
| 465 for (const ProfilesState& profiles_state : pending_profiles) { | 536 for (const ProfilesState& profiles_state : pending_profiles) { |
| 466 for (const StackSamplingProfiler::CallStackProfile& profile : | 537 for (const StackSamplingProfiler::CallStackProfile& profile : |
| 467 profiles_state.profiles) { | 538 profiles_state.profiles) { |
| 468 SampledProfile* sampled_profile = uma_proto->add_sampled_profile(); | 539 SampledProfile* sampled_profile = uma_proto->add_sampled_profile(); |
| 469 sampled_profile->set_process(ToExecutionContextProcess( | 540 sampled_profile->set_process(ToExecutionContextProcess( |
| 470 profiles_state.params.process)); | 541 profiles_state.params.process)); |
| 471 sampled_profile->set_thread(ToExecutionContextThread( | 542 sampled_profile->set_thread(ToExecutionContextThread( |
| 472 profiles_state.params.thread)); | 543 profiles_state.params.thread)); |
| 473 sampled_profile->set_trigger_event(ToSampledProfileTriggerEvent( | 544 sampled_profile->set_trigger_event(ToSampledProfileTriggerEvent( |
| 474 profiles_state.params.trigger)); | 545 profiles_state.params.trigger)); |
| 475 CopyProfileToProto(profile, profiles_state.params.ordering_spec, | 546 CopyProfileToProto(profile, profiles_state.params.ordering_spec, |
| 476 sampled_profile->mutable_call_stack_profile()); | 547 sampled_profile->mutable_call_stack_profile()); |
| 477 } | 548 } |
| 478 } | 549 } |
| 479 } | 550 } |
| 480 | 551 |
| 481 // static | 552 // static |
| 482 void CallStackProfileMetricsProvider::ResetStaticStateForTesting() { | 553 void CallStackProfileMetricsProvider::ResetStaticStateForTesting() { |
| 483 PendingProfiles::GetInstance()->ResetToDefaultStateForTesting(); | 554 PendingProfiles::GetInstance()->ResetToDefaultStateForTesting(); |
| 484 } | 555 } |
| 485 | 556 |
| 486 // static | 557 // static |
| 487 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { | 558 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { |
| 488 const std::string group_name = base::FieldTrialList::FindFullName( | 559 return base::FeatureList::IsEnabled(kEnableReporting); |
| 489 CallStackProfileMetricsProvider::kFieldTrialName); | |
| 490 return group_name == | |
| 491 CallStackProfileMetricsProvider::kReportProfilesGroupName; | |
| 492 } | 560 } |
| 493 | 561 |
| 494 } // namespace metrics | 562 } // namespace metrics |
| OLD | NEW |