[export]
Not needed, will delete later
----
DO NOT SUBMIT. This PR is for testing purposes only. [cl/625488709](http://cl/625488709)
PiperOrigin-RevId: 625488709
diff --git a/BUILD b/BUILD
index 0978d4e..3e63934 100644
--- a/BUILD
+++ b/BUILD
@@ -4833,6 +4833,8 @@
"//src/core:connectivity_state",
"//src/core:error",
"//src/core:error_utils",
+ "//src/core:event_engine_extensions",
+ "//src/core:event_engine_query_extensions",
"//src/core:experiments",
"//src/core:gpr_manual_constructor",
"//src/core:http2_errors",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3499823..3dfb23b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2256,6 +2256,7 @@
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
src/core/lib/event_engine/event_engine.cc
+ src/core/lib/event_engine/extensions/tcp_trace.cc
src/core/lib/event_engine/forkable.cc
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -3049,6 +3050,7 @@
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
src/core/lib/event_engine/event_engine.cc
+ src/core/lib/event_engine/extensions/tcp_trace.cc
src/core/lib/event_engine/forkable.cc
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -5167,6 +5169,7 @@
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
src/core/lib/event_engine/event_engine.cc
+ src/core/lib/event_engine/extensions/tcp_trace.cc
src/core/lib/event_engine/forkable.cc
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -17796,6 +17799,7 @@
src/core/lib/event_engine/default_event_engine.cc
src/core/lib/event_engine/default_event_engine_factory.cc
src/core/lib/event_engine/event_engine.cc
+ src/core/lib/event_engine/extensions/tcp_trace.cc
src/core/lib/event_engine/forkable.cc
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
diff --git a/Makefile b/Makefile
index 2262596..e87eef1 100644
--- a/Makefile
+++ b/Makefile
@@ -1099,6 +1099,7 @@
src/core/lib/event_engine/default_event_engine.cc \
src/core/lib/event_engine/default_event_engine_factory.cc \
src/core/lib/event_engine/event_engine.cc \
+ src/core/lib/event_engine/extensions/tcp_trace.cc \
src/core/lib/event_engine/forkable.cc \
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc \
diff --git a/Package.swift b/Package.swift
index c4405cf..8cd1987 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1160,6 +1160,8 @@
"src/core/lib/event_engine/extensions/can_track_errors.h",
"src/core/lib/event_engine/extensions/chaotic_good_extension.h",
"src/core/lib/event_engine/extensions/supports_fd.h",
+ "src/core/lib/event_engine/extensions/tcp_trace.cc",
+ "src/core/lib/event_engine/extensions/tcp_trace.h",
"src/core/lib/event_engine/forkable.cc",
"src/core/lib/event_engine/forkable.h",
"src/core/lib/event_engine/grpc_polled_fd.h",
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index b60ae5b..cf1cc47 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -830,6 +830,7 @@
- src/core/lib/event_engine/extensions/can_track_errors.h
- src/core/lib/event_engine/extensions/chaotic_good_extension.h
- src/core/lib/event_engine/extensions/supports_fd.h
+ - src/core/lib/event_engine/extensions/tcp_trace.h
- src/core/lib/event_engine/forkable.h
- src/core/lib/event_engine/grpc_polled_fd.h
- src/core/lib/event_engine/handle_containers.h
@@ -1677,6 +1678,7 @@
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
- src/core/lib/event_engine/event_engine.cc
+ - src/core/lib/event_engine/extensions/tcp_trace.cc
- src/core/lib/event_engine/forkable.cc
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
- src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -2368,6 +2370,7 @@
- src/core/lib/event_engine/extensions/can_track_errors.h
- src/core/lib/event_engine/extensions/chaotic_good_extension.h
- src/core/lib/event_engine/extensions/supports_fd.h
+ - src/core/lib/event_engine/extensions/tcp_trace.h
- src/core/lib/event_engine/forkable.h
- src/core/lib/event_engine/grpc_polled_fd.h
- src/core/lib/event_engine/handle_containers.h
@@ -2830,6 +2833,7 @@
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
- src/core/lib/event_engine/event_engine.cc
+ - src/core/lib/event_engine/extensions/tcp_trace.cc
- src/core/lib/event_engine/forkable.cc
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
- src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -4458,6 +4462,7 @@
- src/core/lib/event_engine/extensions/can_track_errors.h
- src/core/lib/event_engine/extensions/chaotic_good_extension.h
- src/core/lib/event_engine/extensions/supports_fd.h
+ - src/core/lib/event_engine/extensions/tcp_trace.h
- src/core/lib/event_engine/forkable.h
- src/core/lib/event_engine/grpc_polled_fd.h
- src/core/lib/event_engine/handle_containers.h
@@ -4796,6 +4801,7 @@
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
- src/core/lib/event_engine/event_engine.cc
+ - src/core/lib/event_engine/extensions/tcp_trace.cc
- src/core/lib/event_engine/forkable.cc
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
- src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
@@ -11616,6 +11622,7 @@
- src/core/lib/event_engine/extensions/can_track_errors.h
- src/core/lib/event_engine/extensions/chaotic_good_extension.h
- src/core/lib/event_engine/extensions/supports_fd.h
+ - src/core/lib/event_engine/extensions/tcp_trace.h
- src/core/lib/event_engine/forkable.h
- src/core/lib/event_engine/grpc_polled_fd.h
- src/core/lib/event_engine/handle_containers.h
@@ -11923,6 +11930,7 @@
- src/core/lib/event_engine/default_event_engine.cc
- src/core/lib/event_engine/default_event_engine_factory.cc
- src/core/lib/event_engine/event_engine.cc
+ - src/core/lib/event_engine/extensions/tcp_trace.cc
- src/core/lib/event_engine/forkable.cc
- src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc
- src/core/lib/event_engine/posix_engine/ev_poll_posix.cc
diff --git a/config.m4 b/config.m4
index 4b72ff9..895ec02 100644
--- a/config.m4
+++ b/config.m4
@@ -474,6 +474,7 @@
src/core/lib/event_engine/default_event_engine.cc \
src/core/lib/event_engine/default_event_engine_factory.cc \
src/core/lib/event_engine/event_engine.cc \
+ src/core/lib/event_engine/extensions/tcp_trace.cc \
src/core/lib/event_engine/forkable.cc \
src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc \
src/core/lib/event_engine/posix_engine/ev_poll_posix.cc \
@@ -1520,6 +1521,7 @@
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine/cf_engine)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine/extensions)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine/posix_engine)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine/thread_pool)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/event_engine/thready_event_engine)
diff --git a/config.w32 b/config.w32
index f71331b..2a7242b 100644
--- a/config.w32
+++ b/config.w32
@@ -439,6 +439,7 @@
"src\\core\\lib\\event_engine\\default_event_engine.cc " +
"src\\core\\lib\\event_engine\\default_event_engine_factory.cc " +
"src\\core\\lib\\event_engine\\event_engine.cc " +
+ "src\\core\\lib\\event_engine\\extensions\\tcp_trace.cc " +
"src\\core\\lib\\event_engine\\forkable.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\ev_epoll1_linux.cc " +
"src\\core\\lib\\event_engine\\posix_engine\\ev_poll_posix.cc " +
@@ -1657,6 +1658,7 @@
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine\\cf_engine");
+ FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine\\extensions");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine\\posix_engine");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine\\thread_pool");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\event_engine\\thready_event_engine");
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 530f61b..8730225 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -911,6 +911,7 @@
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
+ 'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
'src/core/lib/event_engine/handle_containers.h',
@@ -2182,6 +2183,7 @@
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
+ 'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
'src/core/lib/event_engine/handle_containers.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index baff363..83d40d4 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -1279,6 +1279,8 @@
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
+ 'src/core/lib/event_engine/extensions/tcp_trace.cc',
+ 'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.cc',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
@@ -2962,6 +2964,7 @@
'src/core/lib/event_engine/extensions/can_track_errors.h',
'src/core/lib/event_engine/extensions/chaotic_good_extension.h',
'src/core/lib/event_engine/extensions/supports_fd.h',
+ 'src/core/lib/event_engine/extensions/tcp_trace.h',
'src/core/lib/event_engine/forkable.h',
'src/core/lib/event_engine/grpc_polled_fd.h',
'src/core/lib/event_engine/handle_containers.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 4a58496..6c0152e 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -1166,6 +1166,8 @@
s.files += %w( src/core/lib/event_engine/extensions/can_track_errors.h )
s.files += %w( src/core/lib/event_engine/extensions/chaotic_good_extension.h )
s.files += %w( src/core/lib/event_engine/extensions/supports_fd.h )
+ s.files += %w( src/core/lib/event_engine/extensions/tcp_trace.cc )
+ s.files += %w( src/core/lib/event_engine/extensions/tcp_trace.h )
s.files += %w( src/core/lib/event_engine/forkable.cc )
s.files += %w( src/core/lib/event_engine/forkable.h )
s.files += %w( src/core/lib/event_engine/grpc_polled_fd.h )
diff --git a/include/grpc/impl/channel_arg_names.h b/include/grpc/impl/channel_arg_names.h
index 663e962..bed5d22 100644
--- a/include/grpc/impl/channel_arg_names.h
+++ b/include/grpc/impl/channel_arg_names.h
@@ -259,6 +259,8 @@
"grpc.experimental.tcp_tx_zerocopy_max_simultaneous_sends"
/* Overrides the TCP socket recieve buffer size, SO_RCVBUF. */
#define GRPC_ARG_TCP_RECEIVE_BUFFER_SIZE "grpc.tcp_receive_buffer_size"
+/** If non-zero, enable TCP tracing and stats collection. */
+#define GRPC_ARG_TCP_TRACING_ENABLED "grpc.tcp_tracing_enabled"
/* Timeout in milliseconds to use for calls to the grpclb load balancer.
If 0 or unset, the balancer calls will have no deadline. */
#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms"
diff --git a/package.xml b/package.xml
index 44f8760..98ec26e 100644
--- a/package.xml
+++ b/package.xml
@@ -1148,6 +1148,8 @@
<file baseinstalldir="/" name="src/core/lib/event_engine/extensions/can_track_errors.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/extensions/chaotic_good_extension.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/extensions/supports_fd.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/event_engine/extensions/tcp_trace.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/event_engine/extensions/tcp_trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/forkable.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/forkable.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/event_engine/grpc_polled_fd.h" role="src" />
diff --git a/src/core/BUILD b/src/core/BUILD
index a9580c2..2baccbe 100644
--- a/src/core/BUILD
+++ b/src/core/BUILD
@@ -76,20 +76,27 @@
grpc_cc_library(
name = "event_engine_extensions",
+ srcs = ["lib/event_engine/extensions/tcp_trace.cc"],
hdrs = [
"lib/event_engine/extensions/can_track_errors.h",
"lib/event_engine/extensions/chaotic_good_extension.h",
"lib/event_engine/extensions/supports_fd.h",
+ "lib/event_engine/extensions/tcp_trace.h",
],
external_deps = [
"absl/status:statusor",
"absl/functional:any_invocable",
"absl/strings",
+ "absl/time",
+ "absl/types:optional",
],
deps = [
":memory_quota",
+ ":metrics",
"//:event_engine_base_hdrs",
+ "//:gpr",
"//:gpr_platform",
+ "//:tcp_tracer",
],
)
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 4acd9b5..3250c4d 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -79,6 +79,8 @@
#include "src/core/lib/channel/tcp_tracer.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/debug/stats_data.h"
+#include "src/core/lib/event_engine/extensions/tcp_trace.h"
+#include "src/core/lib/event_engine/query_extensions.h"
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
@@ -91,6 +93,7 @@
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/iomgr/event_engine_shims/endpoint.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr_fwd.h"
#include "src/core/lib/iomgr/port.h"
@@ -591,6 +594,10 @@
}
}
+using grpc_event_engine::experimental::Http2TransportTcpTracer;
+using grpc_event_engine::experimental::QueryExtension;
+using grpc_event_engine::experimental::TcpTraceExtension;
+
grpc_chttp2_transport::grpc_chttp2_transport(
const grpc_core::ChannelArgs& channel_args, grpc_endpoint* ep,
bool is_client)
@@ -618,6 +625,18 @@
deframe_state(is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0),
is_client(is_client) {
cl = new grpc_core::ContextList();
+
+ if (channel_args.GetBool(GRPC_ARG_TCP_TRACING_ENABLED).value_or(false) &&
+ grpc_event_engine::experimental::grpc_is_event_engine_endpoint(ep)) {
+ epte = QueryExtension<TcpTraceExtension>(
+ grpc_event_engine::experimental::grpc_get_wrapped_event_engine_endpoint(
+ ep));
+ if (epte != nullptr) {
+ tcp_tracer = std::make_shared<Http2TransportTcpTracer>();
+ epte->SetTcpTracer(tcp_tracer);
+ }
+ }
+
CHECK(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) ==
GRPC_CHTTP2_CLIENT_CONNECT_STRLEN);
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 058928a..83bd8a5 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -61,6 +61,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/tcp_tracer.h"
#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/event_engine/extensions/tcp_trace.h"
#include "src/core/lib/gprpp/bitset.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/ref_counted.h"
@@ -535,6 +536,10 @@
// What percentage of rst_stream frames on the server should cause a ping
// frame to be generated.
uint8_t ping_on_rst_stream_percent;
+
+ /// Only set when enabled.
+ grpc_event_engine::experimental::TcpTraceExtension* epte;
+ std::shared_ptr<grpc_core::TcpTracerInterface> tcp_tracer;
};
typedef enum {
diff --git a/src/core/lib/channel/metrics.h b/src/core/lib/channel/metrics.h
index 797be93..d72c5d6 100644
--- a/src/core/lib/channel/metrics.h
+++ b/src/core/lib/channel/metrics.h
@@ -40,6 +40,8 @@
namespace grpc_core {
constexpr absl::string_view kMetricLabelTarget = "grpc.target";
+constexpr absl::string_view kMetricLabelPeerAddress = "grpc.tcp.peer_address";
+constexpr absl::string_view kMetricLabelLocalAddress = "grpc.tcp.local_address";
// A global registry of instruments(metrics). This API is designed to be used
// to register instruments (Counter, Histogram, and Gauge) as part of program
diff --git a/src/core/lib/event_engine/extensions/tcp_trace.cc b/src/core/lib/event_engine/extensions/tcp_trace.cc
new file mode 100644
index 0000000..e54492d
--- /dev/null
+++ b/src/core/lib/event_engine/extensions/tcp_trace.cc
@@ -0,0 +1,134 @@
+// Copyright 2024 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/core/lib/event_engine/extensions/tcp_trace.h"
+
+#include "absl/strings/string_view.h"
+
+#include <grpc/support/metrics.h>
+
+#include "src/core/lib/channel/metrics.h"
+#include "src/core/lib/channel/tcp_tracer.h"
+#include "src/core/lib/gprpp/sync.h"
+
+namespace grpc_event_engine {
+namespace experimental {
+
+const auto kTCPConnectionMetricsMinRtt =
+ grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
+ "grpc.tcp.min_rtt",
+ "EXPERIMENTAL. Records TCP's current estimate of minimum round trip "
+ "time (RTT), typically used as an indication of the network health "
+ "between two endpoints.",
+ "{s}", /*enable_by_default=*/true)
+ .OptionalLabels(grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress)
+ .Build();
+
+const auto kTCPConnectionMetricsDeliveryRate =
+ grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
+ "grpc.tcp.delivery_rate",
+ "EXPERIMENTAL. Records latest throughput measured of the TCP "
+ "connection.",
+ "{bit/s}", /*enable_by_default=*/true)
+ .OptionalLabels(grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress)
+ .Build();
+
+const auto kTCPConnectionMetricsPacketSend =
+ grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
+ "grpc.tcp.packets_sent",
+ "EXPERIMENTAL. Records total packets TCP sends in the calculation "
+ "period.",
+ "{packet}", /*enable_by_default=*/true)
+ .OptionalLabels(grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress)
+ .Build();
+
+const auto kTCPConnectionMetricsPacketRetx =
+ grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
+ "grpc.tcp.packets_retransmitted",
+ "EXPERIMENTAL. Records total packets lost in the calculation period, "
+ "including lost or spuriously retransmitted packets.",
+ "{packet}", /*enable_by_default=*/true)
+ .OptionalLabels(grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress)
+ .Build();
+
+const auto kTCPConnectionMetricsPacketSpuriousRetx =
+ grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
+ "grpc.tcp.packets_spurious_retransmitted",
+ "EXPERIMENTAL. Records total packets spuriously retransmitted packets "
+ "in the calculation period. These are retransmissions that TCP later "
+ "discovered unnecessary.",
+ "{packet}", /*enable_by_default=*/true)
+ .OptionalLabels(grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress)
+ .Build();
+
+void Http2TransportTcpTracer::RecordConnectionMetrics(
+ ConnectionMetrics metrics) {
+ // This will be called periodically by Fathom.
+ // For cumulative stats, compute and get deltas to stats plugins.
+ if (metrics.packet_sent.has_value() && metrics.packet_retx.has_value() &&
+ metrics.packet_spurious_retx.has_value()) {
+ grpc_core::MutexLock lock(&mu_);
+ int packet_sent = metrics.packet_sent.value() -
+ connection_metrics_.packet_sent.value_or(0);
+ int packet_retx = metrics.packet_retx.value() -
+ connection_metrics_.packet_retx.value_or(0);
+ int packet_spurious_retx =
+ metrics.packet_spurious_retx.value() -
+ connection_metrics_.packet_spurious_retx.value_or(0);
+ grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
+ grpc_core::experimental::StatsPluginChannelScope("", ""))
+ .AddCounter(kTCPConnectionMetricsPacketSend, packet_sent, {},
+ {grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress});
+ grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
+ grpc_core::experimental::StatsPluginChannelScope("", ""))
+ .AddCounter(kTCPConnectionMetricsPacketRetx, packet_retx, {},
+ {grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress});
+ grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
+ grpc_core::experimental::StatsPluginChannelScope("", ""))
+ .AddCounter(kTCPConnectionMetricsPacketSpuriousRetx,
+ packet_spurious_retx, {},
+ {grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress});
+ connection_metrics_.packet_sent = metrics.packet_sent;
+ connection_metrics_.packet_retx = metrics.packet_retx;
+ connection_metrics_.packet_spurious_retx = metrics.packet_spurious_retx;
+ }
+ // For non-cumulative stats: Report to stats plugins.
+ if (metrics.min_rtt.has_value()) {
+ grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
+ grpc_core::experimental::StatsPluginChannelScope("", ""))
+ .RecordHistogram(
+ kTCPConnectionMetricsMinRtt,
+ static_cast<float>(metrics.min_rtt.value()) / 1000000.0, {},
+ {grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress});
+ }
+ if (metrics.delivery_rate.has_value()) {
+ grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
+ grpc_core::experimental::StatsPluginChannelScope("", ""))
+ .RecordHistogram(kTCPConnectionMetricsDeliveryRate,
+ metrics.delivery_rate.value(), {},
+ {grpc_core::kMetricLabelPeerAddress,
+ grpc_core::kMetricLabelLocalAddress});
+ }
+}
+} // namespace experimental
+} // namespace grpc_event_engine
\ No newline at end of file
diff --git a/src/core/lib/event_engine/extensions/tcp_trace.h b/src/core/lib/event_engine/extensions/tcp_trace.h
new file mode 100644
index 0000000..4e2eb6e
--- /dev/null
+++ b/src/core/lib/event_engine/extensions/tcp_trace.h
@@ -0,0 +1,58 @@
+// Copyright 2024 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_TCP_TRACE_H
+#define GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_TCP_TRACE_H
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "absl/types/optional.h"
+
+#include "src/core/lib/channel/tcp_tracer.h"
+#include "src/core/lib/gprpp/sync.h"
+
+namespace grpc_event_engine {
+namespace experimental {
+
+class Http2TransportTcpTracer : public grpc_core::TcpTracerInterface {
+ public:
+ Http2TransportTcpTracer() {}
+ ~Http2TransportTcpTracer() override {}
+ // Records a per-message event, unused.
+ void RecordEvent(Type /*type*/, absl::Time /*time*/, size_t /*byte_offset*/,
+ absl::optional<ConnectionMetrics> /*metrics*/) override {}
+ // Records per-connection metrics.
+ void RecordConnectionMetrics(ConnectionMetrics metrics) override;
+
+ private:
+ grpc_core::Mutex mu_;
+ ConnectionMetrics connection_metrics_ ABSL_GUARDED_BY(mu_);
+};
+
+class TcpTraceExtension {
+ public:
+ virtual ~TcpTraceExtension() = default;
+ static absl::string_view EndpointExtensionName() {
+ return "io.grpc.event_engine.extension.tcp_trace";
+ }
+ virtual void SetTcpTracer(
+ std::shared_ptr<grpc_core::TcpTracerInterface> tcp_tracer) = 0;
+};
+
+} // namespace experimental
+} // namespace grpc_event_engine
+
+#endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_EXTENSIONS_TCP_TRACE_H
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index f00614f..f5be2cd 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -448,6 +448,7 @@
'src/core/lib/event_engine/default_event_engine.cc',
'src/core/lib/event_engine/default_event_engine_factory.cc',
'src/core/lib/event_engine/event_engine.cc',
+ 'src/core/lib/event_engine/extensions/tcp_trace.cc',
'src/core/lib/event_engine/forkable.cc',
'src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc',
'src/core/lib/event_engine/posix_engine/ev_poll_posix.cc',
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 649e1eb..191c7a8 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -2165,6 +2165,8 @@
src/core/lib/event_engine/extensions/can_track_errors.h \
src/core/lib/event_engine/extensions/chaotic_good_extension.h \
src/core/lib/event_engine/extensions/supports_fd.h \
+src/core/lib/event_engine/extensions/tcp_trace.cc \
+src/core/lib/event_engine/extensions/tcp_trace.h \
src/core/lib/event_engine/forkable.cc \
src/core/lib/event_engine/forkable.h \
src/core/lib/event_engine/grpc_polled_fd.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index d3a4f44..a1c4edb 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1937,6 +1937,8 @@
src/core/lib/event_engine/extensions/can_track_errors.h \
src/core/lib/event_engine/extensions/chaotic_good_extension.h \
src/core/lib/event_engine/extensions/supports_fd.h \
+src/core/lib/event_engine/extensions/tcp_trace.cc \
+src/core/lib/event_engine/extensions/tcp_trace.h \
src/core/lib/event_engine/forkable.cc \
src/core/lib/event_engine/forkable.h \
src/core/lib/event_engine/grpc_polled_fd.h \