gfe-relnote: In GFE, export number of QUIC packets written per write operation. Protected by FLAGS_quic_export_server_num_packets_per_write_histogram.

PiperOrigin-RevId: 249251940
Change-Id: Ie92306bb1d10dec11c2801353026b363f3046d81
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index e69ac85..9f9a68f 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -868,11 +868,7 @@
   } else {
     header->nonce = nullptr;
   }
-  if (!packet_.packet_number.IsInitialized()) {
-    packet_.packet_number = framer_->first_sending_packet_number();
-  } else {
-    ++packet_.packet_number;
-  }
+  packet_.packet_number = NextSendingPacketNumber();
   header->packet_number = packet_.packet_number;
   header->packet_number_length = GetPacketNumberLength();
   header->retry_token_length_length = GetRetryTokenLengthLength();
@@ -1128,5 +1124,12 @@
   return 7;
 }
 
+QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
+  if (!packet_number().IsInitialized()) {
+    return framer_->first_sending_packet_number();
+  }
+  return packet_number() + 1;
+}
+
 #undef ENDPOINT  // undef for jumbo builds
 }  // namespace quic
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
index 259b577..06acfbe 100644
--- a/quic/core/quic_packet_creator.h
+++ b/quic/core/quic_packet_creator.h
@@ -273,6 +273,9 @@
   // connection ID lengths do not change.
   QuicPacketLength GetGuaranteedLargestMessagePayload() const;
 
+  // Packet number of next created packet.
+  QuicPacketNumber NextSendingPacketNumber() const;
+
   void set_debug_delegate(DebugDelegate* debug_delegate) {
     debug_delegate_ = debug_delegate;
   }
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc
index f490900..6f578f5 100644
--- a/quic/core/quic_packet_generator.cc
+++ b/quic/core/quic_packet_generator.cc
@@ -14,6 +14,7 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
 
 namespace quic {
 
@@ -317,6 +318,9 @@
 
 void QuicPacketGenerator::AttachPacketFlusher() {
   flusher_attached_ = true;
+  if (!write_start_packet_number_.IsInitialized()) {
+    write_start_packet_number_ = packet_creator_.NextSendingPacketNumber();
+  }
 }
 
 void QuicPacketGenerator::Flush() {
@@ -324,6 +328,17 @@
   packet_creator_.Flush();
   SendRemainingPendingPadding();
   flusher_attached_ = false;
+  if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
+    if (!write_start_packet_number_.IsInitialized()) {
+      QUIC_BUG << "write_start_packet_number is not initialized";
+      return;
+    }
+    QUIC_SERVER_HISTOGRAM_COUNTS(
+        "quic_server_num_written_packets_per_write",
+        packet_creator_.NextSendingPacketNumber() - write_start_packet_number_,
+        1, 200, 50, "Number of QUIC packets written per write operation");
+  }
+  write_start_packet_number_.Clear();
 }
 
 void QuicPacketGenerator::FlushAllQueuedFrames() {
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h
index 6ea8215..327cc47 100644
--- a/quic/core/quic_packet_generator.h
+++ b/quic/core/quic_packet_generator.h
@@ -318,6 +318,11 @@
   // Whether crypto handshake packets should be fully padded.
   bool fully_pad_crypto_handshake_packets_;
 
+  // Packet number of the first packet of a write operation. This gets set
+  // when the out-most flusher attaches and gets cleared when the out-most
+  // flusher detaches.
+  QuicPacketNumber write_start_packet_number_;
+
   // Latched value of quic_deprecate_ack_bundling_mode.
   const bool deprecate_ack_bundling_mode_;