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

Side by Side Diff: components/metrics/profiler/profiler_metrics_provider.cc

Issue 985773002: Introducing phased profiling framework (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@write_to_file
Patch Set: Fixing Android compile errors. Created 5 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/profiler/profiler_metrics_provider.h" 5 #include "components/metrics/profiler/profiler_metrics_provider.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/tracked_objects.h" 11 #include "base/tracked_objects.h"
12 #include "components/metrics/metrics_log.h" 12 #include "components/metrics/metrics_log.h"
13 #include "components/nacl/common/nacl_process_type.h" 13 #include "components/nacl/common/nacl_process_type.h"
14 #include "components/variations/variations_associated_data.h" 14 #include "components/variations/variations_associated_data.h"
15 #include "content/public/common/process_type.h"
16
17 using tracked_objects::ProcessDataSnapshot;
18 15
19 namespace metrics { 16 namespace metrics {
20 17
21 namespace { 18 namespace {
22 19
23 ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType( 20 ProfilerEventProto::TrackedObject::ProcessType AsProtobufProcessType(
24 int process_type) { 21 int process_type) {
25 switch (process_type) { 22 switch (process_type) {
26 case content::PROCESS_TYPE_BROWSER: 23 case content::PROCESS_TYPE_BROWSER:
27 return ProfilerEventProto::TrackedObject::BROWSER; 24 return ProfilerEventProto::TrackedObject::BROWSER;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 67
71 // Normalizes a source filename (which is platform- and build-method-dependent) 68 // Normalizes a source filename (which is platform- and build-method-dependent)
72 // by extracting the last component of the full file name. 69 // by extracting the last component of the full file name.
73 // Example: "c:\b\build\slave\win\build\src\chrome\app\chrome_main.cc" => 70 // Example: "c:\b\build\slave\win\build\src\chrome\app\chrome_main.cc" =>
74 // "chrome_main.cc". 71 // "chrome_main.cc".
75 std::string NormalizeFileName(const std::string& file_name) { 72 std::string NormalizeFileName(const std::string& file_name) {
76 const size_t offset = file_name.find_last_of("\\/"); 73 const size_t offset = file_name.find_last_of("\\/");
77 return offset != std::string::npos ? file_name.substr(offset + 1) : file_name; 74 return offset != std::string::npos ? file_name.substr(offset + 1) : file_name;
78 } 75 }
79 76
80 void WriteProfilerData(const ProcessDataSnapshot& profiler_data, 77 void WriteProfilerData(
81 int process_type, 78 const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
82 ProfilerEventProto* performance_profile) { 79 base::ProcessId process_id,
83 for (std::vector<tracked_objects::TaskSnapshot>::const_iterator it = 80 content::ProcessType process_type,
84 profiler_data.tasks.begin(); 81 ProfilerEventProto* performance_profile) {
85 it != profiler_data.tasks.end(); 82 for (const auto& task : process_data_phase.tasks) {
86 ++it) { 83 const tracked_objects::DeathDataSnapshot& death_data = task.death_data;
87 const tracked_objects::DeathDataSnapshot& death_data = it->death_data;
88 ProfilerEventProto::TrackedObject* tracked_object = 84 ProfilerEventProto::TrackedObject* tracked_object =
89 performance_profile->add_tracked_object(); 85 performance_profile->add_tracked_object();
90 tracked_object->set_birth_thread_name_hash( 86 tracked_object->set_birth_thread_name_hash(
91 MetricsLog::Hash(MapThreadName(it->birth.thread_name))); 87 MetricsLog::Hash(MapThreadName(task.birth.thread_name)));
92 tracked_object->set_exec_thread_name_hash( 88 tracked_object->set_exec_thread_name_hash(
93 MetricsLog::Hash(MapThreadName(it->death_thread_name))); 89 MetricsLog::Hash(MapThreadName(task.death_thread_name)));
94 tracked_object->set_source_file_name_hash( 90 tracked_object->set_source_file_name_hash(
95 MetricsLog::Hash(NormalizeFileName( 91 MetricsLog::Hash(NormalizeFileName(task.birth.location.file_name)));
96 it->birth.location.file_name)));
97 tracked_object->set_source_function_name_hash( 92 tracked_object->set_source_function_name_hash(
98 MetricsLog::Hash(it->birth.location.function_name)); 93 MetricsLog::Hash(task.birth.location.function_name));
99 tracked_object->set_source_line_number(it->birth.location.line_number); 94 tracked_object->set_source_line_number(task.birth.location.line_number);
100 tracked_object->set_exec_count(death_data.count); 95 tracked_object->set_exec_count(death_data.count);
101 tracked_object->set_exec_time_total(death_data.run_duration_sum); 96 tracked_object->set_exec_time_total(death_data.run_duration_sum);
102 tracked_object->set_exec_time_sampled(death_data.run_duration_sample); 97 tracked_object->set_exec_time_sampled(death_data.run_duration_sample);
103 tracked_object->set_queue_time_total(death_data.queue_duration_sum); 98 tracked_object->set_queue_time_total(death_data.queue_duration_sum);
104 tracked_object->set_queue_time_sampled(death_data.queue_duration_sample); 99 tracked_object->set_queue_time_sampled(death_data.queue_duration_sample);
105 tracked_object->set_process_type(AsProtobufProcessType(process_type)); 100 tracked_object->set_process_type(AsProtobufProcessType(process_type));
106 tracked_object->set_process_id(profiler_data.process_id); 101 tracked_object->set_process_id(process_id);
107 } 102 }
108 } 103 }
109 104
110 // Returns true if the user is assigned to the experiment group for enabled 105 // Returns true if the user is assigned to the experiment group for enabled
111 // cellular uploads. 106 // cellular uploads.
112 bool IsCellularEnabledByExperiment() { 107 bool IsCellularEnabledByExperiment() {
113 const std::string group_name = 108 const std::string group_name =
114 base::FieldTrialList::FindFullName("UMA_EnableCellularLogUpload"); 109 base::FieldTrialList::FindFullName("UMA_EnableCellularLogUpload");
115 return group_name == "Enabled"; 110 return group_name == "Enabled";
116 } 111 }
117 112
118 } // namespace 113 } // namespace
119 114
120 ProfilerMetricsProvider::ProfilerMetricsProvider() : has_profiler_data_(false) { 115 ProfilerMetricsProvider::ProfilerMetricsProvider() {
121 } 116 }
122 117
123 ProfilerMetricsProvider::ProfilerMetricsProvider( 118 ProfilerMetricsProvider::ProfilerMetricsProvider(
124 const base::Callback<void(bool*)>& cellular_callback) 119 const base::Callback<void(bool*)>& cellular_callback)
125 : has_profiler_data_(false), cellular_callback_(cellular_callback) { 120 : cellular_callback_(cellular_callback) {
126 } 121 }
127 122
128 ProfilerMetricsProvider::~ProfilerMetricsProvider() { 123 ProfilerMetricsProvider::~ProfilerMetricsProvider() {
129 } 124 }
130 125
131 void ProfilerMetricsProvider::ProvideGeneralMetrics( 126 void ProfilerMetricsProvider::ProvideGeneralMetrics(
132 ChromeUserMetricsExtension* uma_proto) { 127 ChromeUserMetricsExtension* uma_proto) {
133 if (!has_profiler_data_)
134 return;
135
136 DCHECK_EQ(tracked_objects::TIME_SOURCE_TYPE_WALL_TIME, 128 DCHECK_EQ(tracked_objects::TIME_SOURCE_TYPE_WALL_TIME,
137 tracked_objects::GetTimeSourceType()); 129 tracked_objects::GetTimeSourceType());
138 130
139 DCHECK_EQ(0, uma_proto->profiler_event_size()); 131 DCHECK_EQ(0, uma_proto->profiler_event_size());
140 ProfilerEventProto* profile = uma_proto->add_profiler_event(); 132
141 profile->Swap(&profiler_event_cache_); 133 for (auto& event : profiler_events_cache_) {
142 has_profiler_data_ = false; 134 uma_proto->add_profiler_event()->Swap(&event.second);
135 }
136
137 profiler_events_cache_.clear();
143 } 138 }
144 139
145 void ProfilerMetricsProvider::RecordProfilerData( 140 void ProfilerMetricsProvider::RecordProfilerData(
146 const tracked_objects::ProcessDataSnapshot& process_data, 141 const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
147 int process_type) { 142 base::ProcessId process_id,
143 content::ProcessType process_type,
144 int profiling_phase,
145 base::TimeDelta phase_start,
146 base::TimeDelta phase_finish,
147 const ProfilerEvents& past_events) {
148 if (IsCellularConnection() && IsCellularEnabledByExperiment()) 148 if (IsCellularConnection() && IsCellularEnabledByExperiment())
149 return; 149 return;
150 if (tracked_objects::GetTimeSourceType() != 150 if (tracked_objects::GetTimeSourceType() !=
151 tracked_objects::TIME_SOURCE_TYPE_WALL_TIME) { 151 tracked_objects::TIME_SOURCE_TYPE_WALL_TIME) {
152 // We currently only support the default time source, wall clock time. 152 // We currently only support the default time source, wall clock time.
153 return; 153 return;
154 } 154 }
155 155
156 has_profiler_data_ = true; 156 const bool new_phase = !ContainsKey(profiler_events_cache_, profiling_phase);
157 profiler_event_cache_.set_profile_version( 157 ProfilerEventProto* profiler_event = &profiler_events_cache_[profiling_phase];
158 ProfilerEventProto::VERSION_STARTUP_PROFILE); 158
159 profiler_event_cache_.set_time_source(ProfilerEventProto::WALL_CLOCK_TIME); 159 if (new_phase) {
160 WriteProfilerData(process_data, process_type, &profiler_event_cache_); 160 profiler_event->set_profile_version(
161 ProfilerEventProto::VERSION_SPLIT_PROFILE);
162 profiler_event->set_time_source(ProfilerEventProto::WALL_CLOCK_TIME);
163 profiler_event->set_profiling_start_ms(phase_start.InMilliseconds());
164 profiler_event->set_profiling_finish_ms(phase_finish.InMilliseconds());
165 for (const auto& event : past_events) {
166 profiler_event->add_past_session_event(event);
167 }
168 }
169
170 WriteProfilerData(process_data_phase, process_id, process_type,
171 profiler_event);
161 } 172 }
162 173
163 bool ProfilerMetricsProvider::IsCellularConnection() { 174 bool ProfilerMetricsProvider::IsCellularConnection() {
164 bool is_cellular = false; 175 bool is_cellular = false;
165 // For android get current connection type from NetworkMetricsProvider if the 176 // For android get current connection type from NetworkMetricsProvider if the
166 // callback exists. 177 // callback exists.
167 #if defined(OS_ANDROID) 178 #if defined(OS_ANDROID)
168 if (!cellular_callback_.is_null()) 179 if (!cellular_callback_.is_null())
169 cellular_callback_.Run(&is_cellular); 180 cellular_callback_.Run(&is_cellular);
170 #endif 181 #endif
171 return is_cellular; 182 return is_cellular;
172 } 183 }
173 184
174 } // namespace metrics 185 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698