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

Side by Side Diff: chrome/browser/net/passive_log_collector.cc

Issue 1560025: Initialize the new net internals page using the passively collected log entri... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Add missing unittest file Created 10 years, 8 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/net/passive_log_collector.h" 5 #include "chrome/browser/net/passive_log_collector.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/browser/chrome_thread.h" 10 #include "chrome/browser/chrome_thread.h"
11 11
12 namespace { 12 namespace {
13 const size_t kMaxNumEntriesPerLog = 50; 13 const size_t kMaxNumEntriesPerLog = 50;
14 const size_t kMaxConnectJobGraveyardSize = 3; 14 const size_t kMaxConnectJobGraveyardSize = 3;
15 const size_t kMaxRequestGraveyardSize = 25; 15 const size_t kMaxRequestGraveyardSize = 25;
16 const size_t kMaxLiveRequests = 200; 16 const size_t kMaxLiveRequests = 200;
17 17
18 // Sort function on source ID. 18 // Sort function on source ID.
19 bool OrderBySourceID(const PassiveLogCollector::RequestInfo& a, 19 bool OrderBySourceID(const PassiveLogCollector::RequestInfo& a,
20 const PassiveLogCollector::RequestInfo& b) { 20 const PassiveLogCollector::RequestInfo& b) {
21 return a.entries[0].source.id < b.entries[0].source.id; 21 return a.entries[0].source.id < b.entries[0].source.id;
22 } 22 }
23 23
24 void AddEntryToRequestInfo(const net::CapturingNetLog::Entry& entry, 24 void AddEntryToRequestInfo(const PassiveLogCollector::Entry& entry,
25 bool is_unbounded, 25 bool is_unbounded,
26 PassiveLogCollector::RequestInfo* out_info) { 26 PassiveLogCollector::RequestInfo* out_info) {
27 // Start dropping new entries when the log has gotten too big. 27 // Start dropping new entries when the log has gotten too big.
28 if (out_info->entries.size() + 1 <= kMaxNumEntriesPerLog || is_unbounded) { 28 if (out_info->entries.size() + 1 <= kMaxNumEntriesPerLog || is_unbounded) {
29 out_info->entries.push_back(entry); 29 out_info->entries.push_back(entry);
30 } else { 30 } else {
31 out_info->num_entries_truncated += 1; 31 out_info->num_entries_truncated += 1;
32 out_info->entries[kMaxNumEntriesPerLog - 1] = entry; 32 out_info->entries[kMaxNumEntriesPerLog - 1] = entry;
33 } 33 }
34 } 34 }
35 35
36 void AppendToRequestInfo(const PassiveLogCollector::RequestInfo& info, 36 void AppendToRequestInfo(const PassiveLogCollector::RequestInfo& info,
37 bool is_unbounded, 37 bool is_unbounded,
38 PassiveLogCollector::RequestInfo* out_info) { 38 PassiveLogCollector::RequestInfo* out_info) {
39 for (size_t i = 0; i < info.entries.size(); ++i) 39 for (size_t i = 0; i < info.entries.size(); ++i)
40 AddEntryToRequestInfo(info.entries[i], is_unbounded, out_info); 40 AddEntryToRequestInfo(info.entries[i], is_unbounded, out_info);
41 } 41 }
42 42
43 // Appends all of the logged events in |input| to |out|.
44 void AppendAllEntriesFromRequests(
45 const PassiveLogCollector::RequestInfoList& input,
46 PassiveLogCollector::EntryList* out) {
47 for (size_t i = 0; i < input.size(); ++i) {
48 const PassiveLogCollector::EntryList& entries = input[i].entries;
49 out->insert(out->end(), entries.begin(), entries.end());
50 }
51 }
52
53 // Comparator to sort entries by their |order| property, ascending.
54 bool SortByOrderComparator(const PassiveLogCollector::Entry& a,
55 const PassiveLogCollector::Entry& b) {
56 return a.order < b.order;
57 }
58
43 } // namespace 59 } // namespace
44 60
45 //---------------------------------------------------------------------------- 61 //----------------------------------------------------------------------------
46 // PassiveLogCollector 62 // PassiveLogCollector
47 //---------------------------------------------------------------------------- 63 //----------------------------------------------------------------------------
48 64
49 PassiveLogCollector::PassiveLogCollector() 65 PassiveLogCollector::PassiveLogCollector()
50 : url_request_tracker_(&connect_job_tracker_), 66 : url_request_tracker_(&connect_job_tracker_),
51 socket_stream_tracker_(&connect_job_tracker_) { 67 socket_stream_tracker_(&connect_job_tracker_),
68 num_events_seen_(0) {
52 } 69 }
53 70
54 PassiveLogCollector::~PassiveLogCollector() { 71 PassiveLogCollector::~PassiveLogCollector() {
55 } 72 }
56 73
57 void PassiveLogCollector::OnAddEntry( 74 void PassiveLogCollector::OnAddEntry(
58 net::NetLog::EventType type, 75 net::NetLog::EventType type,
59 const base::TimeTicks& time, 76 const base::TimeTicks& time,
60 const net::NetLog::Source& source, 77 const net::NetLog::Source& source,
61 net::NetLog::EventPhase phase, 78 net::NetLog::EventPhase phase,
62 net::NetLog::EventParameters* extra_parameters) { 79 net::NetLog::EventParameters* extra_parameters) {
63 // Package the parameters into a single struct for convenience. 80 // Package the parameters into a single struct for convenience.
64 net::CapturingNetLog::Entry entry(type, time, source, phase, 81 Entry entry(num_events_seen_++, type, time, source, phase, extra_parameters);
65 extra_parameters);
66 82
67 switch (entry.source.type) { 83 switch (entry.source.type) {
68 case net::NetLog::SOURCE_URL_REQUEST: 84 case net::NetLog::SOURCE_URL_REQUEST:
69 url_request_tracker_.OnAddEntry(entry); 85 url_request_tracker_.OnAddEntry(entry);
70 break; 86 break;
71 case net::NetLog::SOURCE_SOCKET_STREAM: 87 case net::NetLog::SOURCE_SOCKET_STREAM:
72 socket_stream_tracker_.OnAddEntry(entry); 88 socket_stream_tracker_.OnAddEntry(entry);
73 break; 89 break;
74 case net::NetLog::SOURCE_CONNECT_JOB: 90 case net::NetLog::SOURCE_CONNECT_JOB:
75 connect_job_tracker_.OnAddEntry(entry); 91 connect_job_tracker_.OnAddEntry(entry);
76 break; 92 break;
77 case net::NetLog::SOURCE_INIT_PROXY_RESOLVER: 93 case net::NetLog::SOURCE_INIT_PROXY_RESOLVER:
78 init_proxy_resolver_tracker_.OnAddEntry(entry); 94 init_proxy_resolver_tracker_.OnAddEntry(entry);
79 break; 95 break;
80 default: 96 default:
81 // Drop all other logged events. 97 // Drop all other logged events.
82 break; 98 break;
83 } 99 }
84 } 100 }
85 101
86 void PassiveLogCollector::Clear() { 102 void PassiveLogCollector::Clear() {
87 connect_job_tracker_.Clear(); 103 connect_job_tracker_.Clear();
88 url_request_tracker_.Clear(); 104 url_request_tracker_.Clear();
89 socket_stream_tracker_.Clear(); 105 socket_stream_tracker_.Clear();
90 } 106 }
91 107
108 void PassiveLogCollector::GetAllCapturedEvents(EntryList* out) const {
109 out->clear();
110
111 // Append all of the captured entries held by the various trackers to
112 // |out|.
113 socket_stream_tracker_.AppendAllEntries(out);
114 url_request_tracker_.AppendAllEntries(out);
115
116 const EntryList& proxy_entries =
117 init_proxy_resolver_tracker_.entries();
118 out->insert(out->end(), proxy_entries.begin(), proxy_entries.end());
119
120 // Now sort the list of entries by their insertion time (ascending).
121 std::sort(out->begin(), out->end(), &SortByOrderComparator);
122 }
123
92 //---------------------------------------------------------------------------- 124 //----------------------------------------------------------------------------
93 // RequestTrackerBase 125 // RequestTrackerBase
94 //---------------------------------------------------------------------------- 126 //----------------------------------------------------------------------------
95 127
96 PassiveLogCollector::RequestTrackerBase::RequestTrackerBase( 128 PassiveLogCollector::RequestTrackerBase::RequestTrackerBase(
97 size_t max_graveyard_size) 129 size_t max_graveyard_size)
98 : max_graveyard_size_(max_graveyard_size), 130 : max_graveyard_size_(max_graveyard_size),
99 next_graveyard_index_(0), 131 next_graveyard_index_(0),
100 is_unbounded_(false) { 132 is_unbounded_(false) {
101 } 133 }
102 134
103 void PassiveLogCollector::RequestTrackerBase::OnAddEntry( 135 void PassiveLogCollector::RequestTrackerBase::OnAddEntry(const Entry& entry) {
104 const net::CapturingNetLog::Entry& entry) {
105 RequestInfo& info = live_requests_[entry.source.id]; 136 RequestInfo& info = live_requests_[entry.source.id];
106 Action result = DoAddEntry(entry, &info); 137 Action result = DoAddEntry(entry, &info);
107 138
108 switch (result) { 139 switch (result) {
109 case ACTION_MOVE_TO_GRAVEYARD: 140 case ACTION_MOVE_TO_GRAVEYARD:
110 InsertIntoGraveyard(info); 141 InsertIntoGraveyard(info);
111 // (fall-through) 142 // (fall-through)
112 case ACTION_DELETE: 143 case ACTION_DELETE:
113 RemoveFromLiveRequests(entry.source.id); 144 RemoveFromLiveRequests(entry.source.id);
114 break; 145 break;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 ClearRecentlyDeceased(); 223 ClearRecentlyDeceased();
193 224
194 is_unbounded_ = unbounded; 225 is_unbounded_ = unbounded;
195 } 226 }
196 227
197 void PassiveLogCollector::RequestTrackerBase::Clear() { 228 void PassiveLogCollector::RequestTrackerBase::Clear() {
198 ClearRecentlyDeceased(); 229 ClearRecentlyDeceased();
199 live_requests_.clear(); 230 live_requests_.clear();
200 } 231 }
201 232
233 void PassiveLogCollector::RequestTrackerBase::AppendAllEntries(
234 EntryList* out) const {
235 AppendAllEntriesFromRequests(GetLiveRequests(), out);
236 AppendAllEntriesFromRequests(GetRecentlyDeceased(), out);
237 }
238
202 void PassiveLogCollector::RequestTrackerBase::InsertIntoGraveyard( 239 void PassiveLogCollector::RequestTrackerBase::InsertIntoGraveyard(
203 const RequestInfo& info) { 240 const RequestInfo& info) {
204 if (is_unbounded_) { 241 if (is_unbounded_) {
205 graveyard_.push_back(info); 242 graveyard_.push_back(info);
206 return; 243 return;
207 } 244 }
208 245
209 // Otherwise enforce a bound on the graveyard size, by treating it as a 246 // Otherwise enforce a bound on the graveyard size, by treating it as a
210 // circular buffer. 247 // circular buffer.
211 if (graveyard_.size() < max_graveyard_size_) { 248 if (graveyard_.size() < max_graveyard_size_) {
(...skipping 11 matching lines...) Expand all
223 // ConnectJobTracker 260 // ConnectJobTracker
224 //---------------------------------------------------------------------------- 261 //----------------------------------------------------------------------------
225 262
226 const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 3; 263 const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 3;
227 264
228 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker() 265 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker()
229 : RequestTrackerBase(kMaxGraveyardSize) { 266 : RequestTrackerBase(kMaxGraveyardSize) {
230 } 267 }
231 268
232 PassiveLogCollector::RequestTrackerBase::Action 269 PassiveLogCollector::RequestTrackerBase::Action
233 PassiveLogCollector::ConnectJobTracker::DoAddEntry( 270 PassiveLogCollector::ConnectJobTracker::DoAddEntry(const Entry& entry,
234 const net::CapturingNetLog::Entry& entry, 271 RequestInfo* out_info) {
235 RequestInfo* out_info) {
236 // Save the entry (possibly truncating). 272 // Save the entry (possibly truncating).
237 AddEntryToRequestInfo(entry, is_unbounded(), out_info); 273 AddEntryToRequestInfo(entry, is_unbounded(), out_info);
238 274
239 // If this is the end of the connect job, move the request to the graveyard. 275 // If this is the end of the connect job, move the request to the graveyard.
240 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB && 276 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB &&
241 entry.phase == net::NetLog::PHASE_END) { 277 entry.phase == net::NetLog::PHASE_END) {
242 return ACTION_MOVE_TO_GRAVEYARD; 278 return ACTION_MOVE_TO_GRAVEYARD;
243 } 279 }
244 280
245 return ACTION_NONE; 281 return ACTION_NONE;
246 } 282 }
247 283
248 //---------------------------------------------------------------------------- 284 //----------------------------------------------------------------------------
249 // RequestTracker 285 // RequestTracker
250 //---------------------------------------------------------------------------- 286 //----------------------------------------------------------------------------
251 287
252 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25; 288 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25;
253 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardURLSize = 1000; 289 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardURLSize = 1000;
254 290
255 PassiveLogCollector::RequestTracker::RequestTracker( 291 PassiveLogCollector::RequestTracker::RequestTracker(
256 ConnectJobTracker* connect_job_tracker) 292 ConnectJobTracker* connect_job_tracker)
257 : RequestTrackerBase(kMaxGraveyardSize), 293 : RequestTrackerBase(kMaxGraveyardSize),
258 connect_job_tracker_(connect_job_tracker) { 294 connect_job_tracker_(connect_job_tracker) {
259 } 295 }
260 296
261 PassiveLogCollector::RequestTrackerBase::Action 297 PassiveLogCollector::RequestTrackerBase::Action
262 PassiveLogCollector::RequestTracker::DoAddEntry( 298 PassiveLogCollector::RequestTracker::DoAddEntry(const Entry& entry,
263 const net::CapturingNetLog::Entry& entry, 299 RequestInfo* out_info) {
264 RequestInfo* out_info) {
265 300
266 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) { 301 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) {
267 // If this was notification that a ConnectJob was bound to the request, 302 // If this was notification that a ConnectJob was bound to the request,
268 // copy all the logged data for that ConnectJob. 303 // copy all the logged data for that ConnectJob.
269 AddConnectJobInfo(entry, out_info); 304 AddConnectJobInfo(entry, out_info);
270 } else { 305 } else {
271 // Otherwise just append this entry to the request info. 306 // Otherwise just append this entry to the request info.
272 AddEntryToRequestInfo(entry, is_unbounded(), out_info); 307 AddEntryToRequestInfo(entry, is_unbounded(), out_info);
273 } 308 }
274 309
(...skipping 16 matching lines...) Expand all
291 // adds to clutter. 326 // adds to clutter.
292 return ACTION_DELETE; 327 return ACTION_DELETE;
293 } 328 }
294 return ACTION_MOVE_TO_GRAVEYARD; 329 return ACTION_MOVE_TO_GRAVEYARD;
295 } 330 }
296 331
297 return ACTION_NONE; 332 return ACTION_NONE;
298 } 333 }
299 334
300 void PassiveLogCollector::RequestTracker::AddConnectJobInfo( 335 void PassiveLogCollector::RequestTracker::AddConnectJobInfo(
301 const net::CapturingNetLog::Entry& entry, 336 const Entry& entry,
302 RequestInfo* live_entry) { 337 RequestInfo* live_entry) {
303 // We have just been notified of which ConnectJob the 338 // We have just been notified of which ConnectJob the
304 // URLRequest/SocketStream was assigned. Lookup all the data we captured 339 // URLRequest/SocketStream was assigned. Lookup all the data we captured
305 // for the ConnectJob, and append it to the URLRequest/SocketStream's 340 // for the ConnectJob, and append it to the URLRequest/SocketStream's
306 // RequestInfo. 341 // RequestInfo.
307 342
308 int connect_job_id = static_cast<net::NetLogIntegerParameter*>( 343 int connect_job_id = static_cast<net::NetLogIntegerParameter*>(
309 entry.extra_parameters.get())->value(); 344 entry.extra_parameters.get())->value();
310 345
311 const RequestInfo* connect_job_info = 346 const RequestInfo* connect_job_info =
312 connect_job_tracker_->GetRequestInfoFromGraveyard(connect_job_id); 347 connect_job_tracker_->GetRequestInfoFromGraveyard(connect_job_id);
313 348
314 if (connect_job_info) { 349 if (connect_job_info) {
315 // Append the ConnectJob information we found. 350 // Append the ConnectJob information we found.
316 AppendToRequestInfo(*connect_job_info, is_unbounded(), live_entry); 351 AppendToRequestInfo(*connect_job_info, is_unbounded(), live_entry);
317 } else { 352 } else {
318 // If we couldn't find the information for the ConnectJob, append a 353 // If we couldn't find the information for the ConnectJob, append a
319 // generic message instead. 354 // generic message instead.
320 net::CapturingNetLog::Entry e(entry); 355 Entry e(entry);
321 e.type = net::NetLog::TYPE_TODO_STRING; 356 e.type = net::NetLog::TYPE_TODO_STRING;
322 e.extra_parameters = new net::NetLogStringParameter( 357 e.extra_parameters = new net::NetLogStringParameter(
323 StringPrintf("Used ConnectJob id=%d", connect_job_id)); 358 StringPrintf("Used ConnectJob id=%d", connect_job_id));
324 AddEntryToRequestInfo(e, is_unbounded(), live_entry); 359 AddEntryToRequestInfo(e, is_unbounded(), live_entry);
325 } 360 }
326 } 361 }
327 362
328 //---------------------------------------------------------------------------- 363 //----------------------------------------------------------------------------
329 // InitProxyResolverTracker 364 // InitProxyResolverTracker
330 //---------------------------------------------------------------------------- 365 //----------------------------------------------------------------------------
331 366
332 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() {} 367 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() {}
333 368
334 void PassiveLogCollector::InitProxyResolverTracker::OnAddEntry( 369 void PassiveLogCollector::InitProxyResolverTracker::OnAddEntry(
335 const net::CapturingNetLog::Entry& entry) { 370 const Entry& entry) {
336 if (entry.type == net::NetLog::TYPE_INIT_PROXY_RESOLVER && 371 if (entry.type == net::NetLog::TYPE_INIT_PROXY_RESOLVER &&
337 entry.phase == net::NetLog::PHASE_BEGIN) { 372 entry.phase == net::NetLog::PHASE_BEGIN) {
338 // If this is the start of a new InitProxyResolver, overwrite the old data. 373 // If this is the start of a new InitProxyResolver, overwrite the old data.
339 entries_.clear(); 374 entries_.clear();
340 entries_.push_back(entry); 375 entries_.push_back(entry);
341 } else { 376 } else {
342 // Otherwise append it to the log for the latest InitProxyResolver. 377 // Otherwise append it to the log for the latest InitProxyResolver.
343 if (!entries_.empty() && entries_[0].source.id != entry.source.id) { 378 if (!entries_.empty() && entries_[0].source.id != entry.source.id) {
344 // If this entry doesn't match what we think was the latest 379 // If this entry doesn't match what we think was the latest
345 // InitProxyResolver, drop it. (This shouldn't happen, but we will guard 380 // InitProxyResolver, drop it. (This shouldn't happen, but we will guard
346 // against it). 381 // against it).
347 return; 382 return;
348 } 383 }
349 entries_.push_back(entry); 384 entries_.push_back(entry);
350 } 385 }
351 386
352 // Safety net: INIT_PROXY_RESOLVER shouldn't generate many messages, but in 387 // Safety net: INIT_PROXY_RESOLVER shouldn't generate many messages, but in
353 // case something goes wrong, avoid exploding the memory usage. 388 // case something goes wrong, avoid exploding the memory usage.
354 if (entries_.size() > kMaxNumEntriesPerLog) 389 if (entries_.size() > kMaxNumEntriesPerLog)
355 entries_.clear(); 390 entries_.clear();
356 } 391 }
357 392
OLDNEW
« no previous file with comments | « chrome/browser/net/passive_log_collector.h ('k') | chrome/browser/net/passive_log_collector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698