• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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