Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(855)

Side by Side Diff: net/quic/quic_connection_logger.cc

Issue 180833004: Gather histogram for received packets indicating losses. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Respond to comments, and add small optimization Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_connection_logger.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "net/quic/quic_connection_logger.h" 5 #include "net/quic/quic_connection_logger.h"
6 6
7 #include <algorithm>
8 #include <string>
9
7 #include "base/bind.h" 10 #include "base/bind.h"
8 #include "base/callback.h" 11 #include "base/callback.h"
9 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
10 #include "base/metrics/sparse_histogram.h" 13 #include "base/metrics/sparse_histogram.h"
11 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
12 #include "base/values.h" 15 #include "base/values.h"
13 #include "net/base/net_log.h" 16 #include "net/base/net_log.h"
14 #include "net/quic/crypto/crypto_handshake_message.h" 17 #include "net/quic/crypto/crypto_handshake_message.h"
15 #include "net/quic/crypto/crypto_protocol.h" 18 #include "net/quic/crypto/crypto_protocol.h"
16 #include "net/quic/quic_address_mismatch.h" 19 #include "net/quic/quic_address_mismatch.h"
17 #include "net/quic/quic_socket_address_coder.h" 20 #include "net/quic/quic_socket_address_coder.h"
18 21
19 using base::StringPiece; 22 using base::StringPiece;
20 using std::string; 23 using std::string;
21 24
22 namespace net { 25 namespace net {
23 26
24 namespace { 27 namespace {
25
26 base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address, 28 base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address,
27 const IPEndPoint* peer_address, 29 const IPEndPoint* peer_address,
28 size_t packet_size, 30 size_t packet_size,
29 NetLog::LogLevel /* log_level */) { 31 NetLog::LogLevel /* log_level */) {
30 base::DictionaryValue* dict = new base::DictionaryValue(); 32 base::DictionaryValue* dict = new base::DictionaryValue();
31 dict->SetString("self_address", self_address->ToString()); 33 dict->SetString("self_address", self_address->ToString());
32 dict->SetString("peer_address", peer_address->ToString()); 34 dict->SetString("peer_address", peer_address->ToString());
33 dict->SetInteger("size", packet_size); 35 dict->SetInteger("size", packet_size);
34 return dict; 36 return dict;
35 } 37 }
(...skipping 12 matching lines...) Expand all
48 if (result.status != WRITE_STATUS_OK) { 50 if (result.status != WRITE_STATUS_OK) {
49 dict->SetInteger("net_error", result.error_code); 51 dict->SetInteger("net_error", result.error_code);
50 } 52 }
51 return dict; 53 return dict;
52 } 54 }
53 55
54 base::Value* NetLogQuicPacketRetransmittedCallback( 56 base::Value* NetLogQuicPacketRetransmittedCallback(
55 QuicPacketSequenceNumber old_sequence_number, 57 QuicPacketSequenceNumber old_sequence_number,
56 QuicPacketSequenceNumber new_sequence_number, 58 QuicPacketSequenceNumber new_sequence_number,
57 NetLog::LogLevel /* log_level */) { 59 NetLog::LogLevel /* log_level */) {
58 base::DictionaryValue* dict = new base::DictionaryValue(); 60 base::DictionaryValue* dict = new base::DictionaryValue();
59 dict->SetString("old_packet_sequence_number", 61 dict->SetString("old_packet_sequence_number",
60 base::Uint64ToString(old_sequence_number)); 62 base::Uint64ToString(old_sequence_number));
61 dict->SetString("new_packet_sequence_number", 63 dict->SetString("new_packet_sequence_number",
62 base::Uint64ToString(new_sequence_number)); 64 base::Uint64ToString(new_sequence_number));
63 return dict; 65 return dict;
64 } 66 }
65 67
66 base::Value* NetLogQuicPacketHeaderCallback(const QuicPacketHeader* header, 68 base::Value* NetLogQuicPacketHeaderCallback(const QuicPacketHeader* header,
67 NetLog::LogLevel /* log_level */) { 69 NetLog::LogLevel /* log_level */) {
68 base::DictionaryValue* dict = new base::DictionaryValue(); 70 base::DictionaryValue* dict = new base::DictionaryValue();
69 dict->SetString("guid", 71 dict->SetString("guid",
70 base::Uint64ToString(header->public_header.guid)); 72 base::Uint64ToString(header->public_header.guid));
71 dict->SetInteger("reset_flag", header->public_header.reset_flag); 73 dict->SetInteger("reset_flag", header->public_header.reset_flag);
72 dict->SetInteger("version_flag", header->public_header.version_flag); 74 dict->SetInteger("version_flag", header->public_header.version_flag);
73 dict->SetString("packet_sequence_number", 75 dict->SetString("packet_sequence_number",
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 NetLog::LogLevel /* log_level */) { 119 NetLog::LogLevel /* log_level */) {
118 base::DictionaryValue* dict = new base::DictionaryValue(); 120 base::DictionaryValue* dict = new base::DictionaryValue();
119 switch (frame->type) { 121 switch (frame->type) {
120 case kInterArrival: { 122 case kInterArrival: {
121 dict->SetString("type", "InterArrival"); 123 dict->SetString("type", "InterArrival");
122 base::ListValue* received = new base::ListValue(); 124 base::ListValue* received = new base::ListValue();
123 dict->Set("received_packets", received); 125 dict->Set("received_packets", received);
124 for (TimeMap::const_iterator it = 126 for (TimeMap::const_iterator it =
125 frame->inter_arrival.received_packet_times.begin(); 127 frame->inter_arrival.received_packet_times.begin();
126 it != frame->inter_arrival.received_packet_times.end(); ++it) { 128 it != frame->inter_arrival.received_packet_times.end(); ++it) {
127 std::string value = base::Uint64ToString(it->first) + "@" + 129 string value = base::Uint64ToString(it->first) + "@" +
128 base::Uint64ToString(it->second.ToDebuggingValue()); 130 base::Uint64ToString(it->second.ToDebuggingValue());
129 received->AppendString(value); 131 received->AppendString(value);
130 } 132 }
131 break; 133 break;
132 } 134 }
133 case kFixRate: 135 case kFixRate:
134 dict->SetString("type", "FixRate"); 136 dict->SetString("type", "FixRate");
135 dict->SetInteger("bitrate_in_bytes_per_second", 137 dict->SetInteger("bitrate_in_bytes_per_second",
136 frame->fix_rate.bitrate.ToBytesPerSecond()); 138 frame->fix_rate.bitrate.ToBytesPerSecond());
137 break; 139 break;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 216
215 } // namespace 217 } // namespace
216 218
217 QuicConnectionLogger::QuicConnectionLogger(const BoundNetLog& net_log) 219 QuicConnectionLogger::QuicConnectionLogger(const BoundNetLog& net_log)
218 : net_log_(net_log), 220 : net_log_(net_log),
219 last_received_packet_sequence_number_(0), 221 last_received_packet_sequence_number_(0),
220 largest_received_packet_sequence_number_(0), 222 largest_received_packet_sequence_number_(0),
221 largest_received_missing_packet_sequence_number_(0), 223 largest_received_missing_packet_sequence_number_(0),
222 out_of_order_recieved_packet_count_(0), 224 out_of_order_recieved_packet_count_(0),
223 num_truncated_acks_sent_(0), 225 num_truncated_acks_sent_(0),
224 num_truncated_acks_received_(0) { 226 num_truncated_acks_received_(0),
227 connection_type_(NetworkChangeNotifier::GetConnectionType()) {
225 } 228 }
226 229
227 QuicConnectionLogger::~QuicConnectionLogger() { 230 QuicConnectionLogger::~QuicConnectionLogger() {
228 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived", 231 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived",
229 out_of_order_recieved_packet_count_); 232 out_of_order_recieved_packet_count_);
230 UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksSent", 233 UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksSent",
231 num_truncated_acks_sent_); 234 num_truncated_acks_sent_);
232 UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksReceived", 235 UMA_HISTOGRAM_COUNTS("Net.QuicSession.TruncatedAcksReceived",
233 num_truncated_acks_received_); 236 num_truncated_acks_received_);
237
238 RecordAckNackHistograms();
234 } 239 }
235 240
236 void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { 241 void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
237 switch (frame.type) { 242 switch (frame.type) {
238 case PADDING_FRAME: 243 case PADDING_FRAME:
239 break; 244 break;
240 case STREAM_FRAME: 245 case STREAM_FRAME:
241 net_log_.AddEvent( 246 net_log_.AddEvent(
242 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_SENT, 247 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_SENT,
243 base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame)); 248 base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 QuicPacketSequenceNumber delta = header.packet_sequence_number - 324 QuicPacketSequenceNumber delta = header.packet_sequence_number -
320 largest_received_packet_sequence_number_; 325 largest_received_packet_sequence_number_;
321 if (delta > 1) { 326 if (delta > 1) {
322 // There is a gap between the largest packet previously received and 327 // There is a gap between the largest packet previously received and
323 // the current packet. This indicates either loss, or out-of-order 328 // the current packet. This indicates either loss, or out-of-order
324 // delivery. 329 // delivery.
325 UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapReceived", delta - 1); 330 UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapReceived", delta - 1);
326 } 331 }
327 largest_received_packet_sequence_number_ = header.packet_sequence_number; 332 largest_received_packet_sequence_number_ = header.packet_sequence_number;
328 } 333 }
334 if (header.packet_sequence_number < MAX_PACKET_STATUS) {
335 packets_received_[header.packet_sequence_number] = true;
Ryan Hamilton 2014/03/06 04:47:43 Since you're comparing with <, and not indexing by
jar (doing other things) 2014/03/07 17:11:48 Fixed per discussion.
336 }
329 if (header.packet_sequence_number < last_received_packet_sequence_number_) { 337 if (header.packet_sequence_number < last_received_packet_sequence_number_) {
330 ++out_of_order_recieved_packet_count_; 338 ++out_of_order_recieved_packet_count_;
331 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderGapReceived", 339 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderGapReceived",
332 last_received_packet_sequence_number_ - 340 last_received_packet_sequence_number_ -
333 header.packet_sequence_number); 341 header.packet_sequence_number);
334 } 342 }
335 last_received_packet_sequence_number_ = header.packet_sequence_number; 343 last_received_packet_sequence_number_ = header.packet_sequence_number;
336 } 344 }
337 345
338 void QuicConnectionLogger::OnStreamFrame(const QuicStreamFrame& frame) { 346 void QuicConnectionLogger::OnStreamFrame(const QuicStreamFrame& frame) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 base::Bind(&NetLogQuicOnConnectionClosedCallback, error, from_peer)); 467 base::Bind(&NetLogQuicOnConnectionClosedCallback, error, from_peer));
460 } 468 }
461 469
462 void QuicConnectionLogger::OnSuccessfulVersionNegotiation( 470 void QuicConnectionLogger::OnSuccessfulVersionNegotiation(
463 const QuicVersion& version) { 471 const QuicVersion& version) {
464 string quic_version = QuicVersionToString(version); 472 string quic_version = QuicVersionToString(version);
465 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_VERSION_NEGOTIATED, 473 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_VERSION_NEGOTIATED,
466 NetLog::StringCallback("version", &quic_version)); 474 NetLog::StringCallback("version", &quic_version));
467 } 475 }
468 476
477 void QuicConnectionLogger::RecordAckNackHistograms() {
478 if (largest_received_packet_sequence_number_ == 0)
479 return; // Connection was never used.
480 std::string prefix("Net.QuicSession.PacketReceived_");
481 std::string suffix = NetworkChangeNotifier::ConnectionTypeToString(
482 connection_type_);
483 base::HistogramBase* packet_ack_histogram(base::LinearHistogram::FactoryGet(
484 prefix + "Ack_" + suffix, 1, MAX_PACKET_STATUS, MAX_PACKET_STATUS + 1,
Ryan Hamilton 2014/03/06 04:47:43 Can you extract this logic into a single method th
jar (doing other things) 2014/03/07 17:11:48 Done.
485 base::HistogramBase::kUmaTargetedHistogramFlag));
486 // Most of the time, we don't have any missing packets, so only cache the
487 // NACK histogram when we need it (just in time).
Ryan Hamilton 2014/03/06 04:47:43 Given that this code runs extremely infrequently,
jar (doing other things) 2014/03/07 17:11:48 Done.
488 base::HistogramBase* packet_nack_histogram = NULL;
489 // largest_received_packet_sequence_number_ is a uint64, so it is easier
490 // to take the min() with a size_t MAX_PACKET_STATUS manually.
491 const size_t last_index =
492 (MAX_PACKET_STATUS - 1 < largest_received_packet_sequence_number_) ?
493 MAX_PACKET_STATUS - 1 :
494 static_cast<size_t>(largest_received_packet_sequence_number_);
Ryan Hamilton 2014/03/06 04:47:43 I don't think I understand why doing this manually
jar (doing other things) 2014/03/07 17:11:48 Per discussion... I changed to consistent typedefs
495 // We never get packet 0, so we skip recording stats for it, as it would
496 // always show as missing (Not ACKnowledged).
497 DCHECK(!packets_received_[0]);
498 for (size_t i = 1; i <= last_index; ++i) {
499 if (packets_received_[i]) {
500 packet_ack_histogram->Add(i);
501 } else {
502 if (!packet_nack_histogram) {
503 // Now we need the NACK histogram now.
504 packet_nack_histogram = base::LinearHistogram::FactoryGet(
505 prefix + "Nack_" + suffix, 1, MAX_PACKET_STATUS,
506 MAX_PACKET_STATUS + 1,
507 base::HistogramBase::kUmaTargetedHistogramFlag);
508 }
509 packet_nack_histogram->Add(i);
510 }
511 }
512 }
513
469 } // namespace net 514 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection_logger.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698