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

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

Issue 136403007: Implement system tracing for cros (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix json framing Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/tracing_controller_impl.h" 5 #include "content/browser/tracing/tracing_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/json/string_escape.h" 10 #include "base/json/string_escape.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "content/browser/tracing/trace_message_filter.h" 12 #include "content/browser/tracing/trace_message_filter.h"
13 #include "content/browser/tracing/tracing_ui.h" 13 #include "content/browser/tracing/tracing_ui.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 #if defined(OS_CHROMEOS)
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/debug_daemon_client.h"
21 #endif
22
18 using base::debug::TraceLog; 23 using base::debug::TraceLog;
19 24
20 namespace content { 25 namespace content {
21 26
22 namespace { 27 namespace {
23 28
24 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = 29 base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
25 LAZY_INSTANCE_INITIALIZER; 30 LAZY_INSTANCE_INITIALIZER;
26 31
27 } // namespace 32 } // namespace
28 33
29 TracingController* TracingController::GetInstance() { 34 TracingController* TracingController::GetInstance() {
30 return TracingControllerImpl::GetInstance(); 35 return TracingControllerImpl::GetInstance();
31 } 36 }
32 37
33 class TracingControllerImpl::ResultFile { 38 class TracingControllerImpl::ResultFile {
34 public: 39 public:
35 explicit ResultFile(const base::FilePath& path); 40 explicit ResultFile(const base::FilePath& path);
36 void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) { 41 void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) {
37 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 42 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
38 base::Bind(&TracingControllerImpl::ResultFile::WriteTask, 43 base::Bind(&TracingControllerImpl::ResultFile::WriteTask,
39 base::Unretained(this), events_str_ptr)); 44 base::Unretained(this), events_str_ptr));
40 } 45 }
41 void Close(const base::Closure& callback) { 46 void Close(const base::Closure& callback) {
42 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 47 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
43 base::Bind(&TracingControllerImpl::ResultFile::CloseTask, 48 base::Bind(&TracingControllerImpl::ResultFile::CloseTask,
44 base::Unretained(this), callback)); 49 base::Unretained(this), callback));
45 } 50 }
51 void WriteSystemTrace(
52 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
53 BrowserThread::PostTask(
54 BrowserThread::FILE,
55 FROM_HERE,
56 base::Bind(&TracingControllerImpl::ResultFile::WriteSystemTraceTask,
57 base::Unretained(this), events_str_ptr));
58 }
59
46 const base::FilePath& path() const { return path_; } 60 const base::FilePath& path() const { return path_; }
47 61
48 private: 62 private:
49 void OpenTask(); 63 void OpenTask();
50 void WriteTask(const scoped_refptr<base::RefCountedString>& events_str_ptr); 64 void WriteTask(const scoped_refptr<base::RefCountedString>& events_str_ptr);
65 void WriteSystemTraceTask(
66 const scoped_refptr<base::RefCountedString>& events_str_ptr);
51 void CloseTask(const base::Closure& callback); 67 void CloseTask(const base::Closure& callback);
52 68
53 FILE* file_; 69 FILE* file_;
54 base::FilePath path_; 70 base::FilePath path_;
55 bool has_at_least_one_result_; 71 bool has_at_least_one_result_;
72 scoped_refptr<base::RefCountedString> system_trace_;
56 73
57 DISALLOW_COPY_AND_ASSIGN(ResultFile); 74 DISALLOW_COPY_AND_ASSIGN(ResultFile);
58 }; 75 };
59 76
60 TracingControllerImpl::ResultFile::ResultFile(const base::FilePath& path) 77 TracingControllerImpl::ResultFile::ResultFile(const base::FilePath& path)
61 : file_(NULL), 78 : file_(NULL),
62 path_(path), 79 path_(path),
63 has_at_least_one_result_(false) { 80 has_at_least_one_result_(false) {
64 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 81 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
65 base::Bind(&TracingControllerImpl::ResultFile::OpenTask, 82 base::Bind(&TracingControllerImpl::ResultFile::OpenTask,
(...skipping 24 matching lines...) Expand all
90 size_t written = fwrite(",", 1, 1, file_); 107 size_t written = fwrite(",", 1, 1, file_);
91 DCHECK(written == 1); 108 DCHECK(written == 1);
92 } 109 }
93 has_at_least_one_result_ = true; 110 has_at_least_one_result_ = true;
94 size_t written = fwrite(events_str_ptr->data().c_str(), 111 size_t written = fwrite(events_str_ptr->data().c_str(),
95 events_str_ptr->data().size(), 1, 112 events_str_ptr->data().size(), 1,
96 file_); 113 file_);
97 DCHECK(written == 1); 114 DCHECK(written == 1);
98 } 115 }
99 116
117 void TracingControllerImpl::ResultFile::WriteSystemTraceTask(
118 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
119 system_trace_ = events_str_ptr;
120 }
121
100 void TracingControllerImpl::ResultFile::CloseTask( 122 void TracingControllerImpl::ResultFile::CloseTask(
101 const base::Closure& callback) { 123 const base::Closure& callback) {
102 if (!file_) 124 if (!file_)
103 return; 125 return;
104 126
105 const char* trailout = "]}"; 127 const char* trailevents = "]";
106 size_t written = fwrite(trailout, strlen(trailout), 1, file_); 128 size_t written = fwrite(trailevents, strlen(trailevents), 1, file_);
129 DCHECK(written == 1);
130
131 if (system_trace_) {
132 std::string json_string = base::GetQuotedJSONString(system_trace_->data());
133
134 const char* systemTraceHead = ", \"systemTraceEvents\": ";
135 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_);
136 DCHECK(written == 1);
137
138 written = fwrite(json_string.data(), json_string.size(), 1, file_);
139 DCHECK(written == 1);
140
141 system_trace_ = NULL;
142 }
143
144 const char* trailout = "}";
145 written = fwrite(trailout, strlen(trailout), 1, file_);
107 DCHECK(written == 1); 146 DCHECK(written == 1);
108 base::CloseFile(file_); 147 base::CloseFile(file_);
109 file_ = NULL; 148 file_ = NULL;
110 149
111 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); 150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
112 } 151 }
113 152
114 153
115 TracingControllerImpl::TracingControllerImpl() : 154 TracingControllerImpl::TracingControllerImpl() :
116 pending_disable_recording_ack_count_(0), 155 pending_disable_recording_ack_count_(0),
117 pending_capture_monitoring_snapshot_ack_count_(0), 156 pending_capture_monitoring_snapshot_ack_count_(0),
118 pending_trace_buffer_percent_full_ack_count_(0), 157 pending_trace_buffer_percent_full_ack_count_(0),
119 maximum_trace_buffer_percent_full_(0), 158 maximum_trace_buffer_percent_full_(0),
120 // Tracing may have been enabled by ContentMainRunner if kTraceStartup 159 // Tracing may have been enabled by ContentMainRunner if kTraceStartup
121 // is specified in command line. 160 // is specified in command line.
161 #if defined(OS_CHROMEOS)
162 is_system_tracing_(false),
163 #endif
122 is_recording_(TraceLog::GetInstance()->IsEnabled()), 164 is_recording_(TraceLog::GetInstance()->IsEnabled()),
123 is_monitoring_(false) { 165 is_monitoring_(false) {
124 } 166 }
125 167
126 TracingControllerImpl::~TracingControllerImpl() { 168 TracingControllerImpl::~TracingControllerImpl() {
127 // This is a Leaky instance. 169 // This is a Leaky instance.
128 NOTREACHED(); 170 NOTREACHED();
129 } 171 }
130 172
131 TracingControllerImpl* TracingControllerImpl::GetInstance() { 173 TracingControllerImpl* TracingControllerImpl::GetInstance() {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 if (pending_get_categories_done_callback_.is_null()) 229 if (pending_get_categories_done_callback_.is_null())
188 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 230 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
189 #endif 231 #endif
190 232
191 options_ = options; 233 options_ = options;
192 int trace_options = (options & RECORD_CONTINUOUSLY) ? 234 int trace_options = (options & RECORD_CONTINUOUSLY) ?
193 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; 235 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL;
194 if (options & ENABLE_SAMPLING) { 236 if (options & ENABLE_SAMPLING) {
195 trace_options |= TraceLog::ENABLE_SAMPLING; 237 trace_options |= TraceLog::ENABLE_SAMPLING;
196 } 238 }
197 // TODO(haraken): How to handle ENABLE_SYSTRACE? 239 #if defined(OS_CHROMEOS)
240 if (options & ENABLE_SYSTRACE) {
241 DCHECK(!is_system_tracing_);
242 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
243 StartSystemTracing();
244 is_system_tracing_ = true;
245 }
246 #endif
198 247
199 base::Closure on_enable_recording_done_callback = 248 base::Closure on_enable_recording_done_callback =
200 base::Bind(&TracingControllerImpl::OnEnableRecordingDone, 249 base::Bind(&TracingControllerImpl::OnEnableRecordingDone,
201 base::Unretained(this), 250 base::Unretained(this),
202 category_filter,trace_options, callback); 251 category_filter,trace_options, callback);
203 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 252 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
204 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, 253 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
205 base::Unretained(this), 254 base::Unretained(this),
206 category_filter, 255 category_filter,
207 base::debug::TraceLog::RECORDING_MODE, 256 base::debug::TraceLog::RECORDING_MODE,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 // called with the last of the local trace data. 651 // called with the last of the local trace data.
603 TraceLog::GetInstance()->Flush( 652 TraceLog::GetInstance()->Flush(
604 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected, 653 base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
605 base::Unretained(this))); 654 base::Unretained(this)));
606 return; 655 return;
607 } 656 }
608 657
609 if (pending_disable_recording_ack_count_ != 0) 658 if (pending_disable_recording_ack_count_ != 0)
610 return; 659 return;
611 660
661 OnDisableRecordingComplete();
662 }
663
664 void TracingControllerImpl::OnDisableRecordingComplete() {
612 // All acks (including from the subprocesses and the local trace) have been 665 // All acks (including from the subprocesses and the local trace) have been
613 // received. 666 // received.
614 is_recording_ = false; 667 is_recording_ = false;
615 668
669 #if defined(OS_CHROMEOS)
670 if (is_system_tracing_) {
671 // Disable system tracing now that the local trace has shutdown.
672 // This must be done last because we potentially need to push event
673 // records into the system event log for synchronizing system event
674 // timestamps with chrome event timestamps--and since the system event
675 // log is a ring-buffer (on linux) adding them at the end is the only
676 // way we're confident we'll have them in the final result.
677 is_system_tracing_ = false;
678 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
679 RequestStopSystemTracing(
680 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
681 base::Unretained(this)));
682 return;
683 }
684 #endif
685
616 // Trigger callback if one is set. 686 // Trigger callback if one is set.
617 if (!pending_get_categories_done_callback_.is_null()) { 687 if (!pending_get_categories_done_callback_.is_null()) {
618 pending_get_categories_done_callback_.Run(known_category_groups_); 688 pending_get_categories_done_callback_.Run(known_category_groups_);
619 pending_get_categories_done_callback_.Reset(); 689 pending_get_categories_done_callback_.Reset();
620 } else if (result_file_) { 690 } else if (result_file_) {
621 result_file_->Close( 691 result_file_->Close(
622 base::Bind(&TracingControllerImpl::OnResultFileClosed, 692 base::Bind(&TracingControllerImpl::OnResultFileClosed,
623 base::Unretained(this))); 693 base::Unretained(this)));
624 } 694 }
625 } 695 }
626 696
627 void TracingControllerImpl::OnResultFileClosed() { 697 void TracingControllerImpl::OnResultFileClosed() {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
629 699
630 if (!result_file_) 700 if (!result_file_)
631 return; 701 return;
632 702
633 if (!pending_disable_recording_done_callback_.is_null()) { 703 if (!pending_disable_recording_done_callback_.is_null()) {
634 pending_disable_recording_done_callback_.Run(result_file_->path()); 704 pending_disable_recording_done_callback_.Run(result_file_->path());
635 pending_disable_recording_done_callback_.Reset(); 705 pending_disable_recording_done_callback_.Reset();
636 } 706 }
637 result_file_.reset(); 707 result_file_.reset();
638 } 708 }
639 709
710 #if defined(OS_CHROMEOS)
711 void TracingControllerImpl::OnEndSystemTracingAcked(
712 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
714
715 if (result_file_)
716 result_file_->WriteSystemTrace(events_str_ptr);
717
718 DCHECK(!is_system_tracing_);
719 OnDisableRecordingComplete();
720 }
721 #endif
722
640 void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked( 723 void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
641 TraceMessageFilter* trace_message_filter) { 724 TraceMessageFilter* trace_message_filter) {
642 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 725 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
643 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 726 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
644 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked, 727 base::Bind(&TracingControllerImpl::OnCaptureMonitoringSnapshotAcked,
645 base::Unretained(this), 728 base::Unretained(this),
646 make_scoped_refptr(trace_message_filter))); 729 make_scoped_refptr(trace_message_filter)));
647 return; 730 return;
648 } 731 }
649 732
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 is_monitoring_ = is_monitoring; 894 is_monitoring_ = is_monitoring;
812 #if !defined(OS_ANDROID) 895 #if !defined(OS_ANDROID)
813 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); 896 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin();
814 it != tracing_uis_.end(); it++) { 897 it != tracing_uis_.end(); it++) {
815 (*it)->OnMonitoringStateChanged(is_monitoring); 898 (*it)->OnMonitoringStateChanged(is_monitoring);
816 } 899 }
817 #endif 900 #endif
818 } 901 }
819 902
820 } // namespace content 903 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698