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 |