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

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

Issue 1002103004: NOT FOR REVIEW - Slow Reports Reference Implementation Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: JSON serialization. Created 5 years, 7 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
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include "content/browser/tracing/tracing_controller_impl.h" 4 #include "content/browser/tracing/tracing_controller_impl.h"
5 5
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/files/file_util.h" 7 #include "base/files/file_util.h"
8 #include "content/public/browser/browser_thread.h" 8 #include "content/public/browser/browser_thread.h"
9 #include "third_party/zlib/zlib.h" 9 #include "third_party/zlib/zlib.h"
10 10
11 namespace content { 11 namespace content {
12 12
13 namespace { 13 namespace {
14 14
15 class FileTraceDataSink : public TracingController::TraceDataSink { 15 class StringTraceDataEndpoint : public TracingController::TraceDataEndpoint {
16 public: 16 public:
17 explicit FileTraceDataSink(const base::FilePath& trace_file_path, 17 typedef base::Callback<void(base::RefCountedString*)> CompletionCallback;
18 const base::Closure& callback) 18
19 explicit StringTraceDataEndpoint(CompletionCallback callback)
20 : completion_callback_(callback) {}
21
22 void ReceiveTraceFinalContents(const std::string& contents) override {
23 std::string tmp = contents;
24 scoped_refptr<base::RefCountedString> str =
25 base::RefCountedString::TakeString(&tmp);
26
27 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
28 base::Bind(completion_callback_, str));
29 }
30
31 private:
32 ~StringTraceDataEndpoint() override {}
33
34 CompletionCallback completion_callback_;
35
36 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint);
37 };
38
39 class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
40 public:
41 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path,
42 const base::Closure& callback)
19 : file_path_(trace_file_path), 43 : file_path_(trace_file_path),
20 completion_callback_(callback), 44 completion_callback_(callback),
21 file_(NULL) {} 45 file_(NULL) {}
22 46
23 void AddTraceChunk(const std::string& chunk) override { 47 void ReceiveTraceChunk(const std::string& chunk) override {
24 std::string tmp = chunk; 48 std::string tmp = chunk;
25 scoped_refptr<base::RefCountedString> chunk_ptr = 49 scoped_refptr<base::RefCountedString> chunk_ptr =
26 base::RefCountedString::TakeString(&tmp); 50 base::RefCountedString::TakeString(&tmp);
27 BrowserThread::PostTask( 51 BrowserThread::PostTask(
28 BrowserThread::FILE, 52 BrowserThread::FILE, FROM_HERE,
29 FROM_HERE, 53 base::Bind(&FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread, this,
30 base::Bind( 54 chunk_ptr));
31 &FileTraceDataSink::AddTraceChunkOnFileThread, this, chunk_ptr));
32 } 55 }
33 void SetSystemTrace(const std::string& data) override { 56
34 system_trace_ = data; 57 void ReceiveTraceFinalContents(const std::string& contents) override {
35 }
36 void Close() override {
37 BrowserThread::PostTask( 58 BrowserThread::PostTask(
38 BrowserThread::FILE, 59 BrowserThread::FILE, FROM_HERE,
39 FROM_HERE, 60 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this));
40 base::Bind(&FileTraceDataSink::CloseOnFileThread, this));
41 } 61 }
42 62
43 private: 63 private:
44 ~FileTraceDataSink() override { DCHECK(file_ == NULL); } 64 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); }
45 65
46 void AddTraceChunkOnFileThread( 66 void ReceiveTraceChunkOnFileThread(
47 const scoped_refptr<base::RefCountedString> chunk) { 67 const scoped_refptr<base::RefCountedString> chunk) {
48 if (file_ != NULL) 68 if (!OpenFileIfNeededOnFileThread())
49 fputc(',', file_);
50 else if (!OpenFileIfNeededOnFileThread())
51 return; 69 return;
52 ignore_result(fwrite(chunk->data().c_str(), strlen(chunk->data().c_str()), 70 ignore_result(
53 1, file_)); 71 fwrite(chunk->data().c_str(), chunk->data().size(), 1, file_));
54 } 72 }
55 73
56 bool OpenFileIfNeededOnFileThread() { 74 bool OpenFileIfNeededOnFileThread() {
57 if (file_ != NULL) 75 if (file_ != NULL)
58 return true; 76 return true;
59 file_ = base::OpenFile(file_path_, "w"); 77 file_ = base::OpenFile(file_path_, "w");
60 if (file_ == NULL) { 78 if (file_ == NULL) {
61 LOG(ERROR) << "Failed to open " << file_path_.value(); 79 LOG(ERROR) << "Failed to open " << file_path_.value();
62 return false; 80 return false;
63 } 81 }
64 const char preamble[] = "{\"traceEvents\": [";
65 ignore_result(fwrite(preamble, strlen(preamble), 1, file_));
66 return true; 82 return true;
67 } 83 }
68 84
69 void CloseOnFileThread() { 85 void CloseOnFileThread() {
70 if (OpenFileIfNeededOnFileThread()) { 86 if (OpenFileIfNeededOnFileThread()) {
71 fputc(']', file_);
72 if (!system_trace_.empty()) {
73 const char systemTraceEvents[] = ",\"systemTraceEvents\": ";
74 ignore_result(fwrite(systemTraceEvents, strlen(systemTraceEvents),
75 1, file_));
76 ignore_result(fwrite(system_trace_.c_str(),
77 strlen(system_trace_.c_str()), 1, file_));
78 }
79 fputc('}', file_);
80 base::CloseFile(file_); 87 base::CloseFile(file_);
81 file_ = NULL; 88 file_ = NULL;
82 } 89 }
83 BrowserThread::PostTask( 90 BrowserThread::PostTask(
84 BrowserThread::UI, 91 BrowserThread::UI, FROM_HERE,
85 FROM_HERE, 92 base::Bind(&FileTraceDataEndpoint::FinalizeOnUIThread, this));
86 base::Bind(&FileTraceDataSink::FinalizeOnUIThread, this));
87 } 93 }
88 94
89 void FinalizeOnUIThread() { completion_callback_.Run(); } 95 void FinalizeOnUIThread() { completion_callback_.Run(); }
90 96
91 base::FilePath file_path_; 97 base::FilePath file_path_;
92 base::Closure completion_callback_; 98 base::Closure completion_callback_;
93 FILE* file_; 99 FILE* file_;
94 std::string system_trace_;
95 100
96 DISALLOW_COPY_AND_ASSIGN(FileTraceDataSink); 101 DISALLOW_COPY_AND_ASSIGN(FileTraceDataEndpoint);
97 }; 102 };
98 103
99 class StringTraceDataSink : public TracingController::TraceDataSink { 104 class StringTraceDataSink : public TracingController::TraceDataSink {
100 public: 105 public:
101 typedef base::Callback<void(base::RefCountedString*)> CompletionCallback; 106 explicit StringTraceDataSink(
107 scoped_refptr<TracingController::TraceDataEndpoint> endpoint)
108 : endpoint_(endpoint) {}
102 109
103 explicit StringTraceDataSink(CompletionCallback callback) 110 void AddTraceChunk(const std::string& chunk) override {
104 : completion_callback_(callback) {} 111 std::string trace_string;
112 if (trace_.empty())
113 trace_string = "{\"traceEvents\":[";
114 else
115 trace_string = ",";
116 trace_string += chunk;
105 117
106 // TracingController::TraceDataSink implementation 118 AddTraceChunkAndPassToEndpoint(trace_string);
107 void AddTraceChunk(const std::string& chunk) override { 119 }
108 if (!trace_.empty()) 120
109 trace_ += ","; 121 void AddTraceChunkAndPassToEndpoint(const std::string& chunk) {
110 trace_ += chunk; 122 trace_ += chunk;
123
124 endpoint_->ReceiveTraceChunk(chunk);
111 } 125 }
126
112 void SetSystemTrace(const std::string& data) override { 127 void SetSystemTrace(const std::string& data) override {
113 system_trace_ = data; 128 system_trace_ = data;
114 } 129 }
130
115 void Close() override { 131 void Close() override {
116 std::string result = "{\"traceEvents\":[" + trace_ + "]"; 132 AddTraceChunkAndPassToEndpoint("]");
117 if (!system_trace_.empty()) 133 if (!system_trace_.empty())
118 result += ",\"systemTraceEvents\": " + system_trace_; 134 AddTraceChunkAndPassToEndpoint(",\"systemTraceEvents\": " +
119 result += "}"; 135 system_trace_);
136 AddTraceChunkAndPassToEndpoint("}");
120 137
121 scoped_refptr<base::RefCountedString> str = 138 endpoint_->ReceiveTraceFinalContents(trace_);
122 base::RefCountedString::TakeString(&result);
123 completion_callback_.Run(str.get());
124 } 139 }
125 140
126 private: 141 private:
127 ~StringTraceDataSink() override {} 142 ~StringTraceDataSink() override {}
128 143
144 scoped_refptr<TracingController::TraceDataEndpoint> endpoint_;
129 std::string trace_; 145 std::string trace_;
130 std::string system_trace_; 146 std::string system_trace_;
131 CompletionCallback completion_callback_;
132 147
133 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink); 148 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink);
134 }; 149 };
135 150
136 class CompressedStringTraceDataSink : public TracingController::TraceDataSink { 151 class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
137 public: 152 public:
153 const int kChunkSize = 0x4000;
154
138 explicit CompressedStringTraceDataSink( 155 explicit CompressedStringTraceDataSink(
139 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) 156 scoped_refptr<TracingController::TraceDataEndpoint> endpoint)
140 : endpoint_(endpoint), already_tried_open_(false) {} 157 : endpoint_(endpoint), already_tried_open_(false) {}
141 158
142 void AddTraceChunk(const std::string& chunk) override { 159 void AddTraceChunk(const std::string& chunk) override {
143 std::string tmp = chunk; 160 std::string tmp = chunk;
144 scoped_refptr<base::RefCountedString> chunk_ptr = 161 scoped_refptr<base::RefCountedString> chunk_ptr =
145 base::RefCountedString::TakeString(&tmp); 162 base::RefCountedString::TakeString(&tmp);
146 BrowserThread::PostTask( 163 BrowserThread::PostTask(
147 BrowserThread::FILE, FROM_HERE, 164 BrowserThread::FILE, FROM_HERE,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 trace += chunk_ptr->data(); 213 trace += chunk_ptr->data();
197 AddTraceChunkAndCompressOnFileThread(trace, false); 214 AddTraceChunkAndCompressOnFileThread(trace, false);
198 } 215 }
199 216
200 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk, 217 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk,
201 bool finished) { 218 bool finished) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
203 if (!OpenZStreamOnFileThread()) 220 if (!OpenZStreamOnFileThread())
204 return; 221 return;
205 222
206 const int kChunkSize = 0x4000;
207
208 char buffer[kChunkSize]; 223 char buffer[kChunkSize];
209 int err; 224 int err;
210 stream_->avail_in = chunk.size(); 225 stream_->avail_in = chunk.size();
211 stream_->next_in = (unsigned char*)chunk.data(); 226 stream_->next_in = (unsigned char*)chunk.data();
212 do { 227 do {
213 stream_->avail_out = kChunkSize; 228 stream_->avail_out = kChunkSize;
214 stream_->next_out = (unsigned char*)buffer; 229 stream_->next_out = (unsigned char*)buffer;
215 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); 230 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH);
216 if (err != Z_OK && (err != Z_STREAM_END && finished)) { 231 if (err != Z_OK && (err != Z_STREAM_END && finished)) {
217 stream_.reset(); 232 stream_.reset();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 std::string system_trace_; 270 std::string system_trace_;
256 271
257 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink); 272 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink);
258 }; 273 };
259 274
260 } // namespace 275 } // namespace
261 276
262 scoped_refptr<TracingController::TraceDataSink> 277 scoped_refptr<TracingController::TraceDataSink>
263 TracingController::CreateStringSink( 278 TracingController::CreateStringSink(
264 const base::Callback<void(base::RefCountedString*)>& callback) { 279 const base::Callback<void(base::RefCountedString*)>& callback) {
265 return new StringTraceDataSink(callback); 280 return new StringTraceDataSink(new StringTraceDataEndpoint(callback));
266 } 281 }
267 282
268 scoped_refptr<TracingController::TraceDataSink> 283 scoped_refptr<TracingController::TraceDataSink>
269 TracingController::CreateCompressedStringSink( 284 TracingController::CreateCompressedStringSink(
270 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) { 285 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) {
271 return new CompressedStringTraceDataSink(endpoint); 286 return new CompressedStringTraceDataSink(endpoint);
272 } 287 }
273 288
274 scoped_refptr<TracingController::TraceDataSink> 289 scoped_refptr<TracingController::TraceDataSink>
275 TracingController::CreateFileSink(const base::FilePath& file_path, 290 TracingController::CreateFileSink(const base::FilePath& file_path,
276 const base::Closure& callback) { 291 const base::Closure& callback) {
277 return new FileTraceDataSink(file_path, callback); 292 return new StringTraceDataSink(CreateFileEndpoint(file_path, callback));
293 }
294
295 scoped_refptr<TracingController::TraceDataEndpoint>
296 TracingController::CreateFileEndpoint(const base::FilePath& file_path,
297 const base::Closure& callback) {
298 return new FileTraceDataEndpoint(file_path, callback);
278 } 299 }
279 300
280 } // namespace content 301 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698