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

Side by Side Diff: content/browser/tracing/trace_controller_impl.cc

Issue 65343006: Use TracingController for startup tracing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 #include "content/browser/tracing/trace_controller_impl.h" 5 #include "content/browser/tracing/trace_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "components/tracing/tracing_messages.h" 11 #include "components/tracing/tracing_messages.h"
12 #include "content/browser/tracing/trace_message_filter.h" 12 #include "content/browser/tracing/trace_message_filter.h"
13 #include "content/browser/tracing/trace_subscriber_stdio.h" 13 #include "content/browser/tracing/trace_subscriber_stdio.h"
14 #include "content/common/child_process_messages.h" 14 #include "content/common/child_process_messages.h"
15 #include "content/public/browser/browser_message_filter.h" 15 #include "content/public/browser/browser_message_filter.h"
16 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
17 17
18 using base::debug::TraceLog; 18 using base::debug::TraceLog;
19 19
20 namespace content { 20 namespace content {
21 21
22 namespace { 22 namespace {
23 23
24 base::LazyInstance<TraceControllerImpl>::Leaky g_controller = 24 base::LazyInstance<TraceControllerImpl>::Leaky g_controller =
25 LAZY_INSTANCE_INITIALIZER; 25 LAZY_INSTANCE_INITIALIZER;
26 26
27 class AutoStopTraceSubscriberStdio : public TraceSubscriberStdio {
28 public:
29 AutoStopTraceSubscriberStdio(const base::FilePath& file_path)
30 : TraceSubscriberStdio(file_path,
31 FILE_TYPE_PROPERTY_LIST,
32 false) {}
33
34 static void EndStartupTrace(AutoStopTraceSubscriberStdio* subscriber) {
35 if (!TraceControllerImpl::GetInstance()->EndTracingAsync(subscriber))
36 delete subscriber;
37 // else, the tracing will end asynchronously in OnEndTracingComplete().
38 }
39
40 virtual void OnEndTracingComplete() OVERRIDE {
41 TraceSubscriberStdio::OnEndTracingComplete();
42 delete this;
43 // TODO(joth): this would be the time to automatically open up
44 // chrome://tracing/ and load up the trace data collected.
45 }
46 };
47
48 } // namespace 27 } // namespace
49 28
50 TraceController* TraceController::GetInstance() { 29 TraceController* TraceController::GetInstance() {
51 return TraceControllerImpl::GetInstance(); 30 return TraceControllerImpl::GetInstance();
52 } 31 }
53 32
54 TraceControllerImpl::TraceControllerImpl() : 33 TraceControllerImpl::TraceControllerImpl() :
55 subscriber_(NULL), 34 subscriber_(NULL),
56 pending_end_ack_count_(0), 35 pending_end_ack_count_(0),
57 pending_bpf_ack_count_(0), 36 pending_bpf_ack_count_(0),
58 maximum_bpf_(0.0f), 37 maximum_bpf_(0.0f),
59 is_tracing_(false), 38 is_tracing_(false),
60 is_tracing_startup_(false),
61 is_get_category_groups_(false), 39 is_get_category_groups_(false),
62 category_filter_( 40 category_filter_(
63 base::debug::CategoryFilter::kDefaultCategoryFilterString) { 41 base::debug::CategoryFilter::kDefaultCategoryFilterString) {
64 TraceLog::GetInstance()->SetNotificationCallback( 42 TraceLog::GetInstance()->SetNotificationCallback(
65 base::Bind(&TraceControllerImpl::OnTraceNotification, 43 base::Bind(&TraceControllerImpl::OnTraceNotification,
66 base::Unretained(this))); 44 base::Unretained(this)));
67 } 45 }
68 46
69 TraceControllerImpl::~TraceControllerImpl() { 47 TraceControllerImpl::~TraceControllerImpl() {
70 // No need to SetNotificationCallback(nil) on the TraceLog since this is a 48 // No need to SetNotificationCallback(nil) on the TraceLog since this is a
71 // Leaky instance. 49 // Leaky instance.
72 NOTREACHED(); 50 NOTREACHED();
73 } 51 }
74 52
75 TraceControllerImpl* TraceControllerImpl::GetInstance() { 53 TraceControllerImpl* TraceControllerImpl::GetInstance() {
76 return g_controller.Pointer(); 54 return g_controller.Pointer();
77 } 55 }
78 56
79 void TraceControllerImpl::InitStartupTracing(const CommandLine& command_line) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81 base::FilePath trace_file = command_line.GetSwitchValuePath(
82 switches::kTraceStartupFile);
83 // trace_file = "none" means that startup events will show up for the next
84 // begin/end tracing (via about:tracing or AutomationProxy::BeginTracing/
85 // EndTracing, for example).
86 if (trace_file == base::FilePath().AppendASCII("none"))
87 return;
88
89 if (trace_file.empty()) {
90 // Default to saving the startup trace into the current dir.
91 trace_file = base::FilePath().AppendASCII("chrometrace.log");
92 }
93 scoped_ptr<AutoStopTraceSubscriberStdio> subscriber(
94 new AutoStopTraceSubscriberStdio(trace_file));
95 DCHECK(can_begin_tracing(subscriber.get()));
96
97 std::string delay_str = command_line.GetSwitchValueASCII(
98 switches::kTraceStartupDuration);
99 int delay_secs = 5;
100 if (!delay_str.empty() && !base::StringToInt(delay_str, &delay_secs)) {
101 DLOG(WARNING) << "Could not parse --" << switches::kTraceStartupDuration
102 << "=" << delay_str << " defaulting to 5 (secs)";
103 delay_secs = 5;
104 }
105
106 is_tracing_startup_ = true;
107 OnTracingBegan(subscriber.get());
108 BrowserThread::PostDelayedTask(
109 BrowserThread::UI,
110 FROM_HERE,
111 base::Bind(&AutoStopTraceSubscriberStdio::EndStartupTrace,
112 base::Unretained(subscriber.release())),
113 base::TimeDelta::FromSeconds(delay_secs));
114 }
115
116 bool TraceControllerImpl::GetKnownCategoryGroupsAsync( 57 bool TraceControllerImpl::GetKnownCategoryGroupsAsync(
117 TraceSubscriber* subscriber) { 58 TraceSubscriber* subscriber) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 60
120 // Known categories come back from child processes with the EndTracingAck 61 // Known categories come back from child processes with the EndTracingAck
121 // message. So to get known categories, just begin and end tracing immediately 62 // message. So to get known categories, just begin and end tracing immediately
122 // afterwards. This will ping all the child processes for categories. 63 // afterwards. This will ping all the child processes for categories.
123 is_get_category_groups_ = true; 64 is_get_category_groups_ = true;
124 bool success = BeginTracing(subscriber, "*", 65 bool success = BeginTracing(subscriber, "*",
125 TraceLog::GetInstance()->trace_options()) && 66 TraceLog::GetInstance()->trace_options()) &&
(...skipping 26 matching lines...) Expand all
152 93
153 bool TraceControllerImpl::EndTracingAsync(TraceSubscriber* subscriber) { 94 bool TraceControllerImpl::EndTracingAsync(TraceSubscriber* subscriber) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 96
156 if (!can_end_tracing() || subscriber != subscriber_) 97 if (!can_end_tracing() || subscriber != subscriber_)
157 return false; 98 return false;
158 99
159 // Disable local trace early to avoid traces during end-tracing process from 100 // Disable local trace early to avoid traces during end-tracing process from
160 // interfering with the process. 101 // interfering with the process.
161 TraceLog::GetInstance()->SetDisabled(); 102 TraceLog::GetInstance()->SetDisabled();
162 is_tracing_startup_ = false;
163 103
164 #if defined(OS_ANDROID) 104 #if defined(OS_ANDROID)
165 if (!is_get_category_groups_) 105 if (!is_get_category_groups_)
166 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 106 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
167 #endif 107 #endif
168 108
169 // There could be a case where there are no child processes and filters_ 109 // There could be a case where there are no child processes and filters_
170 // is empty. In that case we can immediately tell the subscriber that tracing 110 // is empty. In that case we can immediately tell the subscriber that tracing
171 // has ended. To avoid recursive calls back to the subscriber, we will just 111 // has ended. To avoid recursive calls back to the subscriber, we will just
172 // use the existing asynchronous OnEndTracingAck code. 112 // use the existing asynchronous OnEndTracingAck code.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 205 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
266 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 206 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
267 base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this), 207 base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this),
268 make_scoped_refptr(filter))); 208 make_scoped_refptr(filter)));
269 return; 209 return;
270 } 210 }
271 211
272 filters_.insert(filter); 212 filters_.insert(filter);
273 if (is_tracing_enabled()) { 213 if (is_tracing_enabled()) {
274 std::string cf_str = category_filter_.ToString(); 214 std::string cf_str = category_filter_.ToString();
275 filter->SendBeginTracing(cf_str, trace_options_, is_tracing_startup_); 215 filter->SendBeginTracing(cf_str, trace_options_);
276 if (!watch_category_.empty()) 216 if (!watch_category_.empty())
277 filter->SendSetWatchEvent(watch_category_, watch_name_); 217 filter->SendSetWatchEvent(watch_category_, watch_name_);
278 } 218 }
279 } 219 }
280 220
281 void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) { 221 void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
282 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 222 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
283 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 223 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
284 base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this), 224 base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this),
285 make_scoped_refptr(filter))); 225 make_scoped_refptr(filter)));
286 return; 226 return;
287 } 227 }
288 228
289 filters_.erase(filter); 229 filters_.erase(filter);
290 } 230 }
291 231
292 void TraceControllerImpl::OnTracingBegan(TraceSubscriber* subscriber) { 232 void TraceControllerImpl::OnTracingBegan(TraceSubscriber* subscriber) {
293 is_tracing_ = true; 233 is_tracing_ = true;
294 234
295 subscriber_ = subscriber; 235 subscriber_ = subscriber;
296 236
297 category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter(); 237 category_filter_ = TraceLog::GetInstance()->GetCurrentCategoryFilter();
298 trace_options_ = TraceLog::GetInstance()->trace_options(); 238 trace_options_ = TraceLog::GetInstance()->trace_options();
299 239
300 // Notify all child processes. 240 // Notify all child processes.
301 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { 241 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
302 it->get()->SendBeginTracing(category_filter_.ToString(), trace_options_, 242 it->get()->SendBeginTracing(category_filter_.ToString(), trace_options_);
303 is_tracing_startup_);
304 } 243 }
305 } 244 }
306 245
307 void TraceControllerImpl::OnEndTracingAck( 246 void TraceControllerImpl::OnEndTracingAck(
308 const std::vector<std::string>& known_category_groups) { 247 const std::vector<std::string>& known_category_groups) {
309 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 248 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
310 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 249 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
311 base::Bind(&TraceControllerImpl::OnEndTracingAck, 250 base::Bind(&TraceControllerImpl::OnEndTracingAck,
312 base::Unretained(this), known_category_groups)); 251 base::Unretained(this), known_category_groups));
313 return; 252 return;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // The last ack represents local trace, so we need to ack it now. Note that 362 // The last ack represents local trace, so we need to ack it now. Note that
424 // this code only executes if there were child processes. 363 // this code only executes if there were child processes.
425 float bpf = TraceLog::GetInstance()->GetBufferPercentFull(); 364 float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
426 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 365 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
427 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply, 366 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
428 base::Unretained(this), bpf)); 367 base::Unretained(this), bpf));
429 } 368 }
430 } 369 }
431 370
432 } // namespace content 371 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/trace_controller_impl.h ('k') | content/browser/tracing/trace_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698