1 // Copyright 2015 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METRICS_PROVIDER_H_ 6 #define COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METRICS_PROVIDER_H_ 7 8 #include <map> 9 #include <string> 10 11 #include "base/feature_list.h" 12 #include "base/functional/callback.h" 13 #include "base/time/time.h" 14 #include "build/buildflag.h" 15 #include "components/metrics/metrics_provider.h" 16 #include "third_party/metrics_proto/execution_context.pb.h" 17 #include "third_party/metrics_proto/sampled_profile.pb.h" 18 19 namespace metrics { 20 21 class ChromeUserMetricsExtension; 22 23 // base::Feature for reporting CPU profiles. Provided here for test use. 24 BASE_DECLARE_FEATURE(kSamplingProfilerReporting); 25 26 // Performs metrics logging for the stack sampling profiler. 27 class CallStackProfileMetricsProvider : public MetricsProvider { 28 public: 29 // A callback type that can be registered to intercept profiles, for testing 30 // purposes. 31 using InterceptorCallback = 32 base::RepeatingCallback<void(SampledProfile profile)>; 33 34 #if BUILDFLAG(IS_CHROMEOS) 35 // Count of profiles, brokens down by the Process and Thread type of the 36 // profile. 37 using ProcessThreadCount = 38 std::map<::metrics::Process, std::map<::metrics::Thread, int>>; 39 #endif 40 41 CallStackProfileMetricsProvider(); 42 43 CallStackProfileMetricsProvider(const CallStackProfileMetricsProvider&) = 44 delete; 45 CallStackProfileMetricsProvider& operator=( 46 const CallStackProfileMetricsProvider&) = delete; 47 48 ~CallStackProfileMetricsProvider() override; 49 50 // Receives SampledProfile protobuf instances. May be called on any thread. 51 static void ReceiveProfile(base::TimeTicks profile_start_time, 52 SampledProfile profile); 53 54 // Receives serialized SampledProfile protobuf instances. May be called on any 55 // thread. Note that receiving serialized profiles is supported separately so 56 // that profiles received in serialized form can be kept in that form until 57 // upload. This significantly reduces memory costs. Serialized profile strings 58 // may be large, so the caller must use std::move() to provide them to this 59 // API rather than copying by value. 60 static void ReceiveSerializedProfile(base::TimeTicks profile_start_time, 61 bool is_heap_profile, 62 std::string&& serialized_profile); 63 64 // Allows tests to intercept received CPU profiles, to validate that the 65 // expected profiles are received. This function must be invoked prior to 66 // starting any profiling since the callback is accessed asynchronously on the 67 // profiling thread. 68 static void SetCpuInterceptorCallbackForTesting(InterceptorCallback callback); 69 70 #if BUILDFLAG(IS_CHROMEOS) 71 // Gets the counts of all successfully collected profiles, broken down by 72 // process type and thread type. "Successfully collected" is defined pretty 73 // minimally (we got a couple of frames). Expensive function; intended only 74 // to be run during ChromeOS tast integration testing, not to be run on end- 75 // user machines. 76 static ProcessThreadCount GetSuccessfullyCollectedCounts(); 77 #endif 78 79 // MetricsProvider: 80 void OnRecordingEnabled() override; 81 void OnRecordingDisabled() override; 82 void ProvideCurrentSessionData( 83 ChromeUserMetricsExtension* uma_proto) override; 84 85 protected: 86 // Reset the static state to the defaults after startup. 87 static void ResetStaticStateForTesting(); 88 }; 89 90 } // namespace metrics 91 92 #endif // COMPONENTS_METRICS_CALL_STACKS_CALL_STACK_PROFILE_METRICS_PROVIDER_H_ 93