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

Unified Diff: content/browser/tracing/tracing_controller_impl.cc

Issue 66893003: Allow TracingController to output trace data to specified file (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed unnecessary include 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | content/public/browser/tracing_controller.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/tracing/tracing_controller_impl.cc
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index d2e8a31854617e550deb33c5c749404cc6a951a8..6eea271f6df2b3a4476d9a95ba33fa537823c73a 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -28,15 +28,94 @@ TracingController* TracingController::GetInstance() {
return TracingControllerImpl::GetInstance();
}
+class TracingControllerImpl::ResultFile {
+ public:
+ explicit ResultFile(const base::FilePath& path);
+ void Write(const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::WriteTask,
+ base::Unretained(this), events_str_ptr));
+ }
+ void Close(const base::Closure& callback) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::CloseTask,
+ base::Unretained(this), callback));
+ }
+ const base::FilePath& path() const { return path_; }
+
+ private:
+ void OpenTask();
+ void WriteTask(const scoped_refptr<base::RefCountedString>& events_str_ptr);
+ void CloseTask(const base::Closure& callback);
+
+ FILE* file_;
+ base::FilePath path_;
+ bool has_at_least_one_result_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResultFile);
+};
+
+TracingControllerImpl::ResultFile::ResultFile(const base::FilePath& path)
+ : file_(NULL),
+ path_(path),
+ has_at_least_one_result_(false) {
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&TracingControllerImpl::ResultFile::OpenTask,
+ base::Unretained(this)));
+}
+
+void TracingControllerImpl::ResultFile::OpenTask() {
+ if (path_.empty())
+ file_util::CreateTemporaryFile(&path_);
+ file_ = file_util::OpenFile(path_, "w");
+ if (!file_) {
+ LOG(ERROR) << "Failed to open " << path_.value();
+ return;
+ }
+ const char* preamble = "{\"traceEvents\": [";
+ size_t written = fwrite(preamble, strlen(preamble), 1, file_);
+ DCHECK(written == 1);
+}
+
+void TracingControllerImpl::ResultFile::WriteTask(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ if (!file_)
+ return;
+
+ // If there is already a result in the file, then put a commma
+ // before the next batch of results.
+ if (has_at_least_one_result_)
+ fwrite(",", 1, 1, file_);
+ has_at_least_one_result_ = true;
+ size_t written = fwrite(events_str_ptr->data().c_str(),
+ events_str_ptr->data().size(), 1,
+ file_);
+ DCHECK(written == 1);
+}
+
+void TracingControllerImpl::ResultFile::CloseTask(
+ const base::Closure& callback) {
+ if (!file_)
+ return;
+
+ const char* trailout = "]}";
+ size_t written = fwrite(trailout, strlen(trailout), 1, file_);
+ DCHECK(written == 1);
+ file_util::CloseFile(file_);
+ file_ = NULL;
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+}
+
+
TracingControllerImpl::TracingControllerImpl() :
pending_disable_recording_ack_count_(0),
pending_capture_monitoring_snapshot_ack_count_(0),
is_recording_(false),
is_monitoring_(false),
+ trace_options_(TraceLog::RECORD_UNTIL_FULL),
category_filter_(
- base::debug::CategoryFilter::kDefaultCategoryFilterString),
- result_file_(0),
- result_file_has_at_least_one_result_(false) {
+ base::debug::CategoryFilter::kDefaultCategoryFilterString) {
}
TracingControllerImpl::~TracingControllerImpl() {
@@ -59,7 +138,7 @@ void TracingControllerImpl::GetCategories(
EnableRecording(base::debug::CategoryFilter("*"),
TracingController::Options(),
EnableRecordingDoneCallback());
- DisableRecording(TracingFileResultCallback());
+ DisableRecording(base::FilePath(), TracingFileResultCallback());
}
bool TracingControllerImpl::EnableRecording(
@@ -94,6 +173,7 @@ bool TracingControllerImpl::EnableRecording(
}
bool TracingControllerImpl::DisableRecording(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -111,17 +191,8 @@ bool TracingControllerImpl::DisableRecording(
TraceLog::GetInstance()->AddClockSyncMetadataEvent();
#endif
- // We don't need to create a temporary file when getting categories.
- if (pending_get_categories_done_callback_.is_null()) {
- base::FilePath temporary_file;
- file_util::CreateTemporaryFile(&temporary_file);
- result_file_path_.reset(new base::FilePath(temporary_file));
- result_file_ = file_util::OpenFile(*result_file_path_, "w");
- result_file_has_at_least_one_result_ = false;
- const char* preamble = "{\"traceEvents\": [";
- size_t written = fwrite(preamble, strlen(preamble), 1, result_file_);
- DCHECK(written == 1);
- }
+ if (!callback.is_null() || !result_file_path.empty())
+ result_file_.reset(new ResultFile(result_file_path));
// There could be a case where there are no child processes and filters_
// is empty. In that case we can immediately tell the subscriber that tracing
@@ -203,6 +274,7 @@ void TracingControllerImpl::GetMonitoringStatus(
}
void TracingControllerImpl::CaptureMonitoringSnapshot(
+ const base::FilePath& result_file_path,
const TracingFileResultCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -211,14 +283,8 @@ void TracingControllerImpl::CaptureMonitoringSnapshot(
pending_capture_monitoring_snapshot_done_callback_ = callback;
- base::FilePath temporary_file;
- file_util::CreateTemporaryFile(&temporary_file);
- result_file_path_.reset(new base::FilePath(temporary_file));
- result_file_ = file_util::OpenFile(*result_file_path_, "w");
- result_file_has_at_least_one_result_ = false;
- const char* preamble = "{\"traceEvents\": [";
- size_t written = fwrite(preamble, strlen(preamble), 1, result_file_);
- DCHECK(written == 1);
+ if (!callback.is_null() || !result_file_path.empty())
+ monitoring_snapshot_file_.reset(new ResultFile(result_file_path));
// There could be a case where there are no child processes and filters_
// is empty. In that case we can immediately tell the subscriber that tracing
@@ -308,15 +374,24 @@ void TracingControllerImpl::OnDisableRecordingAcked(
if (!pending_get_categories_done_callback_.is_null()) {
pending_get_categories_done_callback_.Run(known_category_groups_);
pending_get_categories_done_callback_.Reset();
- } else if (!pending_disable_recording_done_callback_.is_null()) {
- const char* trailout = "]}";
- size_t written = fwrite(trailout, strlen(trailout), 1, result_file_);
- DCHECK(written == 1);
- file_util::CloseFile(result_file_);
- result_file_ = 0;
- pending_disable_recording_done_callback_.Run(result_file_path_.Pass());
+ } else if (result_file_) {
+ result_file_->Close(
+ base::Bind(&TracingControllerImpl::OnResultFileClosed,
+ base::Unretained(this)));
+ }
+}
+
+void TracingControllerImpl::OnResultFileClosed() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!result_file_)
+ return;
+
+ if (!pending_disable_recording_done_callback_.is_null()) {
+ pending_disable_recording_done_callback_.Run(result_file_->path());
pending_disable_recording_done_callback_.Reset();
}
+ result_file_.reset();
}
void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
@@ -342,16 +417,25 @@ void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked() {
if (pending_capture_monitoring_snapshot_ack_count_ != 0)
return;
+ if (monitoring_snapshot_file_) {
+ monitoring_snapshot_file_->Close(
+ base::Bind(&TracingControllerImpl::OnMonitoringSnapshotFileClosed,
+ base::Unretained(this)));
+ }
+}
+
+void TracingControllerImpl::OnMonitoringSnapshotFileClosed() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!monitoring_snapshot_file_)
+ return;
+
if (!pending_capture_monitoring_snapshot_done_callback_.is_null()) {
- const char* trailout = "]}";
- size_t written = fwrite(trailout, strlen(trailout), 1, result_file_);
- DCHECK(written == 1);
- file_util::CloseFile(result_file_);
- result_file_ = 0;
pending_capture_monitoring_snapshot_done_callback_.Run(
- result_file_path_.Pass());
+ monitoring_snapshot_file_->path());
pending_capture_monitoring_snapshot_done_callback_.Reset();
}
+ monitoring_snapshot_file_.reset();
}
void TracingControllerImpl::OnTraceDataCollected(
@@ -365,22 +449,21 @@ void TracingControllerImpl::OnTraceDataCollected(
return;
}
- // Drop trace events if we are just getting categories.
- if (!pending_get_categories_done_callback_.is_null())
- return;
+ if (result_file_)
+ result_file_->Write(events_str_ptr);
+}
- // If there is already a result in the file, then put a commma
- // before the next batch of results.
- if (result_file_has_at_least_one_result_) {
- size_t written = fwrite(",", 1, 1, result_file_);
- DCHECK(written == 1);
- } else {
- result_file_has_at_least_one_result_ = true;
+void TracingControllerImpl::OnMonitoringTraceDataCollected(
+ const scoped_refptr<base::RefCountedString>& events_str_ptr) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TracingControllerImpl::OnMonitoringTraceDataCollected,
+ base::Unretained(this), events_str_ptr));
+ return;
}
- size_t written = fwrite(events_str_ptr->data().c_str(),
- events_str_ptr->data().size(), 1,
- result_file_);
- DCHECK(written == 1);
+
+ if (!monitoring_snapshot_file_)
+ monitoring_snapshot_file_->Write(events_str_ptr);
}
void TracingControllerImpl::OnLocalTraceDataCollected(
@@ -402,7 +485,7 @@ void TracingControllerImpl::OnLocalMonitoringTraceDataCollected(
const scoped_refptr<base::RefCountedString>& events_str_ptr,
bool has_more_events) {
if (events_str_ptr->data().size())
- OnTraceDataCollected(events_str_ptr);
+ OnMonitoringTraceDataCollected(events_str_ptr);
if (has_more_events)
return;
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | content/public/browser/tracing_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698