Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/chromium/quic_connection_logger.h" | 5 #include "net/quic/chromium/quic_connection_logger.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "net/quic/core/quic_socket_address_coder.h" | 27 #include "net/quic/core/quic_socket_address_coder.h" |
| 28 #include "net/quic/core/quic_time.h" | 28 #include "net/quic/core/quic_time.h" |
| 29 | 29 |
| 30 using base::StringPiece; | 30 using base::StringPiece; |
| 31 using std::string; | 31 using std::string; |
| 32 | 32 |
| 33 namespace net { | 33 namespace net { |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 // We have ranges-of-buckets in the cumulative histogram (covering 21 packet | |
| 38 // sequences) of length 2, 3, 4, ... 22. | |
| 39 // Hence the largest sample is bounded by the sum of those numbers. | |
| 40 const int kBoundingSampleInCumulativeHistogram = ((2 + 22) * 21) / 2; | |
| 41 | |
| 42 std::unique_ptr<base::Value> NetLogQuicPacketCallback( | 37 std::unique_ptr<base::Value> NetLogQuicPacketCallback( |
| 43 const IPEndPoint* self_address, | 38 const IPEndPoint* self_address, |
| 44 const IPEndPoint* peer_address, | 39 const IPEndPoint* peer_address, |
| 45 size_t packet_size, | 40 size_t packet_size, |
| 46 NetLogCaptureMode /* capture_mode */) { | 41 NetLogCaptureMode /* capture_mode */) { |
| 47 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 42 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 48 dict->SetString("self_address", self_address->ToString()); | 43 dict->SetString("self_address", self_address->ToString()); |
| 49 dict->SetString("peer_address", peer_address->ToString()); | 44 dict->SetString("peer_address", peer_address->ToString()); |
| 50 dict->SetInteger("size", packet_size); | 45 dict->SetInteger("size", packet_size); |
| 51 return std::move(dict); | 46 return std::move(dict); |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 UMA_HISTOGRAM_CUSTOM_COUNTS( | 335 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 341 "Net.QuicSession.StreamFrameDuplicatedShortConnection", | 336 "Net.QuicSession.StreamFrameDuplicatedShortConnection", |
| 342 duplicate_stream_frame_per_thousand, 1, 1000, 75); | 337 duplicate_stream_frame_per_thousand, 1, 1000, 75); |
| 343 } else { | 338 } else { |
| 344 UMA_HISTOGRAM_CUSTOM_COUNTS( | 339 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 345 "Net.QuicSession.StreamFrameDuplicatedLongConnection", | 340 "Net.QuicSession.StreamFrameDuplicatedLongConnection", |
| 346 duplicate_stream_frame_per_thousand, 1, 1000, 75); | 341 duplicate_stream_frame_per_thousand, 1, 1000, 75); |
| 347 } | 342 } |
| 348 } | 343 } |
| 349 | 344 |
| 350 RecordLossHistograms(); | 345 if (largest_received_packet_number_ != 0) |
|
Ryan Hamilton
2016/08/18 19:36:33
Is this check needed, since the method already che
Zhongyi Shi
2016/08/18 20:13:11
Ah, yeah, this can be removed. Removed.
| |
| 346 RecordAggregatePacketLossRate(); | |
| 351 } | 347 } |
| 352 | 348 |
| 353 void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { | 349 void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) { |
| 354 switch (frame.type) { | 350 switch (frame.type) { |
| 355 case PADDING_FRAME: | 351 case PADDING_FRAME: |
| 356 break; | 352 break; |
| 357 case STREAM_FRAME: | 353 case STREAM_FRAME: |
| 358 net_log_.AddEvent( | 354 net_log_.AddEvent( |
| 359 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_SENT, | 355 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_SENT, |
| 360 base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame)); | 356 base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame)); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 const CertVerifyResult& result) { | 674 const CertVerifyResult& result) { |
| 679 if (result.cert_status == CERT_STATUS_INVALID) { | 675 if (result.cert_status == CERT_STATUS_INVALID) { |
| 680 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_CERTIFICATE_VERIFY_FAILED); | 676 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_CERTIFICATE_VERIFY_FAILED); |
| 681 return; | 677 return; |
| 682 } | 678 } |
| 683 net_log_.AddEvent( | 679 net_log_.AddEvent( |
| 684 NetLog::TYPE_QUIC_SESSION_CERTIFICATE_VERIFIED, | 680 NetLog::TYPE_QUIC_SESSION_CERTIFICATE_VERIFIED, |
| 685 base::Bind(&NetLogQuicCertificateVerifiedCallback, result.verified_cert)); | 681 base::Bind(&NetLogQuicCertificateVerifiedCallback, result.verified_cert)); |
| 686 } | 682 } |
| 687 | 683 |
| 688 base::HistogramBase* QuicConnectionLogger::GetPacketNumberHistogram( | |
| 689 const char* statistic_name) const { | |
| 690 string prefix("Net.QuicSession.PacketReceived_"); | |
| 691 return base::LinearHistogram::FactoryGet( | |
| 692 prefix + statistic_name + connection_description_, 1, | |
| 693 received_packets_.size(), received_packets_.size() + 1, | |
| 694 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 695 } | |
| 696 | |
| 697 base::HistogramBase* QuicConnectionLogger::Get6PacketHistogram( | 684 base::HistogramBase* QuicConnectionLogger::Get6PacketHistogram( |
| 698 const char* which_6) const { | 685 const char* which_6) const { |
| 699 // This histogram takes a binary encoding of the 6 consecutive packets | 686 // This histogram takes a binary encoding of the 6 consecutive packets |
| 700 // received. As a result, there are 64 possible sample-patterns. | 687 // received. As a result, there are 64 possible sample-patterns. |
| 701 string prefix("Net.QuicSession.6PacketsPatternsReceived_"); | 688 string prefix("Net.QuicSession.6PacketsPatternsReceived_"); |
| 702 return base::LinearHistogram::FactoryGet( | 689 return base::LinearHistogram::FactoryGet( |
| 703 prefix + which_6 + connection_description_, 1, 64, 65, | 690 prefix + which_6 + connection_description_, 1, 64, 65, |
| 704 base::HistogramBase::kUmaTargetedHistogramFlag); | 691 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 705 } | 692 } |
| 706 | 693 |
| 707 base::HistogramBase* QuicConnectionLogger::Get21CumulativeHistogram( | |
| 708 const char* which_21) const { | |
| 709 // This histogram contains, for each sequence of 21 packets, the results from | |
| 710 // 21 distinct questions about that sequence. Conceptually the histogtram is | |
| 711 // broken into 21 distinct ranges, and one sample is added into each of those | |
| 712 // ranges whenever we process a set of 21 packets. | |
| 713 // There is a little rendundancy, as each "range" must have the same number | |
| 714 // of samples, all told, but the histogram is a tad easier to read this way. | |
| 715 // The questions are: | |
| 716 // Was the first packet present (bucket 0==>no; bucket 1==>yes) | |
| 717 // Of the first two packets, how many were present? (bucket 2==> none; | |
| 718 // bucket 3==> 1 of 2; bucket 4==> 2 of 2) | |
| 719 // Of the first three packets, how many were present? (bucket 5==>none; | |
| 720 // bucket 6==> 1 of 3; bucket 7==> 2 of 3; bucket 8==> 3 of 3). | |
| 721 // etc. | |
| 722 string prefix("Net.QuicSession.21CumulativePacketsReceived_"); | |
| 723 return base::LinearHistogram::FactoryGet( | |
| 724 prefix + which_21 + connection_description_, 1, | |
| 725 kBoundingSampleInCumulativeHistogram, | |
| 726 kBoundingSampleInCumulativeHistogram + 1, | |
| 727 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 728 } | |
| 729 | |
| 730 // static | |
| 731 void QuicConnectionLogger::AddTo21CumulativeHistogram( | |
| 732 base::HistogramBase* histogram, | |
| 733 int bit_mask_of_packets, | |
| 734 int valid_bits_in_mask) { | |
| 735 DCHECK_LE(valid_bits_in_mask, 21); | |
| 736 DCHECK_LT(bit_mask_of_packets, 1 << 21); | |
| 737 const int blank_bits_in_mask = 21 - valid_bits_in_mask; | |
| 738 DCHECK_EQ(bit_mask_of_packets & ((1 << blank_bits_in_mask) - 1), 0); | |
| 739 bit_mask_of_packets >>= blank_bits_in_mask; | |
| 740 int bits_so_far = 0; | |
| 741 int range_start = 0; | |
| 742 for (int i = 1; i <= valid_bits_in_mask; ++i) { | |
| 743 bits_so_far += bit_mask_of_packets & 1; | |
| 744 bit_mask_of_packets >>= 1; | |
| 745 DCHECK_LT(range_start + bits_so_far, kBoundingSampleInCumulativeHistogram); | |
| 746 histogram->Add(range_start + bits_so_far); | |
| 747 range_start += i + 1; | |
| 748 } | |
| 749 } | |
| 750 | |
| 751 float QuicConnectionLogger::ReceivedPacketLossRate() const { | 694 float QuicConnectionLogger::ReceivedPacketLossRate() const { |
| 752 if (largest_received_packet_number_ <= num_packets_received_) | 695 if (largest_received_packet_number_ <= num_packets_received_) |
| 753 return 0.0f; | 696 return 0.0f; |
| 754 float num_received = largest_received_packet_number_ - num_packets_received_; | 697 float num_received = largest_received_packet_number_ - num_packets_received_; |
| 755 return num_received / largest_received_packet_number_; | 698 return num_received / largest_received_packet_number_; |
| 756 } | 699 } |
| 757 | 700 |
| 758 void QuicConnectionLogger::OnRttChanged(QuicTime::Delta rtt) const { | 701 void QuicConnectionLogger::OnRttChanged(QuicTime::Delta rtt) const { |
| 759 // Notify socket performance watcher of the updated RTT value. | 702 // Notify socket performance watcher of the updated RTT value. |
| 760 if (!socket_performance_watcher_) | 703 if (!socket_performance_watcher_) |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 778 return; | 721 return; |
| 779 | 722 |
| 780 string prefix("Net.QuicSession.PacketLossRate_"); | 723 string prefix("Net.QuicSession.PacketLossRate_"); |
| 781 base::HistogramBase* histogram = base::Histogram::FactoryGet( | 724 base::HistogramBase* histogram = base::Histogram::FactoryGet( |
| 782 prefix + connection_description_, 1, 1000, 75, | 725 prefix + connection_description_, 1, 1000, 75, |
| 783 base::HistogramBase::kUmaTargetedHistogramFlag); | 726 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 784 histogram->Add(static_cast<base::HistogramBase::Sample>( | 727 histogram->Add(static_cast<base::HistogramBase::Sample>( |
| 785 ReceivedPacketLossRate() * 1000)); | 728 ReceivedPacketLossRate() * 1000)); |
| 786 } | 729 } |
| 787 | 730 |
| 788 void QuicConnectionLogger::RecordLossHistograms() const { | |
| 789 if (largest_received_packet_number_ == 0) | |
| 790 return; // Connection was never used. | |
| 791 RecordAggregatePacketLossRate(); | |
| 792 | |
| 793 base::HistogramBase* is_not_ack_histogram = | |
| 794 GetPacketNumberHistogram("IsNotAck_"); | |
| 795 base::HistogramBase* is_an_ack_histogram = | |
| 796 GetPacketNumberHistogram("IsAnAck_"); | |
| 797 base::HistogramBase* packet_arrived_histogram = | |
| 798 GetPacketNumberHistogram("Ack_"); | |
| 799 base::HistogramBase* packet_missing_histogram = | |
| 800 GetPacketNumberHistogram("Nack_"); | |
| 801 base::HistogramBase* ongoing_cumulative_packet_histogram = | |
| 802 Get21CumulativeHistogram("Some21s_"); | |
| 803 base::HistogramBase* first_cumulative_packet_histogram = | |
| 804 Get21CumulativeHistogram("First21_"); | |
| 805 base::HistogramBase* six_packet_histogram = Get6PacketHistogram("Some6s_"); | |
| 806 | |
| 807 DCHECK_EQ(received_packets_.size(), received_acks_.size()); | |
| 808 const QuicPacketNumber last_index = std::min<QuicPacketNumber>( | |
| 809 received_packets_.size() - 1, largest_received_packet_number_); | |
| 810 const QuicPacketNumber index_of_first_21_contribution = | |
| 811 std::min<QuicPacketNumber>(21, last_index); | |
| 812 // Bit pattern of consecutively received packets that is maintained as we scan | |
| 813 // through the received_packets_ vector. Less significant bits correspond to | |
| 814 // less recent packets, and only the low order 21 bits are ever defined. | |
| 815 // Bit is 1 iff corresponding packet was received. | |
| 816 int packet_pattern_21 = 0; | |
| 817 // Zero is an invalid packet sequence number. | |
| 818 DCHECK(!received_packets_[0]); | |
| 819 for (size_t i = 1; i <= last_index; ++i) { | |
| 820 if (received_acks_[i]) | |
| 821 is_an_ack_histogram->Add(i); | |
| 822 else | |
| 823 is_not_ack_histogram->Add(i); | |
| 824 | |
| 825 packet_pattern_21 >>= 1; | |
| 826 if (received_packets_[i]) { | |
| 827 packet_arrived_histogram->Add(i); | |
| 828 packet_pattern_21 |= (1 << 20); // Turn on the 21st bit. | |
| 829 } else { | |
| 830 packet_missing_histogram->Add(i); | |
| 831 } | |
| 832 | |
| 833 if (i == index_of_first_21_contribution) { | |
| 834 AddTo21CumulativeHistogram(first_cumulative_packet_histogram, | |
| 835 packet_pattern_21, i); | |
| 836 } | |
| 837 // We'll just record for non-overlapping ranges, to reduce histogramming | |
| 838 // cost for now. Each call does 21 separate histogram additions. | |
| 839 if (i > 21 || i % 21 == 0) { | |
| 840 AddTo21CumulativeHistogram(ongoing_cumulative_packet_histogram, | |
| 841 packet_pattern_21, 21); | |
| 842 } | |
| 843 | |
| 844 if (i < 6) | |
| 845 continue; // Not enough packets to do any pattern recording. | |
| 846 int recent_6_mask = packet_pattern_21 >> 15; | |
| 847 DCHECK_LT(recent_6_mask, 64); | |
| 848 if (i == 6) { | |
| 849 Get6PacketHistogram("First6_")->Add(recent_6_mask); | |
| 850 continue; | |
| 851 } | |
| 852 // Record some overlapping patterns, to get a better picture, since this is | |
| 853 // not very expensive. | |
| 854 if (i % 3 == 0) | |
| 855 six_packet_histogram->Add(recent_6_mask); | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 } // namespace net | 731 } // namespace net |
| OLD | NEW |