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 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. 32 bool SortByOrderComparator(const ChromeNetLog::Entry& a, 33 const ChromeNetLog::Entry& b) { 34 return a.order < b.order; 35 } 36 37 } // namespace 38 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 46 PassiveLogCollector::SourceInfo::~SourceInfo() {} 47 48 //---------------------------------------------------------------------------- 49 // PassiveLogCollector 50 //---------------------------------------------------------------------------- 51 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 81 PassiveLogCollector::~PassiveLogCollector() { 82 } 83 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 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* 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 114 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 128 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 153 PassiveLogCollector::GlobalSourceTracker::GlobalSourceTracker() {} 154 PassiveLogCollector::GlobalSourceTracker::~GlobalSourceTracker() {} 155 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 164 void PassiveLogCollector::GlobalSourceTracker::Clear() { 165 entries_.clear(); 166 } 167 168 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 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 186 PassiveLogCollector::SourceTracker::~SourceTracker() {} 187 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 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 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 255 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 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 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 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 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 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 379 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker( 380 PassiveLogCollector* parent) 381 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) { 382 } 383 384 PassiveLogCollector::SourceTracker::Action 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 411 PassiveLogCollector::SocketTracker::SocketTracker() 412 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 413 } 414 415 PassiveLogCollector::SourceTracker::Action 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 443 PassiveLogCollector::RequestTracker::RequestTracker(PassiveLogCollector* parent) 444 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) { 445 } 446 447 PassiveLogCollector::SourceTracker::Action 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 480 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() 481 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 482 } 483 484 PassiveLogCollector::SourceTracker::Action 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 503 PassiveLogCollector::SpdySessionTracker::SpdySessionTracker() 504 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 505 } 506 507 PassiveLogCollector::SourceTracker::Action 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 526 PassiveLogCollector::DNSRequestTracker::DNSRequestTracker() 527 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 528 } 529 530 PassiveLogCollector::SourceTracker::Action 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 549 PassiveLogCollector::DNSJobTracker::DNSJobTracker() 550 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 551 } 552 553 PassiveLogCollector::SourceTracker::Action 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 572 PassiveLogCollector::DiskCacheEntryTracker::DiskCacheEntryTracker() 573 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 574 } 575 576 PassiveLogCollector::SourceTracker::Action 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 597 PassiveLogCollector::MemCacheEntryTracker::MemCacheEntryTracker() 598 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { 599 } 600 601 PassiveLogCollector::SourceTracker::Action 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 622 PassiveLogCollector::HttpStreamJobTracker::HttpStreamJobTracker( 623 PassiveLogCollector* parent) 624 : SourceTracker(kMaxNumSources, kMaxGraveyardSize, parent) { 625 } 626 627 PassiveLogCollector::SourceTracker::Action 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