diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8ce331e529d..8a5c3e7e5e5 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -25,17 +25,10 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/gprpp/inlined_vector.h" typedef struct grpc_subchannel grpc_subchannel; namespace grpc_core { - -// TODO(ncteisen), this only contains the uuids of the children for now, -// since that is all that is strictly needed. In a future enhancement we will -// add human readable names as in the channelz.proto -typedef InlinedVector ChildRefsList; - namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 776c15138b8..9c7481e0c51 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3157,6 +3157,10 @@ static grpc_endpoint* chttp2_get_endpoint(grpc_transport* t) { return (reinterpret_cast(t))->ep; } +static intptr_t get_socket_uuid(grpc_transport* t) { + return grpc_chttp2_transport_get_socket_uuid(t); +} + static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), "chttp2", init_stream, @@ -3166,7 +3170,8 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), perform_transport_op, destroy_stream, destroy_transport, - chttp2_get_endpoint}; + chttp2_get_endpoint, + get_socket_uuid}; static const grpc_transport_vtable* get_vtable(void) { return &vtable; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 81e2634e3a7..e2faef2e9a8 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -1437,6 +1437,8 @@ static void destroy_transport(grpc_transport* gt) {} static grpc_endpoint* get_endpoint(grpc_transport* gt) { return nullptr; } +static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } + static void perform_op(grpc_transport* gt, grpc_transport_op* op) {} static const grpc_transport_vtable grpc_cronet_vtable = { @@ -1449,7 +1451,8 @@ static const grpc_transport_vtable grpc_cronet_vtable = { perform_op, destroy_stream, destroy_transport, - get_endpoint}; + get_endpoint, + get_socket_uuid}; grpc_transport* grpc_create_cronet_transport(void* engine, const char* target, const grpc_channel_args* args, diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index b0ca7f8207e..56951f83386 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1170,6 +1170,8 @@ static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, static grpc_endpoint* get_endpoint(grpc_transport* t) { return nullptr; } +static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } + /******************************************************************************* * GLOBAL INIT AND DESTROY */ @@ -1194,7 +1196,7 @@ static const grpc_transport_vtable inproc_vtable = { sizeof(inproc_stream), "inproc", init_stream, set_pollset, set_pollset_set, perform_stream_op, perform_transport_op, destroy_stream, destroy_transport, - get_endpoint}; + get_endpoint, get_socket_uuid}; /******************************************************************************* * Main inproc transport functions diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 339c827525c..c1194ae8721 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -36,6 +36,7 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" #include "src/core/lib/transport/error_utils.h" namespace grpc_core { @@ -149,8 +150,10 @@ RefCountedPtr ChannelNode::MakeChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } -ServerNode::ServerNode(size_t channel_tracer_max_nodes) - : BaseNode(EntityType::kServer), trace_(channel_tracer_max_nodes) {} +ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) + : BaseNode(EntityType::kServer), + server_(server), + trace_(channel_tracer_max_nodes) {} ServerNode::~ServerNode() {} @@ -182,6 +185,20 @@ grpc_json* ServerNode::RenderJson() { } // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); + json = top_level_json; + ChildRefsList listen_sockets; + grpc_server_populate_listen_sockets(server_, &listen_sockets); + if (!listen_sockets.empty()) { + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "listenSocket", nullptr, GRPC_JSON_ARRAY, false); + for (size_t i = 0; i < listen_sockets.size(); ++i) { + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", + listen_sockets[i]); + } + } return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index b7ae1012389..5edd90c8130 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -24,6 +24,7 @@ #include #include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -40,6 +41,12 @@ "grpc.channelz_channel_is_internal_channel" namespace grpc_core { + +// TODO(ncteisen), this only contains the uuids of the children for now, +// since that is all that is strictly needed. In a future enhancement we will +// add human readable names as in the channelz.proto +typedef InlinedVector ChildRefsList; + namespace channelz { namespace testing { @@ -172,7 +179,7 @@ class ChannelNode : public BaseNode { // Handles channelz bookkeeping for servers class ServerNode : public BaseNode { public: - explicit ServerNode(size_t channel_tracer_max_nodes); + explicit ServerNode(grpc_server* server, size_t channel_tracer_max_nodes); ~ServerNode() override; grpc_json* RenderJson() override; @@ -192,6 +199,7 @@ class ServerNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: + grpc_server* server_; CallCountingHelper call_counter_; ChannelTrace trace_; }; diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index e2ea334dedf..88e734a8a0d 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -36,6 +36,7 @@ typedef struct connected_channel_channel_data { grpc_transport* transport; + intptr_t socket_uuid; } channel_data; typedef struct { @@ -217,6 +218,7 @@ static void bind_transport(grpc_channel_stack* channel_stack, GPR_ASSERT(elem->filter == &grpc_connected_filter); GPR_ASSERT(cd->transport == nullptr); cd->transport = static_cast(t); + cd->socket_uuid = grpc_transport_get_socket_uuid(cd->transport); /* HACK(ctiller): increase call stack size for the channel to make space for channel data. We need a cleaner (but performant) way to do this, @@ -237,6 +239,13 @@ bool grpc_add_connected_filter(grpc_channel_stack_builder* builder, builder, &grpc_connected_filter, bind_transport, t); } +intptr_t grpc_connected_channel_get_socket_uuid( + grpc_channel_element* connected_channel_elem) { + channel_data* chand = + static_cast(connected_channel_elem->channel_data); + return chand->socket_uuid; +} + grpc_stream* grpc_connected_channel_get_stream(grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); return TRANSPORT_STREAM_FROM_CALL_DATA(calld); diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h index faa1c73a21f..b5389c4e4cd 100644 --- a/src/core/lib/channel/connected_channel.h +++ b/src/core/lib/channel/connected_channel.h @@ -28,6 +28,9 @@ extern const grpc_channel_filter grpc_connected_filter; bool grpc_add_connected_filter(grpc_channel_stack_builder* builder, void* arg_must_be_null); +intptr_t grpc_connected_channel_get_socket_uuid( + grpc_channel_element* connected_channel_elem); + /* Debug helper to dig the transport stream out of a call element */ grpc_stream* grpc_connected_channel_get_stream(grpc_call_element* elem); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 72ddc2648d9..a35d60e275e 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1015,7 +1015,7 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); server->channelz_server = grpc_core::MakeRefCounted( - trace_events_per_node); + server, trace_events_per_node); server->channelz_server->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Server created")); @@ -1212,6 +1212,22 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, grpc_transport_perform_op(transport, op); } +void grpc_server_populate_listen_sockets( + grpc_server* s, grpc_core::ChildRefsList* listen_sockets) { + gpr_mu_lock(&s->mu_global); + channel_data* c = nullptr; + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { + if (c->channel != nullptr) { + grpc_channel_element* connected_channel_elem = + grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(c->channel)); + listen_sockets->push_back( + grpc_connected_channel_get_socket_uuid(connected_channel_elem)); + } + } + gpr_mu_unlock(&s->mu_global); +} + void done_published_shutdown(void* done_arg, grpc_cq_completion* storage) { (void)done_arg; gpr_free(storage); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 0196743ff9d..db47d8032b9 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -47,6 +47,9 @@ void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args); +void grpc_server_populate_listen_sockets( + grpc_server* server, grpc_core::ChildRefsList* listen_sockets); + grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( grpc_server* server); diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index cbdb77c8441..c8fdbb4de26 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -199,6 +199,10 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { return transport->vtable->get_endpoint(transport); } +intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport) { + return transport->vtable->get_socket_uuid(transport); +} + // This comment should be sung to the tune of // "Supercalifragilisticexpialidocious": // diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 9e784635c69..9eaea2dca53 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -366,6 +366,9 @@ void grpc_transport_destroy(grpc_transport* transport); /* Get the endpoint used by \a transport */ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport); +/* Get the socket uuid used by the transport. Returns 0 if not availible. */ +intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport); + /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to \a on_consumed and then delete the returned transport op */ grpc_transport_op* grpc_make_transport_op(grpc_closure* on_consumed); diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index ba5e05df0af..d609470ef01 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -60,6 +60,8 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* (*get_endpoint)(grpc_transport* self); + + intptr_t (*get_socket_uuid)(grpc_transport* self); } grpc_transport_vtable; /* an instance of a grpc transport */ diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 40a0370f0ea..678163e1f28 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -252,6 +252,8 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"listenSocket\"")); + GPR_ASSERT(nullptr != strstr(json, "\"socketId\"")); // channel tracing is not enabled, so these should not be preset. GPR_ASSERT(nullptr == strstr(json, "\"trace\"")); GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\"")); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 9516b2e3e25..f9b5f21c340 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -446,11 +446,13 @@ void Destroy(grpc_transport* self) {} /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* GetEndpoint(grpc_transport* self) { return nullptr; } +static intptr_t GetSocketUuid(grpc_transport* t) { return 0; } + static const grpc_transport_vtable dummy_transport_vtable = { - 0, "dummy_http2", InitStream, - SetPollset, SetPollsetSet, PerformStreamOp, - PerformOp, DestroyStream, Destroy, - GetEndpoint}; + 0, "dummy_http2", InitStream, + SetPollset, SetPollsetSet, PerformStreamOp, + PerformOp, DestroyStream, Destroy, + GetEndpoint, GetSocketUuid}; static grpc_transport dummy_transport = {&dummy_transport_vtable};