1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/net/passive_log_collector.h"
6
7 #include <algorithm>
8
9 #include "base/compiler_specific.h"
10 #include "base/string_util.h"
11 #include "base/format_macros.h"
12 #include "net/url_request/url_request_netlog_params.h"
13
14 namespace {
15
16 // TODO(eroman): Do something with the truncation count.
17
18 const size_t kMaxNumEntriesPerLog = 30;
19
AddEntryToSourceInfo(const ChromeNetLog::Entry & entry,PassiveLogCollector::SourceInfo * out_info)20 void AddEntryToSourceInfo(const ChromeNetLog::Entry& entry,
21 PassiveLogCollector::SourceInfo* out_info) {
22 // Start dropping new entries when the log has gotten too big.
23 if (out_info->entries.size() + 1 <= kMaxNumEntriesPerLog) {
24 out_info->entries.push_back(entry);
25 } else {
26 out_info->num_entries_truncated += 1;
27 out_info->entries[kMaxNumEntriesPerLog - 1] = entry;
28 }
29 }
30
31 // Comparator to sort entries by their |order| property, ascending.
SortByOrderComparator(const ChromeNetLog::Entry & a,const ChromeNetLog::Entry & b)32 bool SortByOrderComparator(const ChromeNetLog::Entry& a,
33 const ChromeNetLog::Entry& b) {
34 return a.order < b.order;
35 }
36
37 } // namespace
38
SourceInfo()39 PassiveLogCollector::SourceInfo::SourceInfo()
40 : source_id(net::NetLog::Source::kInvalidId),
41 num_entries_truncated(0),
42 reference_count(0),
43 is_alive(true) {
44 }
45
~SourceInfo()46 PassiveLogCollector::SourceInfo::~SourceInfo() {}
47
48 //----------------------------------------------------------------------------
49 // PassiveLogCollector
50 //----------------------------------------------------------------------------
51
PassiveLogCollector()52 PassiveLogCollector::PassiveLogCollector()
53 : ThreadSafeObserver(net::NetLog::LOG_BASIC),
54 ALLOW_THIS_IN_INITIALIZER_LIST(connect_job_tracker_(this)),
55 ALLOW_THIS_IN_INITIALIZER_LIST(url_request_tracker_(this)),
56 ALLOW_THIS_IN_INITIALIZER_LIST(socket_stream_tracker_(this)),
57 ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_job_tracker_(this)),
58 num_events_seen_(0) {
59
60 // Define the mapping between source types and the tracker objects.
61 memset(&trackers_[0], 0, sizeof(trackers_));
62 trackers_[net::NetLog::SOURCE_NONE] = &global_source_tracker_;
63 trackers_[net::NetLog::SOURCE_URL_REQUEST] = &url_request_tracker_;
64 trackers_[net::NetLog::SOURCE_SOCKET_STREAM] = &socket_stream_tracker_;
65 trackers_[net::NetLog::SOURCE_CONNECT_JOB] = &connect_job_tracker_;
66 trackers_[net::NetLog::SOURCE_SOCKET] = &socket_tracker_;
67 trackers_[net::NetLog::SOURCE_INIT_PROXY_RESOLVER] =
68 &init_proxy_resolver_tracker_;
69 trackers_[net::NetLog::SOURCE_SPDY_SESSION] = &spdy_session_tracker_;
70 trackers_[net::NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST] =
71 &dns_request_tracker_;
72 trackers_[net::NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB] = &dns_job_tracker_;
73 trackers_[net::NetLog::SOURCE_DISK_CACHE_ENTRY] = &disk_cache_entry_tracker_;
74 trackers_[net::NetLog::SOURCE_MEMORY_CACHE_ENTRY] = &mem_cache_entry_tracker_;
75 trackers_[net::NetLog::SOURCE_HTTP_STREAM_JOB] = &http_stream_job_tracker_;
76 // Make sure our mapping is up-to-date.
77 for (size_t i = 0; i < arraysize(trackers_); ++i)
78 DCHECK(trackers_[i]) << "Unhandled SourceType: " << i;
79 }
80
~PassiveLogCollector()81 PassiveLogCollector::~PassiveLogCollector() {
82 }
83
OnAddEntry(net::NetLog::EventType type,const base::TimeTicks & time,const net::NetLog::Source & source,net::NetLog::EventPhase phase,net::NetLog::EventParameters * params)84 void PassiveLogCollector::OnAddEntry(
85 net::NetLog::EventType type,
86 const base::TimeTicks& time,
87 const net::NetLog::Source& source,
88 net::NetLog::EventPhase phase,
89 net::NetLog::EventParameters* params) {
90 AssertNetLogLockAcquired();
91 // Package the parameters into a single struct for convenience.
92 ChromeNetLog::Entry entry(num_events_seen_++, type, time, source, phase,
93 params);
94
95 SourceTrackerInterface* tracker = GetTrackerForSourceType(entry.source.type);
96 if (tracker)
97 tracker->OnAddEntry(entry);
98 }
99
Clear()100 void PassiveLogCollector::Clear() {
101 AssertNetLogLockAcquired();
102 for (size_t i = 0; i < arraysize(trackers_); ++i)
103 trackers_[i]->Clear();
104 }
105
106 PassiveLogCollector::SourceTrackerInterface*
GetTrackerForSourceType(net::NetLog::SourceType source_type)107 PassiveLogCollector::GetTrackerForSourceType(
108 net::NetLog::SourceType source_type) {
109 CHECK_LT(source_type, static_cast<int>(arraysize(trackers_)));
110 CHECK_GE(source_type, 0);
111 return trackers_[source_type];
112 }
113
GetAllCapturedEvents(ChromeNetLog::EntryList * out) const114 void PassiveLogCollector::GetAllCapturedEvents(
115 ChromeNetLog::EntryList* out) const {
116 AssertNetLogLockAcquired();
117 out->clear();
118
119 // Append all of the captured entries held by the various trackers to
120 // |out|.
121 for (size_t i = 0; i < arraysize(trackers_); ++i)
122 trackers_[i]->AppendAllEntries(out);
123
124 // Now sort the list of entries by their insertion time (ascending).
125 std::sort(out->begin(), out->end(), &SortByOrderComparator);
126 }
127
GetURL() const128 std::string PassiveLogCollector::SourceInfo::GetURL() const {
129 // Note: we look at the first *two* entries, since the outer REQUEST_ALIVE
130 // doesn't actually contain any data.
131 for (size_t i = 0; i < 2 && i < entries.size(); ++i) {
132 const ChromeNetLog::Entry& entry = entries[i];
133 if (entry.phase == net::NetLog::PHASE_BEGIN && entry.params) {
134 switch (entry.type) {
135 case net::NetLog::TYPE_URL_REQUEST_START_JOB:
136 return static_cast<net::URLRequestStartEventParameters*>(
137 entry.params.get())->url().possibly_invalid_spec();
138 case net::NetLog::TYPE_SOCKET_STREAM_CONNECT:
139 return static_cast<net::NetLogStringParameter*>(
140 entry.params.get())->value();
141 default:
142 break;
143 }
144 }
145 }
146 return std::string();
147 }
148
149 //----------------------------------------------------------------------------
150 // GlobalSourceTracker
151 //----------------------------------------------------------------------------
152
GlobalSourceTracker()153 PassiveLogCollector::GlobalSourceTracker::GlobalSourceTracker() {}
~GlobalSourceTracker()154 PassiveLogCollector::GlobalSourceTracker::~GlobalSourceTracker() {}
155
OnAddEntry(const ChromeNetLog::Entry & entry)156 void PassiveLogCollector::GlobalSourceTracker::OnAddEntry(
157 const ChromeNetLog::Entry& entry) {
158 const size_t kMaxEntries = 30u;
159 entries_.push_back(entry);
160 if (entries_.size() > kMaxEntries)
161 entries_.pop_front();
162 }
163
Clear()164 void PassiveLogCollector::GlobalSourceTracker::Clear() {
165 entries_.clear();
166 }
167
AppendAllEntries(ChromeNetLog::EntryList * out) const168 void PassiveLogCollector::GlobalSourceTracker::AppendAllEntries(
169 ChromeNetLog::EntryList* out) const {
170 out->insert(out->end(), entries_.begin(), entries_.end());
171 }
172
173 //----------------------------------------------------------------------------
174 // SourceTracker
175 //----------------------------------------------------------------------------
176
SourceTracker(size_t max_num_sources,size_t max_graveyard_size,PassiveLogCollector * parent)177 PassiveLogCollector::SourceTracker::SourceTracker(
178 size_t max_num_sources,
179 size_t max_graveyard_size,
180 PassiveLogCollector* parent)
181 : max_num_sources_(max_num_sources),
182 max_graveyard_size_(max_graveyard_size),
183 parent_(parent) {
184 }
185
~SourceTracker()186 PassiveLogCollector::SourceTracker::~SourceTracker() {}
187
OnAddEntry(const ChromeNetLog::Entry & entry)188 void PassiveLogCollector::SourceTracker::OnAddEntry(
189 const ChromeNetLog::Entry& entry) {
190 // Lookup or insert a new entry into the bounded map.
191 SourceIDToInfoMap::iterator it = sources_.find(entry.source.id);
192 if (it == sources_.end()) {
193 if (sources_.size() >= max_num_sources_) {
194 LOG(WARNING) << "The passive log data has grown larger "
195 "than expected, resetting";
196 Clear();
197 }
198 it = sources_.insert(
199 SourceIDToInfoMap::value_type(entry.source.id, SourceInfo())).first;
200 it->second.source_id = entry.source.id;
201 }
202
203 SourceInfo& info = it->second;
204 Action result = DoAddEntry(entry, &info);
205
206 if (result != ACTION_NONE) {
207 // We are either queuing it for deletion, or deleting it immediately.
208 // If someone else holds a reference to this source, defer the deletion
209 // until all the references are released.
210 info.is_alive = false;
211 if (info.reference_count == 0) {
212 switch (result) {
213 case ACTION_MOVE_TO_GRAVEYARD:
214 AddToDeletionQueue(info.source_id);
215 break;
216 case ACTION_DELETE:
217 DeleteSourceInfo(info.source_id);
218 break;
219 default:
220 NOTREACHED();
221 break;
222 }
223 }
224 }
225 }
226
DeleteSourceInfo(uint32 source_id)227 void PassiveLogCollector::SourceTracker::DeleteSourceInfo(
228 uint32 source_id) {
229 SourceIDToInfoMap::iterator it = sources_.find(source_id);
230 if (it == sources_.end()) {
231 // TODO(eroman): Is this happening? And if so, why. Remove this
232 // once the cause is understood.
233 LOG(WARNING) << "Tried to delete info for nonexistent source";
234 return;
235 }
236 // The source should not be in the deletion queue.
237 CHECK(std::find(deletion_queue_.begin(), deletion_queue_.end(),
238 source_id) == deletion_queue_.end());
239 ReleaseAllReferencesToDependencies(&(it->second));
240 sources_.erase(it);
241 }
242
Clear()243 void PassiveLogCollector::SourceTracker::Clear() {
244 deletion_queue_.clear();
245
246 // Release all references held to dependent sources.
247 for (SourceIDToInfoMap::iterator it = sources_.begin();
248 it != sources_.end();
249 ++it) {
250 ReleaseAllReferencesToDependencies(&(it->second));
251 }
252 sources_.clear();
253 }
254
AppendAllEntries(ChromeNetLog::EntryList * out) const255 void PassiveLogCollector::SourceTracker::AppendAllEntries(
256 ChromeNetLog::EntryList* out) const {
257 // Append all of the entries for each of the sources.
258 for (SourceIDToInfoMap::const_iterator it = sources_.begin();
259 it != sources_.end();
260 ++it) {
261 const SourceInfo& info = it->second;
262 out->insert(out->end(), info.entries.begin(), info.entries.end());
263 }
264 }
265
AddToDeletionQueue(uint32 source_id)266 void PassiveLogCollector::SourceTracker::AddToDeletionQueue(
267 uint32 source_id) {
268 DCHECK(sources_.find(source_id) != sources_.end());
269 DCHECK(!sources_.find(source_id)->second.is_alive);
270 DCHECK_GE(sources_.find(source_id)->second.reference_count, 0);
271 DCHECK_LE(deletion_queue_.size(), max_graveyard_size_);
272
273 DCHECK(std::find(deletion_queue_.begin(), deletion_queue_.end(),
274 source_id) == deletion_queue_.end());
275 deletion_queue_.push_back(source_id);
276
277 // After the deletion queue has reached its maximum size, start
278 // deleting sources in FIFO order.
279 if (deletion_queue_.size() > max_graveyard_size_) {
280 uint32 oldest = deletion_queue_.front();
281 deletion_queue_.pop_front();
282 DeleteSourceInfo(oldest);
283 }
284 }
285
EraseFromDeletionQueue(uint32 source_id)286 void PassiveLogCollector::SourceTracker::EraseFromDeletionQueue(
287 uint32 source_id) {
288 DeletionQueue::iterator it =
289 std::remove(deletion_queue_.begin(), deletion_queue_.end(),
290 source_id);
291 CHECK(it != deletion_queue_.end());
292 deletion_queue_.erase(it);
293 }
294
AdjustReferenceCountForSource(int offset,uint32 source_id)295 void PassiveLogCollector::SourceTracker::AdjustReferenceCountForSource(
296 int offset, uint32 source_id) {
297 DCHECK(offset == -1 || offset == 1) << "invalid offset: " << offset;
298
299 // In general it is invalid to call AdjustReferenceCountForSource() on
300 // source that doesn't exist. However, it is possible that if
301 // SourceTracker::Clear() was previously called this can happen.
302 SourceIDToInfoMap::iterator it = sources_.find(source_id);
303 if (it == sources_.end()) {
304 LOG(WARNING) << "Released a reference to nonexistent source.";
305 return;
306 }
307
308 SourceInfo& info = it->second;
309 DCHECK_GE(info.reference_count, 0);
310 info.reference_count += offset;
311
312 bool released_unmatched_reference = info.reference_count < 0;
313 if (released_unmatched_reference) {
314 // In general this shouldn't happen, however it is possible to reach this
315 // state if SourceTracker::Clear() was called earlier.
316 LOG(WARNING) << "Released unmatched reference count.";
317 info.reference_count = 0;
318 }
319
320 if (!info.is_alive) {
321 if (info.reference_count == 1 && offset == 1) {
322 // If we just added a reference to a dead source that had no references,
323 // it must have been in the deletion queue, so remove it from the queue.
324 EraseFromDeletionQueue(source_id);
325 } else if (info.reference_count == 0) {
326 if (released_unmatched_reference)
327 EraseFromDeletionQueue(source_id);
328 // If we just released the final reference to a dead source, go ahead
329 // and delete it right away.
330 DeleteSourceInfo(source_id);
331 }
332 }
333 }
334
AddReferenceToSourceDependency(const net::NetLog::Source & source,SourceInfo * info)335 void PassiveLogCollector::SourceTracker::AddReferenceToSourceDependency(
336 const net::NetLog::Source& source, SourceInfo* info) {
337 // Find the tracker which should be holding |source|.
338 DCHECK(parent_);
339 DCHECK_NE(source.type, net::NetLog::SOURCE_NONE);
340 SourceTracker* tracker = static_cast<SourceTracker*>(
341 parent_->GetTrackerForSourceType(source.type));
342 DCHECK(tracker);
343
344 // Tell the owning tracker to increment the reference count of |source|.
345 tracker->AdjustReferenceCountForSource(1, source.id);
346
347 // Make a note to release this reference once |info| is destroyed.
348 info->dependencies.push_back(source);
349 }
350
ReleaseAllReferencesToDependencies(SourceInfo * info)351 void PassiveLogCollector::SourceTracker::ReleaseAllReferencesToDependencies(
352 SourceInfo* info) {
353 // Release all references |info| was holding to other sources.
354 for (SourceDependencyList::const_iterator it = info->dependencies.begin();
355 it != info->dependencies.end(); ++it) {
356 const net::NetLog::Source& source = *it;
357
358 // Find the tracker which should be holding |source|.
359 DCHECK(parent_);
360 DCHECK_NE(source.type, net::NetLog::SOURCE_NONE);
361 SourceTracker* tracker = static_cast<SourceTracker*>(
362 parent_->GetTrackerForSourceType(source.type));
363 DCHECK(tracker);
364
365 // Tell the owning tracker to decrement the reference count of |source|.
366 tracker->AdjustReferenceCountForSource(-1, source.id);
367 }
368
369 info->dependencies.clear();
370 }
371
372 //----------------------------------------------------------------------------
373 // ConnectJobTracker
374 //----------------------------------------------------------------------------
375
376 const size_t PassiveLogCollector::ConnectJobTracker::kMaxNumSources = 100;
377 const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 15;
378
ConnectJobTracker(PassiveLogCollector * parent)379 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker(
380 PassiveLogCollector* parent)
381 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) {
382 }
383
384 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)385 PassiveLogCollector::ConnectJobTracker::DoAddEntry(
386 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
387 AddEntryToSourceInfo(entry, out_info);
388
389 if (entry.type == net::NetLog::TYPE_CONNECT_JOB_SET_SOCKET) {
390 const net::NetLog::Source& source_dependency =
391 static_cast<net::NetLogSourceParameter*>(entry.params.get())->value();
392 AddReferenceToSourceDependency(source_dependency, out_info);
393 }
394
395 // If this is the end of the connect job, move the source to the graveyard.
396 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB &&
397 entry.phase == net::NetLog::PHASE_END) {
398 return ACTION_MOVE_TO_GRAVEYARD;
399 }
400
401 return ACTION_NONE;
402 }
403
404 //----------------------------------------------------------------------------
405 // SocketTracker
406 //----------------------------------------------------------------------------
407
408 const size_t PassiveLogCollector::SocketTracker::kMaxNumSources = 200;
409 const size_t PassiveLogCollector::SocketTracker::kMaxGraveyardSize = 15;
410
SocketTracker()411 PassiveLogCollector::SocketTracker::SocketTracker()
412 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
413 }
414
415 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)416 PassiveLogCollector::SocketTracker::DoAddEntry(const ChromeNetLog::Entry& entry,
417 SourceInfo* out_info) {
418 // TODO(eroman): aggregate the byte counts once truncation starts to happen,
419 // to summarize transaction read/writes for each SOCKET_IN_USE
420 // section.
421 if (entry.type == net::NetLog::TYPE_SOCKET_BYTES_SENT ||
422 entry.type == net::NetLog::TYPE_SOCKET_BYTES_RECEIVED) {
423 return ACTION_NONE;
424 }
425
426 AddEntryToSourceInfo(entry, out_info);
427
428 if (entry.type == net::NetLog::TYPE_SOCKET_ALIVE &&
429 entry.phase == net::NetLog::PHASE_END) {
430 return ACTION_MOVE_TO_GRAVEYARD;
431 }
432
433 return ACTION_NONE;
434 }
435
436 //----------------------------------------------------------------------------
437 // RequestTracker
438 //----------------------------------------------------------------------------
439
440 const size_t PassiveLogCollector::RequestTracker::kMaxNumSources = 100;
441 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25;
442
RequestTracker(PassiveLogCollector * parent)443 PassiveLogCollector::RequestTracker::RequestTracker(PassiveLogCollector* parent)
444 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) {
445 }
446
447 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)448 PassiveLogCollector::RequestTracker::DoAddEntry(
449 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
450 if (entry.type == net::NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB) {
451 const net::NetLog::Source& source_dependency =
452 static_cast<net::NetLogSourceParameter*>(entry.params.get())->value();
453 AddReferenceToSourceDependency(source_dependency, out_info);
454 }
455
456 AddEntryToSourceInfo(entry, out_info);
457
458 // If the request has ended, move it to the graveyard.
459 if (entry.type == net::NetLog::TYPE_REQUEST_ALIVE &&
460 entry.phase == net::NetLog::PHASE_END) {
461 if (StartsWithASCII(out_info->GetURL(), "chrome://", false)) {
462 // Avoid sending "chrome://" requests to the graveyard, since it just
463 // adds to clutter.
464 return ACTION_DELETE;
465 }
466 return ACTION_MOVE_TO_GRAVEYARD;
467 }
468
469 return ACTION_NONE;
470 }
471
472 //----------------------------------------------------------------------------
473 // InitProxyResolverTracker
474 //----------------------------------------------------------------------------
475
476 const size_t PassiveLogCollector::InitProxyResolverTracker::kMaxNumSources = 20;
477 const size_t PassiveLogCollector::InitProxyResolverTracker::kMaxGraveyardSize =
478 3;
479
InitProxyResolverTracker()480 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker()
481 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
482 }
483
484 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)485 PassiveLogCollector::InitProxyResolverTracker::DoAddEntry(
486 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
487 AddEntryToSourceInfo(entry, out_info);
488 if (entry.type == net::NetLog::TYPE_INIT_PROXY_RESOLVER &&
489 entry.phase == net::NetLog::PHASE_END) {
490 return ACTION_MOVE_TO_GRAVEYARD;
491 } else {
492 return ACTION_NONE;
493 }
494 }
495
496 //----------------------------------------------------------------------------
497 // SpdySessionTracker
498 //----------------------------------------------------------------------------
499
500 const size_t PassiveLogCollector::SpdySessionTracker::kMaxNumSources = 50;
501 const size_t PassiveLogCollector::SpdySessionTracker::kMaxGraveyardSize = 10;
502
SpdySessionTracker()503 PassiveLogCollector::SpdySessionTracker::SpdySessionTracker()
504 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
505 }
506
507 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)508 PassiveLogCollector::SpdySessionTracker::DoAddEntry(
509 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
510 AddEntryToSourceInfo(entry, out_info);
511 if (entry.type == net::NetLog::TYPE_SPDY_SESSION &&
512 entry.phase == net::NetLog::PHASE_END) {
513 return ACTION_MOVE_TO_GRAVEYARD;
514 } else {
515 return ACTION_NONE;
516 }
517 }
518
519 //----------------------------------------------------------------------------
520 // DNSRequestTracker
521 //----------------------------------------------------------------------------
522
523 const size_t PassiveLogCollector::DNSRequestTracker::kMaxNumSources = 200;
524 const size_t PassiveLogCollector::DNSRequestTracker::kMaxGraveyardSize = 20;
525
DNSRequestTracker()526 PassiveLogCollector::DNSRequestTracker::DNSRequestTracker()
527 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
528 }
529
530 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)531 PassiveLogCollector::DNSRequestTracker::DoAddEntry(
532 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
533 AddEntryToSourceInfo(entry, out_info);
534 if (entry.type == net::NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST &&
535 entry.phase == net::NetLog::PHASE_END) {
536 return ACTION_MOVE_TO_GRAVEYARD;
537 } else {
538 return ACTION_NONE;
539 }
540 }
541
542 //----------------------------------------------------------------------------
543 // DNSJobTracker
544 //----------------------------------------------------------------------------
545
546 const size_t PassiveLogCollector::DNSJobTracker::kMaxNumSources = 100;
547 const size_t PassiveLogCollector::DNSJobTracker::kMaxGraveyardSize = 15;
548
DNSJobTracker()549 PassiveLogCollector::DNSJobTracker::DNSJobTracker()
550 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
551 }
552
553 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)554 PassiveLogCollector::DNSJobTracker::DoAddEntry(const ChromeNetLog::Entry& entry,
555 SourceInfo* out_info) {
556 AddEntryToSourceInfo(entry, out_info);
557 if (entry.type == net::NetLog::TYPE_HOST_RESOLVER_IMPL_JOB &&
558 entry.phase == net::NetLog::PHASE_END) {
559 return ACTION_MOVE_TO_GRAVEYARD;
560 } else {
561 return ACTION_NONE;
562 }
563 }
564
565 //----------------------------------------------------------------------------
566 // DiskCacheEntryTracker
567 //----------------------------------------------------------------------------
568
569 const size_t PassiveLogCollector::DiskCacheEntryTracker::kMaxNumSources = 100;
570 const size_t PassiveLogCollector::DiskCacheEntryTracker::kMaxGraveyardSize = 25;
571
DiskCacheEntryTracker()572 PassiveLogCollector::DiskCacheEntryTracker::DiskCacheEntryTracker()
573 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
574 }
575
576 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)577 PassiveLogCollector::DiskCacheEntryTracker::DoAddEntry(
578 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
579 AddEntryToSourceInfo(entry, out_info);
580
581 // If the request has ended, move it to the graveyard.
582 if (entry.type == net::NetLog::TYPE_DISK_CACHE_ENTRY_IMPL &&
583 entry.phase == net::NetLog::PHASE_END) {
584 return ACTION_MOVE_TO_GRAVEYARD;
585 }
586
587 return ACTION_NONE;
588 }
589
590 //----------------------------------------------------------------------------
591 // MemCacheEntryTracker
592 //----------------------------------------------------------------------------
593
594 const size_t PassiveLogCollector::MemCacheEntryTracker::kMaxNumSources = 100;
595 const size_t PassiveLogCollector::MemCacheEntryTracker::kMaxGraveyardSize = 25;
596
MemCacheEntryTracker()597 PassiveLogCollector::MemCacheEntryTracker::MemCacheEntryTracker()
598 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
599 }
600
601 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)602 PassiveLogCollector::MemCacheEntryTracker::DoAddEntry(
603 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
604 AddEntryToSourceInfo(entry, out_info);
605
606 // If the request has ended, move it to the graveyard.
607 if (entry.type == net::NetLog::TYPE_DISK_CACHE_MEM_ENTRY_IMPL &&
608 entry.phase == net::NetLog::PHASE_END) {
609 return ACTION_MOVE_TO_GRAVEYARD;
610 }
611
612 return ACTION_NONE;
613 }
614
615 //----------------------------------------------------------------------------
616 // HttpStreamJobTracker
617 //----------------------------------------------------------------------------
618
619 const size_t PassiveLogCollector::HttpStreamJobTracker::kMaxNumSources = 100;
620 const size_t PassiveLogCollector::HttpStreamJobTracker::kMaxGraveyardSize = 25;
621
HttpStreamJobTracker(PassiveLogCollector * parent)622 PassiveLogCollector::HttpStreamJobTracker::HttpStreamJobTracker(
623 PassiveLogCollector* parent)
624 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) {
625 }
626
627 PassiveLogCollector::SourceTracker::Action
DoAddEntry(const ChromeNetLog::Entry & entry,SourceInfo * out_info)628 PassiveLogCollector::HttpStreamJobTracker::DoAddEntry(
629 const ChromeNetLog::Entry& entry, SourceInfo* out_info) {
630 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB ||
631 entry.type == net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET) {
632 const net::NetLog::Source& source_dependency =
633 static_cast<net::NetLogSourceParameter*>(entry.params.get())->value();
634 AddReferenceToSourceDependency(source_dependency, out_info);
635 }
636
637 AddEntryToSourceInfo(entry, out_info);
638
639 // If the request has ended, move it to the graveyard.
640 if (entry.type == net::NetLog::TYPE_HTTP_STREAM_JOB &&
641 entry.phase == net::NetLog::PHASE_END) {
642 return ACTION_MOVE_TO_GRAVEYARD;
643 }
644
645 return ACTION_NONE;
646 }
647