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

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: Cleanup WIP. 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
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(
28 BrowserThread::UI,
29 FROM_HERE,
30 base::Bind( completion_callback_, str));
31 }
32
33 private:
34 ~StringTraceDataEndpoint() override {}
35
36 CompletionCallback completion_callback_;
37
38 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint);
39 };
40
41 class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
42 public:
43 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path,
44 const base::Closure& callback)
19 : file_path_(trace_file_path), 45 : file_path_(trace_file_path),
20 completion_callback_(callback), 46 completion_callback_(callback),
21 file_(NULL) {} 47 file_(NULL) {}
22 48
23 void AddTraceChunk(const std::string& chunk) override { 49 void ReceiveTraceChunk(const std::string& chunk) override {
24 std::string tmp = chunk; 50 std::string tmp = chunk;
25 scoped_refptr<base::RefCountedString> chunk_ptr = 51 scoped_refptr<base::RefCountedString> chunk_ptr =
26 base::RefCountedString::TakeString(&tmp); 52 base::RefCountedString::TakeString(&tmp);
27 BrowserThread::PostTask( 53 BrowserThread::PostTask(
28 BrowserThread::FILE, 54 BrowserThread::FILE,
29 FROM_HERE, 55 FROM_HERE,
30 base::Bind( 56 base::Bind(
31 &FileTraceDataSink::AddTraceChunkOnFileThread, this, chunk_ptr)); 57 &FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread,
58 this,
59 chunk_ptr));
32 } 60 }
33 void SetSystemTrace(const std::string& data) override { 61
34 system_trace_ = data; 62 void ReceiveTraceFinalContents(const std::string& contents) override {
35 }
36 void Close() override {
37 BrowserThread::PostTask( 63 BrowserThread::PostTask(
38 BrowserThread::FILE, 64 BrowserThread::FILE,
39 FROM_HERE, 65 FROM_HERE,
40 base::Bind(&FileTraceDataSink::CloseOnFileThread, this)); 66 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this));
41 } 67 }
42 68
43 private: 69 private:
44 ~FileTraceDataSink() override { DCHECK(file_ == NULL); } 70 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); }
45 71
46 void AddTraceChunkOnFileThread( 72 void ReceiveTraceChunkOnFileThread(
47 const scoped_refptr<base::RefCountedString> chunk) { 73 const scoped_refptr<base::RefCountedString> chunk) {
48 if (file_ != NULL) 74 if (!OpenFileIfNeededOnFileThread())
49 fputc(',', file_);
50 else if (!OpenFileIfNeededOnFileThread())
51 return; 75 return;
52 ignore_result(fwrite(chunk->data().c_str(), strlen(chunk->data().c_str()), 76 ignore_result(
53 1, file_)); 77 fwrite(chunk->data().c_str(), chunk->data().size(), 1, file_));
54 } 78 }
55 79
56 bool OpenFileIfNeededOnFileThread() { 80 bool OpenFileIfNeededOnFileThread() {
57 if (file_ != NULL) 81 if (file_ != NULL)
58 return true; 82 return true;
59 file_ = base::OpenFile(file_path_, "w"); 83 file_ = base::OpenFile(file_path_, "w");
60 if (file_ == NULL) { 84 if (file_ == NULL) {
61 LOG(ERROR) << "Failed to open " << file_path_.value(); 85 LOG(ERROR) << "Failed to open " << file_path_.value();
62 return false; 86 return false;
63 } 87 }
64 const char preamble[] = "{\"traceEvents\": [";
65 ignore_result(fwrite(preamble, strlen(preamble), 1, file_));
66 return true; 88 return true;
67 } 89 }
68 90
69 void CloseOnFileThread() { 91 void CloseOnFileThread() {
70 if (OpenFileIfNeededOnFileThread()) { 92 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_); 93 base::CloseFile(file_);
81 file_ = NULL; 94 file_ = NULL;
82 } 95 }
83 BrowserThread::PostTask( 96 BrowserThread::PostTask(
84 BrowserThread::UI, 97 BrowserThread::UI,
85 FROM_HERE, 98 FROM_HERE,
86 base::Bind(&FileTraceDataSink::FinalizeOnUIThread, this)); 99 base::Bind(&FileTraceDataEndpoint::FinalizeOnUIThread, this));
87 } 100 }
88 101
89 void FinalizeOnUIThread() { completion_callback_.Run(); } 102 void FinalizeOnUIThread() { completion_callback_.Run(); }
90 103
91 base::FilePath file_path_; 104 base::FilePath file_path_;
92 base::Closure completion_callback_; 105 base::Closure completion_callback_;
93 FILE* file_; 106 FILE* file_;
94 std::string system_trace_;
95 107
96 DISALLOW_COPY_AND_ASSIGN(FileTraceDataSink); 108 DISALLOW_COPY_AND_ASSIGN(FileTraceDataEndpoint);
97 }; 109 };
98 110
99 class StringTraceDataSink : public TracingController::TraceDataSink { 111 class StringTraceDataSink : public TracingController::TraceDataSink {
100 public: 112 public:
101 typedef base::Callback<void(base::RefCountedString*)> CompletionCallback; 113 explicit StringTraceDataSink(
114 scoped_refptr<TracingController::TraceDataEndpoint> endpoint)
115 : endpoint_(endpoint) {}
102 116
103 explicit StringTraceDataSink(CompletionCallback callback) 117 void AddTraceChunk(const std::string& chunk) override {
104 : completion_callback_(callback) {} 118 std::string trace_string;
119 if (trace_.empty())
120 trace_string = "{\"traceEvents\":[";
121 else
122 trace_string = ",";
123 trace_string += chunk;
105 124
106 // TracingController::TraceDataSink implementation 125 AddTraceChunkAndPassToEndpoint(trace_string);
107 void AddTraceChunk(const std::string& chunk) override { 126 }
108 if (!trace_.empty()) 127
109 trace_ += ","; 128 void AddTraceChunkAndPassToEndpoint(const std::string& chunk) {
110 trace_ += chunk; 129 trace_ += chunk;
130
131 endpoint_->ReceiveTraceChunk(chunk);
111 } 132 }
133
112 void SetSystemTrace(const std::string& data) override { 134 void SetSystemTrace(const std::string& data) override {
113 system_trace_ = data; 135 system_trace_ = data;
114 } 136 }
137
115 void Close() override { 138 void Close() override {
116 std::string result = "{\"traceEvents\":[" + trace_ + "]"; 139 AddTraceChunkAndPassToEndpoint("]");
117 if (!system_trace_.empty()) 140 if (!system_trace_.empty())
118 result += ",\"systemTraceEvents\": " + system_trace_; 141 AddTraceChunkAndPassToEndpoint(
119 result += "}"; 142 ",\"systemTraceEvents\": " + system_trace_);
143 AddTraceChunkAndPassToEndpoint("}");
120 144
121 scoped_refptr<base::RefCountedString> str = 145 endpoint_->ReceiveTraceFinalContents(trace_);
122 base::RefCountedString::TakeString(&result);
123 completion_callback_.Run(str.get());
124 } 146 }
125 147
126 private: 148 private:
127 ~StringTraceDataSink() override {} 149 ~StringTraceDataSink() override {}
128 150
151 scoped_refptr<TracingController::TraceDataEndpoint> endpoint_;
129 std::string trace_; 152 std::string trace_;
130 std::string system_trace_; 153 std::string system_trace_;
131 CompletionCallback completion_callback_;
132 154
133 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink); 155 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink);
134 }; 156 };
135 157
136 class CompressedStringTraceDataSink : public TracingController::TraceDataSink { 158 class CompressedStringTraceDataSink : public TracingController::TraceDataSink {
137 public: 159 public:
160 const int kChunkSize = 0x4000;
161
138 explicit CompressedStringTraceDataSink( 162 explicit CompressedStringTraceDataSink(
139 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) 163 scoped_refptr<TracingController::TraceDataEndpoint> endpoint)
140 : endpoint_(endpoint), already_tried_open_(false) {} 164 : endpoint_(endpoint), already_tried_open_(false) {}
141 165
142 void AddTraceChunk(const std::string& chunk) override { 166 void AddTraceChunk(const std::string& chunk) override {
143 std::string tmp = chunk; 167 std::string tmp = chunk;
144 scoped_refptr<base::RefCountedString> chunk_ptr = 168 scoped_refptr<base::RefCountedString> chunk_ptr =
145 base::RefCountedString::TakeString(&tmp); 169 base::RefCountedString::TakeString(&tmp);
146 BrowserThread::PostTask( 170 BrowserThread::PostTask(
147 BrowserThread::FILE, FROM_HERE, 171 BrowserThread::FILE, FROM_HERE,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 trace += chunk_ptr->data(); 220 trace += chunk_ptr->data();
197 AddTraceChunkAndCompressOnFileThread(trace, false); 221 AddTraceChunkAndCompressOnFileThread(trace, false);
198 } 222 }
199 223
200 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk, 224 void AddTraceChunkAndCompressOnFileThread(const std::string& chunk,
201 bool finished) { 225 bool finished) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
203 if (!OpenZStreamOnFileThread()) 227 if (!OpenZStreamOnFileThread())
204 return; 228 return;
205 229
206 const int kChunkSize = 0x4000;
207
208 char buffer[kChunkSize]; 230 char buffer[kChunkSize];
209 int err; 231 int err;
210 stream_->avail_in = chunk.size(); 232 stream_->avail_in = chunk.size();
211 stream_->next_in = (unsigned char*)chunk.data(); 233 stream_->next_in = (unsigned char*)chunk.data();
212 do { 234 do {
213 stream_->avail_out = kChunkSize; 235 stream_->avail_out = kChunkSize;
214 stream_->next_out = (unsigned char*)buffer; 236 stream_->next_out = (unsigned char*)buffer;
215 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); 237 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH);
216 if (err != Z_OK && (err != Z_STREAM_END && finished)) { 238 if (err != Z_OK && (err != Z_STREAM_END && finished)) {
217 stream_.reset(); 239 stream_.reset();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 std::string system_trace_; 277 std::string system_trace_;
256 278
257 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink); 279 DISALLOW_COPY_AND_ASSIGN(CompressedStringTraceDataSink);
258 }; 280 };
259 281
260 } // namespace 282 } // namespace
261 283
262 scoped_refptr<TracingController::TraceDataSink> 284 scoped_refptr<TracingController::TraceDataSink>
263 TracingController::CreateStringSink( 285 TracingController::CreateStringSink(
264 const base::Callback<void(base::RefCountedString*)>& callback) { 286 const base::Callback<void(base::RefCountedString*)>& callback) {
265 return new StringTraceDataSink(callback); 287 return new StringTraceDataSink(new StringTraceDataEndpoint(callback));
266 } 288 }
267 289
268 scoped_refptr<TracingController::TraceDataSink> 290 scoped_refptr<TracingController::TraceDataSink>
269 TracingController::CreateCompressedStringSink( 291 TracingController::CreateCompressedStringSink(
270 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) { 292 scoped_refptr<TracingController::TraceDataEndpoint> endpoint) {
271 return new CompressedStringTraceDataSink(endpoint); 293 return new CompressedStringTraceDataSink(endpoint);
272 } 294 }
273 295
274 scoped_refptr<TracingController::TraceDataSink> 296 scoped_refptr<TracingController::TraceDataSink>
275 TracingController::CreateFileSink(const base::FilePath& file_path, 297 TracingController::CreateFileSink(const base::FilePath& file_path,
276 const base::Closure& callback) { 298 const base::Closure& callback) {
277 return new FileTraceDataSink(file_path, callback); 299 return new StringTraceDataSink(
300 CreateFileEndpoint(file_path, callback));
301 }
302
303 scoped_refptr<TracingController::TraceDataEndpoint>
304 TracingController::CreateFileEndpoint(const base::FilePath& file_path,
305 const base::Closure& callback) {
306 return new FileTraceDataEndpoint(file_path, callback);
278 } 307 }
279 308
280 } // namespace content 309 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698