| OLD | NEW |
| 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 "base/format_macros.h" |
| 10 #include "chrome/browser/chrome_thread.h" | 11 #include "chrome/browser/chrome_thread.h" |
| 11 | 12 |
| 12 namespace { | 13 namespace { |
| 13 const size_t kMaxNumEntriesPerLog = 50; | 14 const size_t kMaxNumEntriesPerLog = 50; |
| 14 const size_t kMaxConnectJobGraveyardSize = 3; | 15 const size_t kMaxConnectJobGraveyardSize = 3; |
| 15 const size_t kMaxRequestGraveyardSize = 25; | 16 const size_t kMaxRequestGraveyardSize = 25; |
| 16 const size_t kMaxLiveRequests = 200; | 17 const size_t kMaxLiveRequests = 200; |
| 17 | 18 |
| 18 // Sort function on source ID. | 19 // Sort function on source ID. |
| 19 bool OrderBySourceID(const PassiveLogCollector::RequestInfo& a, | 20 bool OrderBySourceID(const PassiveLogCollector::RequestInfo& a, |
| 20 const PassiveLogCollector::RequestInfo& b) { | 21 const PassiveLogCollector::RequestInfo& b) { |
| 21 return a.entries[0].source.id < b.entries[0].source.id; | 22 return a.source_id < b.source_id; |
| 22 } | 23 } |
| 23 | 24 |
| 24 void AddEntryToRequestInfo(const PassiveLogCollector::Entry& entry, | 25 void AddEntryToRequestInfo(const PassiveLogCollector::Entry& entry, |
| 25 bool is_unbounded, | 26 bool is_unbounded, |
| 26 PassiveLogCollector::RequestInfo* out_info) { | 27 PassiveLogCollector::RequestInfo* out_info) { |
| 27 // Start dropping new entries when the log has gotten too big. | 28 // Start dropping new entries when the log has gotten too big. |
| 28 if (out_info->entries.size() + 1 <= kMaxNumEntriesPerLog || is_unbounded) { | 29 if (out_info->entries.size() + 1 <= kMaxNumEntriesPerLog || is_unbounded) { |
| 29 out_info->entries.push_back(entry); | 30 out_info->entries.push_back(entry); |
| 30 } else { | 31 } else { |
| 31 out_info->num_entries_truncated += 1; | 32 out_info->num_entries_truncated += 1; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 49 out->insert(out->end(), entries.begin(), entries.end()); | 50 out->insert(out->end(), entries.begin(), entries.end()); |
| 50 } | 51 } |
| 51 } | 52 } |
| 52 | 53 |
| 53 // Comparator to sort entries by their |order| property, ascending. | 54 // Comparator to sort entries by their |order| property, ascending. |
| 54 bool SortByOrderComparator(const PassiveLogCollector::Entry& a, | 55 bool SortByOrderComparator(const PassiveLogCollector::Entry& a, |
| 55 const PassiveLogCollector::Entry& b) { | 56 const PassiveLogCollector::Entry& b) { |
| 56 return a.order < b.order; | 57 return a.order < b.order; |
| 57 } | 58 } |
| 58 | 59 |
| 60 void SetSubordinateSource(PassiveLogCollector::RequestInfo* info, |
| 61 const PassiveLogCollector::Entry& entry) { |
| 62 info->subordinate_source.id = static_cast<net::NetLogIntegerParameter*>( |
| 63 entry.extra_parameters.get())->value(); |
| 64 switch (entry.type) { |
| 65 case net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID: |
| 66 info->subordinate_source.type = net::NetLog::SOURCE_CONNECT_JOB; |
| 67 break; |
| 68 case net::NetLog::TYPE_SOCKET_POOL_SOCKET_ID: |
| 69 info->subordinate_source.type = net::NetLog::SOURCE_SOCKET; |
| 70 break; |
| 71 default: |
| 72 NOTREACHED(); |
| 73 break; |
| 74 } |
| 75 } |
| 76 |
| 59 } // namespace | 77 } // namespace |
| 60 | 78 |
| 61 //---------------------------------------------------------------------------- | 79 //---------------------------------------------------------------------------- |
| 62 // PassiveLogCollector | 80 // PassiveLogCollector |
| 63 //---------------------------------------------------------------------------- | 81 //---------------------------------------------------------------------------- |
| 64 | 82 |
| 65 PassiveLogCollector::PassiveLogCollector() | 83 PassiveLogCollector::PassiveLogCollector() |
| 66 : url_request_tracker_(&connect_job_tracker_), | 84 : url_request_tracker_(&connect_job_tracker_, &socket_tracker_), |
| 67 socket_stream_tracker_(&connect_job_tracker_), | 85 socket_stream_tracker_(&connect_job_tracker_, &socket_tracker_), |
| 68 num_events_seen_(0) { | 86 num_events_seen_(0) { |
| 69 } | 87 } |
| 70 | 88 |
| 71 PassiveLogCollector::~PassiveLogCollector() { | 89 PassiveLogCollector::~PassiveLogCollector() { |
| 72 } | 90 } |
| 73 | 91 |
| 74 void PassiveLogCollector::OnAddEntry( | 92 void PassiveLogCollector::OnAddEntry( |
| 75 net::NetLog::EventType type, | 93 net::NetLog::EventType type, |
| 76 const base::TimeTicks& time, | 94 const base::TimeTicks& time, |
| 77 const net::NetLog::Source& source, | 95 const net::NetLog::Source& source, |
| 78 net::NetLog::EventPhase phase, | 96 net::NetLog::EventPhase phase, |
| 79 net::NetLog::EventParameters* extra_parameters) { | 97 net::NetLog::EventParameters* extra_parameters) { |
| 80 // Package the parameters into a single struct for convenience. | 98 // Package the parameters into a single struct for convenience. |
| 81 Entry entry(num_events_seen_++, type, time, source, phase, extra_parameters); | 99 Entry entry(num_events_seen_++, type, time, source, phase, extra_parameters); |
| 82 | 100 |
| 83 switch (entry.source.type) { | 101 switch (entry.source.type) { |
| 84 case net::NetLog::SOURCE_URL_REQUEST: | 102 case net::NetLog::SOURCE_URL_REQUEST: |
| 85 url_request_tracker_.OnAddEntry(entry); | 103 url_request_tracker_.OnAddEntry(entry); |
| 86 break; | 104 break; |
| 87 case net::NetLog::SOURCE_SOCKET_STREAM: | 105 case net::NetLog::SOURCE_SOCKET_STREAM: |
| 88 socket_stream_tracker_.OnAddEntry(entry); | 106 socket_stream_tracker_.OnAddEntry(entry); |
| 89 break; | 107 break; |
| 90 case net::NetLog::SOURCE_CONNECT_JOB: | 108 case net::NetLog::SOURCE_CONNECT_JOB: |
| 91 connect_job_tracker_.OnAddEntry(entry); | 109 connect_job_tracker_.OnAddEntry(entry); |
| 92 break; | 110 break; |
| 111 case net::NetLog::SOURCE_SOCKET: |
| 112 socket_tracker_.OnAddEntry(entry); |
| 113 break; |
| 93 case net::NetLog::SOURCE_INIT_PROXY_RESOLVER: | 114 case net::NetLog::SOURCE_INIT_PROXY_RESOLVER: |
| 94 init_proxy_resolver_tracker_.OnAddEntry(entry); | 115 init_proxy_resolver_tracker_.OnAddEntry(entry); |
| 95 break; | 116 break; |
| 96 default: | 117 default: |
| 97 // Drop all other logged events. | 118 // Drop all other logged events. |
| 98 break; | 119 break; |
| 99 } | 120 } |
| 100 } | 121 } |
| 101 | 122 |
| 102 void PassiveLogCollector::Clear() { | 123 void PassiveLogCollector::Clear() { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 127 | 148 |
| 128 PassiveLogCollector::RequestTrackerBase::RequestTrackerBase( | 149 PassiveLogCollector::RequestTrackerBase::RequestTrackerBase( |
| 129 size_t max_graveyard_size) | 150 size_t max_graveyard_size) |
| 130 : max_graveyard_size_(max_graveyard_size), | 151 : max_graveyard_size_(max_graveyard_size), |
| 131 next_graveyard_index_(0), | 152 next_graveyard_index_(0), |
| 132 is_unbounded_(false) { | 153 is_unbounded_(false) { |
| 133 } | 154 } |
| 134 | 155 |
| 135 void PassiveLogCollector::RequestTrackerBase::OnAddEntry(const Entry& entry) { | 156 void PassiveLogCollector::RequestTrackerBase::OnAddEntry(const Entry& entry) { |
| 136 RequestInfo& info = live_requests_[entry.source.id]; | 157 RequestInfo& info = live_requests_[entry.source.id]; |
| 158 info.source_id = entry.source.id; // In case this is a new entry. |
| 137 Action result = DoAddEntry(entry, &info); | 159 Action result = DoAddEntry(entry, &info); |
| 138 | 160 |
| 139 switch (result) { | 161 switch (result) { |
| 140 case ACTION_MOVE_TO_GRAVEYARD: | 162 case ACTION_MOVE_TO_GRAVEYARD: |
| 141 InsertIntoGraveyard(info); | 163 InsertIntoGraveyard(info); |
| 142 // (fall-through) | 164 // (fall-through) |
| 143 case ACTION_DELETE: | 165 case ACTION_DELETE: |
| 144 RemoveFromLiveRequests(entry.source.id); | 166 RemoveFromLiveRequests(entry.source.id); |
| 145 break; | 167 break; |
| 146 default: | 168 default: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 158 | 180 |
| 159 PassiveLogCollector::RequestInfoList | 181 PassiveLogCollector::RequestInfoList |
| 160 PassiveLogCollector::RequestTrackerBase::GetLiveRequests() const { | 182 PassiveLogCollector::RequestTrackerBase::GetLiveRequests() const { |
| 161 RequestInfoList list; | 183 RequestInfoList list; |
| 162 | 184 |
| 163 // Copy all of the live requests into the vector. | 185 // Copy all of the live requests into the vector. |
| 164 for (SourceIDToInfoMap::const_iterator it = live_requests_.begin(); | 186 for (SourceIDToInfoMap::const_iterator it = live_requests_.begin(); |
| 165 it != live_requests_.end(); | 187 it != live_requests_.end(); |
| 166 ++it) { | 188 ++it) { |
| 167 list.push_back(it->second); | 189 list.push_back(it->second); |
| 190 // We pass the copy (made by the list insert), so changes made in |
| 191 // OnLiveRequest are only seen by our caller. |
| 192 OnLiveRequest(&list.back()); |
| 193 std::sort(list.back().entries.begin(), list.back().entries.end(), |
| 194 SortByOrderComparator); |
| 168 } | 195 } |
| 169 | 196 |
| 170 std::sort(list.begin(), list.end(), OrderBySourceID); | 197 std::sort(list.begin(), list.end(), OrderBySourceID); |
| 171 return list; | 198 return list; |
| 172 } | 199 } |
| 173 | 200 |
| 174 void PassiveLogCollector::RequestTrackerBase::ClearRecentlyDeceased() { | 201 void PassiveLogCollector::RequestTrackerBase::ClearRecentlyDeceased() { |
| 175 next_graveyard_index_ = 0; | 202 next_graveyard_index_ = 0; |
| 176 graveyard_.clear(); | 203 graveyard_.clear(); |
| 177 } | 204 } |
| 178 | 205 |
| 179 // Returns a list of recently completed Requests. | 206 // Returns a list of recently completed Requests. |
| 180 PassiveLogCollector::RequestInfoList | 207 PassiveLogCollector::RequestInfoList |
| 181 PassiveLogCollector::RequestTrackerBase::GetRecentlyDeceased() const { | 208 PassiveLogCollector::RequestTrackerBase::GetRecentlyDeceased() const { |
| 182 RequestInfoList list; | 209 RequestInfoList list; |
| 183 | 210 |
| 184 // Copy the items from |graveyard_| (our circular queue of recently | 211 // Copy the items from |graveyard_| (our circular queue of recently |
| 185 // deceased request infos) into a vector, ordered from oldest to newest. | 212 // deceased request infos) into a vector, ordered from oldest to newest. |
| 186 for (size_t i = 0; i < graveyard_.size(); ++i) { | 213 for (size_t i = 0; i < graveyard_.size(); ++i) { |
| 187 size_t index = (next_graveyard_index_ + i) % graveyard_.size(); | 214 size_t index = (next_graveyard_index_ + i) % graveyard_.size(); |
| 188 list.push_back(graveyard_[index]); | 215 list.push_back(graveyard_[index]); |
| 189 } | 216 } |
| 190 return list; | 217 return list; |
| 191 } | 218 } |
| 192 | 219 |
| 193 const PassiveLogCollector::RequestInfo* | 220 PassiveLogCollector::RequestInfo* |
| 194 PassiveLogCollector::RequestTrackerBase::GetRequestInfoFromGraveyard( | 221 PassiveLogCollector::RequestTrackerBase::GetRequestInfo(uint32 source_id) { |
| 195 int source_id) const { | 222 // Look for it in the live requests first. |
| 196 // Scan through the graveyard to find an entry for |source_id|. | 223 SourceIDToInfoMap::iterator it = live_requests_.find(source_id); |
| 224 if (it != live_requests_.end()) |
| 225 return &(it->second); |
| 226 |
| 227 // Otherwise, scan through the graveyard to find an entry for |source_id|. |
| 197 for (size_t i = 0; i < graveyard_.size(); ++i) { | 228 for (size_t i = 0; i < graveyard_.size(); ++i) { |
| 198 if (graveyard_[i].entries[0].source.id == source_id) { | 229 if (graveyard_[i].source_id == source_id) { |
| 199 return &graveyard_[i]; | 230 return &graveyard_[i]; |
| 200 } | 231 } |
| 201 } | 232 } |
| 202 return NULL; | 233 return NULL; |
| 203 } | 234 } |
| 204 | 235 |
| 205 void PassiveLogCollector::RequestTrackerBase::RemoveFromLiveRequests( | 236 void PassiveLogCollector::RequestTrackerBase::RemoveFromLiveRequests( |
| 206 int source_id) { | 237 uint32 source_id) { |
| 207 // Remove from |live_requests_|. | 238 // Remove from |live_requests_|. |
| 208 SourceIDToInfoMap::iterator it = live_requests_.find(source_id); | 239 SourceIDToInfoMap::iterator it = live_requests_.find(source_id); |
| 209 // TODO(eroman): Shouldn't have this 'if', is it actually really necessary? | 240 // TODO(eroman): Shouldn't have this 'if', is it actually really necessary? |
| 210 if (it != live_requests_.end()) | 241 if (it != live_requests_.end()) |
| 211 live_requests_.erase(it); | 242 live_requests_.erase(it); |
| 212 } | 243 } |
| 213 | 244 |
| 214 void PassiveLogCollector::RequestTrackerBase::SetUnbounded( | 245 void PassiveLogCollector::RequestTrackerBase::SetUnbounded( |
| 215 bool unbounded) { | 246 bool unbounded) { |
| 216 // No change. | 247 // No change. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 // At maximum capacity, overwite the oldest entry. | 284 // At maximum capacity, overwite the oldest entry. |
| 254 graveyard_[next_graveyard_index_] = info; | 285 graveyard_[next_graveyard_index_] = info; |
| 255 } | 286 } |
| 256 next_graveyard_index_ = (next_graveyard_index_ + 1) % max_graveyard_size_; | 287 next_graveyard_index_ = (next_graveyard_index_ + 1) % max_graveyard_size_; |
| 257 } | 288 } |
| 258 | 289 |
| 259 //---------------------------------------------------------------------------- | 290 //---------------------------------------------------------------------------- |
| 260 // ConnectJobTracker | 291 // ConnectJobTracker |
| 261 //---------------------------------------------------------------------------- | 292 //---------------------------------------------------------------------------- |
| 262 | 293 |
| 263 const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 3; | 294 const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 15; |
| 264 | 295 |
| 265 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker() | 296 PassiveLogCollector::ConnectJobTracker::ConnectJobTracker() |
| 266 : RequestTrackerBase(kMaxGraveyardSize) { | 297 : RequestTrackerBase(kMaxGraveyardSize) { |
| 267 } | 298 } |
| 268 | 299 |
| 269 PassiveLogCollector::RequestTrackerBase::Action | 300 PassiveLogCollector::RequestTrackerBase::Action |
| 270 PassiveLogCollector::ConnectJobTracker::DoAddEntry(const Entry& entry, | 301 PassiveLogCollector::ConnectJobTracker::DoAddEntry(const Entry& entry, |
| 271 RequestInfo* out_info) { | 302 RequestInfo* out_info) { |
| 272 // Save the entry (possibly truncating). | |
| 273 AddEntryToRequestInfo(entry, is_unbounded(), out_info); | 303 AddEntryToRequestInfo(entry, is_unbounded(), out_info); |
| 274 | 304 |
| 305 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) { |
| 306 SetSubordinateSource(out_info, entry); |
| 307 } |
| 308 |
| 275 // If this is the end of the connect job, move the request to the graveyard. | 309 // If this is the end of the connect job, move the request to the graveyard. |
| 276 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB && | 310 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB && |
| 277 entry.phase == net::NetLog::PHASE_END) { | 311 entry.phase == net::NetLog::PHASE_END) { |
| 278 return ACTION_MOVE_TO_GRAVEYARD; | 312 return ACTION_MOVE_TO_GRAVEYARD; |
| 279 } | 313 } |
| 280 | 314 |
| 281 return ACTION_NONE; | 315 return ACTION_NONE; |
| 282 } | 316 } |
| 283 | 317 |
| 318 void PassiveLogCollector::ConnectJobTracker::AppendLogEntries( |
| 319 RequestInfo* out_info, bool unbounded, uint32 connect_id) { |
| 320 RequestInfo* connect_info = GetRequestInfo(connect_id); |
| 321 if (!connect_info) { |
| 322 net::NetLogStringParameter* text = new net::NetLogStringParameter( |
| 323 StringPrintf("Used ConnectJob id=%u", connect_id)); |
| 324 Entry new_entry(0, net::NetLog::TYPE_TODO_STRING, base::TimeTicks(), |
| 325 net::NetLog::Source(net::NetLog::SOURCE_CONNECT_JOB, |
| 326 connect_id), |
| 327 net::NetLog::PHASE_NONE, text); |
| 328 AddEntryToRequestInfo(new_entry, unbounded, out_info); |
| 329 return; |
| 330 } |
| 331 |
| 332 AppendToRequestInfo(*connect_info, unbounded, out_info); |
| 333 std::sort(out_info->entries.begin(), out_info->entries.end(), |
| 334 &SortByOrderComparator); |
| 335 out_info->num_entries_truncated += connect_info->num_entries_truncated; |
| 336 |
| 337 if (connect_info->subordinate_source.is_valid()) |
| 338 AppendLogEntries(out_info, unbounded, connect_info->subordinate_source.id); |
| 339 } |
| 340 |
| 341 //---------------------------------------------------------------------------- |
| 342 // SocketTracker |
| 343 //---------------------------------------------------------------------------- |
| 344 |
| 345 const size_t PassiveLogCollector::SocketTracker::kMaxGraveyardSize = 15; |
| 346 |
| 347 PassiveLogCollector::SocketTracker::SocketTracker() |
| 348 : RequestTrackerBase(kMaxGraveyardSize) { |
| 349 } |
| 350 |
| 351 PassiveLogCollector::RequestTrackerBase::Action |
| 352 PassiveLogCollector::SocketTracker::DoAddEntry(const Entry& entry, |
| 353 RequestInfo* out_info) { |
| 354 int int_arg; |
| 355 switch (entry.type) { |
| 356 case net::NetLog::TYPE_SOCKET_BYTES_SENT: |
| 357 int_arg = static_cast<net::NetLogIntegerParameter*>( |
| 358 entry.extra_parameters.get())->value(); |
| 359 out_info->total_bytes_transmitted += int_arg; |
| 360 out_info->bytes_transmitted += int_arg; |
| 361 out_info->last_tx_rx_time = entry.time; |
| 362 out_info->last_tx_rx_position = entry.order; |
| 363 break; |
| 364 case net::NetLog::TYPE_SOCKET_BYTES_RECEIVED: |
| 365 int_arg = static_cast<net::NetLogIntegerParameter*>( |
| 366 entry.extra_parameters.get())->value(); |
| 367 out_info->total_bytes_received += int_arg; |
| 368 out_info->bytes_received += int_arg; |
| 369 out_info->last_tx_rx_time = entry.time; |
| 370 out_info->last_tx_rx_position = entry.order; |
| 371 break; |
| 372 case net::NetLog::TYPE_TCP_SOCKET_DONE: |
| 373 return ACTION_MOVE_TO_GRAVEYARD; |
| 374 default: |
| 375 AddEntryToRequestInfo(entry, is_unbounded(), out_info); |
| 376 break; |
| 377 } |
| 378 return ACTION_NONE; |
| 379 } |
| 380 |
| 381 void PassiveLogCollector::SocketTracker::AppendLogEntries( |
| 382 RequestInfo* out_info, bool unbounded, uint32 socket_id, bool clear) { |
| 383 RequestInfo* socket_info = GetRequestInfo(socket_id); |
| 384 if (!socket_info) { |
| 385 net::NetLogStringParameter* text = new net::NetLogStringParameter( |
| 386 StringPrintf("Used Socket id=%u.", socket_id)); |
| 387 Entry new_entry(0, net::NetLog::TYPE_TODO_STRING, base::TimeTicks(), |
| 388 net::NetLog::Source(net::NetLog::SOURCE_SOCKET, socket_id), |
| 389 net::NetLog::PHASE_NONE, text); |
| 390 AddEntryToRequestInfo(new_entry, unbounded, out_info); |
| 391 return; |
| 392 } |
| 393 |
| 394 AppendToRequestInfo(*socket_info, unbounded, out_info); |
| 395 out_info->num_entries_truncated += socket_info->num_entries_truncated; |
| 396 |
| 397 // Synthesize a log entry for bytes sent and received. |
| 398 if (socket_info->bytes_transmitted > 0 || socket_info->bytes_received > 0) { |
| 399 net::NetLogStringParameter* text = new net::NetLogStringParameter( |
| 400 StringPrintf("Tx/Rx: %"PRIu64"/%"PRIu64" [%"PRIu64"/%"PRIu64 |
| 401 " total on socket] (Bytes)", |
| 402 socket_info->bytes_transmitted, |
| 403 socket_info->bytes_received, |
| 404 socket_info->total_bytes_transmitted, |
| 405 socket_info->total_bytes_received)); |
| 406 Entry new_entry(socket_info->last_tx_rx_position, |
| 407 net::NetLog::TYPE_TODO_STRING, |
| 408 socket_info->last_tx_rx_time, |
| 409 net::NetLog::Source(net::NetLog::SOURCE_SOCKET, socket_id), |
| 410 net::NetLog::PHASE_NONE, |
| 411 text); |
| 412 AddEntryToRequestInfo(new_entry, unbounded, out_info); |
| 413 } |
| 414 std::sort(out_info->entries.begin(), out_info->entries.end(), |
| 415 &SortByOrderComparator); |
| 416 |
| 417 if (clear) |
| 418 ClearInfo(socket_info); |
| 419 } |
| 420 |
| 421 void PassiveLogCollector::SocketTracker::ClearInfo(RequestInfo* info) { |
| 422 info->entries.clear(); |
| 423 info->num_entries_truncated = 0; |
| 424 info->bytes_transmitted = 0; |
| 425 info->bytes_received = 0; |
| 426 info->last_tx_rx_position = 0; |
| 427 info->last_tx_rx_time = base::TimeTicks(); |
| 428 } |
| 429 |
| 284 //---------------------------------------------------------------------------- | 430 //---------------------------------------------------------------------------- |
| 285 // RequestTracker | 431 // RequestTracker |
| 286 //---------------------------------------------------------------------------- | 432 //---------------------------------------------------------------------------- |
| 287 | 433 |
| 288 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25; | 434 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25; |
| 289 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardURLSize = 1000; | 435 const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardURLSize = 1000; |
| 290 | 436 |
| 291 PassiveLogCollector::RequestTracker::RequestTracker( | 437 PassiveLogCollector::RequestTracker::RequestTracker( |
| 292 ConnectJobTracker* connect_job_tracker) | 438 ConnectJobTracker* connect_job_tracker, SocketTracker* socket_tracker) |
| 293 : RequestTrackerBase(kMaxGraveyardSize), | 439 : RequestTrackerBase(kMaxGraveyardSize), |
| 294 connect_job_tracker_(connect_job_tracker) { | 440 connect_job_tracker_(connect_job_tracker), |
| 441 socket_tracker_(socket_tracker) { |
| 295 } | 442 } |
| 296 | 443 |
| 297 PassiveLogCollector::RequestTrackerBase::Action | 444 PassiveLogCollector::RequestTrackerBase::Action |
| 298 PassiveLogCollector::RequestTracker::DoAddEntry(const Entry& entry, | 445 PassiveLogCollector::RequestTracker::DoAddEntry(const Entry& entry, |
| 299 RequestInfo* out_info) { | 446 RequestInfo* out_info) { |
| 447 // We expect up to three events with IDs. |
| 448 // - Begin SOCKET_POOL_CONNECT_JOB_ID: Means a ConnectJob was created for |
| 449 // this request. Including it for now, but the resulting socket may be |
| 450 // used for a different request. |
| 451 // - End SOCKET_POOL_CONNECT_JOB_ID: The named ConnectJob completed and |
| 452 // this request will be getting the socket from that request. |
| 453 // - SOCKET_POOL_SOCKET_ID: The given socket will be used for this request. |
| 454 // |
| 455 // The action to take when seeing these events depends on the current |
| 456 // content of the |subordinate_source| field: |
| 457 // |subordinate_source| is invalid (fresh state). |
| 458 // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|. |
| 459 // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID. |
| 460 // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|. |
| 461 // |subordinate_source| is a ConnectJob: |
| 462 // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|. |
| 463 // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID and |
| 464 // clear the |subordinate_source|. |
| 465 // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|. (The request was |
| 466 // assigned a new idle socket, after starting a ConnectJob.) |
| 467 // |subordinate_source| is a Socket: |
| 468 // First, integrate the subordinate socket source, then: |
| 469 // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|. |
| 470 // (Connection restarted with a new ConnectJob.) |
| 471 // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID and |
| 472 // clear the |subordinate_source|. (Connection restarted with a late bound |
| 473 // ConnectJob.) |
| 474 // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|. (Connection |
| 475 // restarted and got an idle socket.) |
| 476 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID || |
| 477 entry.type == net::NetLog::TYPE_SOCKET_POOL_SOCKET_ID) { |
| 300 | 478 |
| 301 if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) { | 479 if (out_info->subordinate_source.is_valid() && |
| 302 // If this was notification that a ConnectJob was bound to the request, | 480 out_info->subordinate_source.type == net::NetLog::SOURCE_SOCKET) |
| 303 // copy all the logged data for that ConnectJob. | 481 IntegrateSubordinateSource(out_info, true); |
| 304 AddConnectJobInfo(entry, out_info); | 482 |
| 305 } else { | 483 SetSubordinateSource(out_info, entry); |
| 306 // Otherwise just append this entry to the request info. | 484 |
| 307 AddEntryToRequestInfo(entry, is_unbounded(), out_info); | 485 if (entry.phase == net::NetLog::PHASE_END && |
| 486 entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) { |
| 487 IntegrateSubordinateSource(out_info, true); |
| 488 out_info->subordinate_source.id = net::NetLog::Source::kInvalidId; |
| 489 } |
| 308 } | 490 } |
| 309 | 491 |
| 492 AddEntryToRequestInfo(entry, is_unbounded(), out_info); |
| 493 |
| 310 // If this was the start of a URLRequest/SocketStream, extract the URL. | 494 // If this was the start of a URLRequest/SocketStream, extract the URL. |
| 311 // Note: we look at the first *two* entries, since the outer REQUEST_ALIVE | 495 // Note: we look at the first *two* entries, since the outer REQUEST_ALIVE |
| 312 // doesn't actually contain any data. | 496 // doesn't actually contain any data. |
| 313 if (out_info->url.empty() && out_info->entries.size() <= 2 && | 497 if (out_info->url.empty() && out_info->entries.size() <= 2 && |
| 314 entry.phase == net::NetLog::PHASE_BEGIN && entry.extra_parameters && | 498 entry.phase == net::NetLog::PHASE_BEGIN && entry.extra_parameters && |
| 315 (entry.type == net::NetLog::TYPE_URL_REQUEST_START || | 499 (entry.type == net::NetLog::TYPE_URL_REQUEST_START || |
| 316 entry.type == net::NetLog::TYPE_SOCKET_STREAM_CONNECT)) { | 500 entry.type == net::NetLog::TYPE_SOCKET_STREAM_CONNECT)) { |
| 317 out_info->url = static_cast<net::NetLogStringParameter*>( | 501 out_info->url = static_cast<net::NetLogStringParameter*>( |
| 318 entry.extra_parameters.get())->value(); | 502 entry.extra_parameters.get())->value(); |
| 319 } | 503 } |
| 320 | 504 |
| 321 // If the request has ended, move it to the graveyard. | 505 // If the request has ended, move it to the graveyard. |
| 322 if (entry.type == net::NetLog::TYPE_REQUEST_ALIVE && | 506 if (entry.type == net::NetLog::TYPE_REQUEST_ALIVE && |
| 323 entry.phase == net::NetLog::PHASE_END) { | 507 entry.phase == net::NetLog::PHASE_END) { |
| 508 IntegrateSubordinateSource(out_info, true); |
| 324 if (StartsWithASCII(out_info->url, "chrome://", false)) { | 509 if (StartsWithASCII(out_info->url, "chrome://", false)) { |
| 325 // Avoid sending "chrome://" requests to the graveyard, since it just | 510 // Avoid sending "chrome://" requests to the graveyard, since it just |
| 326 // adds to clutter. | 511 // adds to clutter. |
| 327 return ACTION_DELETE; | 512 return ACTION_DELETE; |
| 328 } | 513 } |
| 329 return ACTION_MOVE_TO_GRAVEYARD; | 514 return ACTION_MOVE_TO_GRAVEYARD; |
| 330 } | 515 } |
| 331 | 516 |
| 332 return ACTION_NONE; | 517 return ACTION_NONE; |
| 333 } | 518 } |
| 334 | 519 |
| 335 void PassiveLogCollector::RequestTracker::AddConnectJobInfo( | 520 void PassiveLogCollector::RequestTracker::IntegrateSubordinateSource( |
| 336 const Entry& entry, | 521 RequestInfo* info, bool clear_entries) const { |
| 337 RequestInfo* live_entry) { | 522 if (!info->subordinate_source.is_valid()) |
| 338 // We have just been notified of which ConnectJob the | 523 return; |
| 339 // URLRequest/SocketStream was assigned. Lookup all the data we captured | |
| 340 // for the ConnectJob, and append it to the URLRequest/SocketStream's | |
| 341 // RequestInfo. | |
| 342 | 524 |
| 343 int connect_job_id = static_cast<net::NetLogIntegerParameter*>( | 525 uint32 subordinate_id = info->subordinate_source.id; |
| 344 entry.extra_parameters.get())->value(); | 526 switch (info->subordinate_source.type) { |
| 345 | 527 case net::NetLog::SOURCE_CONNECT_JOB: |
| 346 const RequestInfo* connect_job_info = | 528 connect_job_tracker_->AppendLogEntries( |
| 347 connect_job_tracker_->GetRequestInfoFromGraveyard(connect_job_id); | 529 info, connect_job_tracker_->is_unbounded(), subordinate_id); |
| 348 | 530 break; |
| 349 if (connect_job_info) { | 531 case net::NetLog::SOURCE_SOCKET: |
| 350 // Append the ConnectJob information we found. | 532 socket_tracker_->AppendLogEntries(info, socket_tracker_->is_unbounded(), |
| 351 AppendToRequestInfo(*connect_job_info, is_unbounded(), live_entry); | 533 subordinate_id, clear_entries); |
| 352 } else { | 534 break; |
| 353 // If we couldn't find the information for the ConnectJob, append a | 535 default: |
| 354 // generic message instead. | 536 NOTREACHED(); |
| 355 Entry e(entry); | 537 break; |
| 356 e.type = net::NetLog::TYPE_TODO_STRING; | |
| 357 e.extra_parameters = new net::NetLogStringParameter( | |
| 358 StringPrintf("Used ConnectJob id=%d", connect_job_id)); | |
| 359 AddEntryToRequestInfo(e, is_unbounded(), live_entry); | |
| 360 } | 538 } |
| 361 } | 539 } |
| 362 | 540 |
| 363 //---------------------------------------------------------------------------- | 541 //---------------------------------------------------------------------------- |
| 364 // InitProxyResolverTracker | 542 // InitProxyResolverTracker |
| 365 //---------------------------------------------------------------------------- | 543 //---------------------------------------------------------------------------- |
| 366 | 544 |
| 367 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() {} | 545 PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() {} |
| 368 | 546 |
| 369 void PassiveLogCollector::InitProxyResolverTracker::OnAddEntry( | 547 void PassiveLogCollector::InitProxyResolverTracker::OnAddEntry( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 383 } | 561 } |
| 384 entries_.push_back(entry); | 562 entries_.push_back(entry); |
| 385 } | 563 } |
| 386 | 564 |
| 387 // Safety net: INIT_PROXY_RESOLVER shouldn't generate many messages, but in | 565 // Safety net: INIT_PROXY_RESOLVER shouldn't generate many messages, but in |
| 388 // case something goes wrong, avoid exploding the memory usage. | 566 // case something goes wrong, avoid exploding the memory usage. |
| 389 if (entries_.size() > kMaxNumEntriesPerLog) | 567 if (entries_.size() > kMaxNumEntriesPerLog) |
| 390 entries_.clear(); | 568 entries_.clear(); |
| 391 } | 569 } |
| 392 | 570 |
| OLD | NEW |