channelz_registry.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <algorithm>
24 #include <cstdint>
25 #include <cstring>
26 #include <utility>
27 #include <vector>
28 
29 #include <grpc/grpc.h>
30 #include <grpc/support/log.h>
32 
36 #include "src/core/lib/json/json.h"
37 
38 namespace grpc_core {
39 namespace channelz {
40 namespace {
41 
42 const int kPaginationLimit = 100;
43 
44 } // anonymous namespace
45 
47  static ChannelzRegistry* singleton = new ChannelzRegistry();
48  return singleton;
49 }
50 
52  MutexLock lock(&mu_);
53  node->uuid_ = ++uuid_generator_;
54  node_map_[node->uuid_] = node;
55 }
56 
58  GPR_ASSERT(uuid >= 1);
59  MutexLock lock(&mu_);
60  GPR_ASSERT(uuid <= uuid_generator_);
61  node_map_.erase(uuid);
62 }
63 
65  MutexLock lock(&mu_);
66  if (uuid < 1 || uuid > uuid_generator_) {
67  return nullptr;
68  }
69  auto it = node_map_.find(uuid);
70  if (it == node_map_.end()) return nullptr;
71  // Found node. Return only if its refcount is not zero (i.e., when we
72  // know that there is no other thread about to destroy it).
73  BaseNode* node = it->second;
74  return node->RefIfNonZero();
75 }
76 
78  intptr_t start_channel_id) {
79  std::vector<RefCountedPtr<BaseNode>> top_level_channels;
80  RefCountedPtr<BaseNode> node_after_pagination_limit;
81  {
82  MutexLock lock(&mu_);
83  for (auto it = node_map_.lower_bound(start_channel_id);
84  it != node_map_.end(); ++it) {
85  BaseNode* node = it->second;
86  RefCountedPtr<BaseNode> node_ref;
88  (node_ref = node->RefIfNonZero()) != nullptr) {
89  // Check if we are over pagination limit to determine if we need to set
90  // the "end" element. If we don't go through this block, we know that
91  // when the loop terminates, we have <= to kPaginationLimit.
92  // Note that because we have already increased this node's
93  // refcount, we need to decrease it, but we can't unref while
94  // holding the lock, because this may lead to a deadlock.
95  if (top_level_channels.size() == kPaginationLimit) {
96  node_after_pagination_limit = std::move(node_ref);
97  break;
98  }
99  top_level_channels.emplace_back(std::move(node_ref));
100  }
101  }
102  }
103  Json::Object object;
104  if (!top_level_channels.empty()) {
105  // Create list of channels.
107  for (size_t i = 0; i < top_level_channels.size(); ++i) {
108  array.emplace_back(top_level_channels[i]->RenderJson());
109  }
110  object["channel"] = std::move(array);
111  }
112  if (node_after_pagination_limit == nullptr) object["end"] = true;
113  Json json(std::move(object));
114  return json.Dump();
115 }
116 
118  std::vector<RefCountedPtr<BaseNode>> servers;
119  RefCountedPtr<BaseNode> node_after_pagination_limit;
120  {
121  MutexLock lock(&mu_);
122  for (auto it = node_map_.lower_bound(start_server_id);
123  it != node_map_.end(); ++it) {
124  BaseNode* node = it->second;
125  RefCountedPtr<BaseNode> node_ref;
126  if (node->type() == BaseNode::EntityType::kServer &&
127  (node_ref = node->RefIfNonZero()) != nullptr) {
128  // Check if we are over pagination limit to determine if we need to set
129  // the "end" element. If we don't go through this block, we know that
130  // when the loop terminates, we have <= to kPaginationLimit.
131  // Note that because we have already increased this node's
132  // refcount, we need to decrease it, but we can't unref while
133  // holding the lock, because this may lead to a deadlock.
134  if (servers.size() == kPaginationLimit) {
135  node_after_pagination_limit = std::move(node_ref);
136  break;
137  }
138  servers.emplace_back(std::move(node_ref));
139  }
140  }
141  }
142  Json::Object object;
143  if (!servers.empty()) {
144  // Create list of servers.
146  for (size_t i = 0; i < servers.size(); ++i) {
147  array.emplace_back(servers[i]->RenderJson());
148  }
149  object["server"] = std::move(array);
150  }
151  if (node_after_pagination_limit == nullptr) object["end"] = true;
152  Json json(std::move(object));
153  return json.Dump();
154 }
155 
157  std::vector<RefCountedPtr<BaseNode>> nodes;
158  {
159  MutexLock lock(&mu_);
160  for (auto& p : node_map_) {
161  RefCountedPtr<BaseNode> node = p.second->RefIfNonZero();
162  if (node != nullptr) {
163  nodes.emplace_back(std::move(node));
164  }
165  }
166  }
167  for (size_t i = 0; i < nodes.size(); ++i) {
168  std::string json = nodes[i]->RenderJsonString();
169  gpr_log(GPR_INFO, "%s", json.c_str());
170  }
171 }
172 
173 } // namespace channelz
174 } // namespace grpc_core
175 
176 char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
177  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
179  return gpr_strdup(
181  .c_str());
182 }
183 
184 char* grpc_channelz_get_servers(intptr_t start_server_id) {
185  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
187  return gpr_strdup(
189  .c_str());
190 }
191 
193  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
197  if (server_node == nullptr ||
198  server_node->type() !=
200  return nullptr;
201  }
203  {"server", server_node->RenderJson()},
204  };
205  return gpr_strdup(json.Dump().c_str());
206 }
207 
209  intptr_t start_socket_id,
210  intptr_t max_results) {
211  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
213  // Validate inputs before handing them of to the renderer.
216  if (base_node == nullptr ||
218  start_socket_id < 0 || max_results < 0) {
219  return nullptr;
220  }
221  // This cast is ok since we have just checked to make sure base_node is
222  // actually a server node.
223  grpc_core::channelz::ServerNode* server_node =
224  static_cast<grpc_core::channelz::ServerNode*>(base_node.get());
225  return gpr_strdup(
226  server_node->RenderServerSockets(start_socket_id, max_results).c_str());
227 }
228 
230  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
234  if (channel_node == nullptr ||
235  (channel_node->type() !=
237  channel_node->type() !=
239  return nullptr;
240  }
242  {"channel", channel_node->RenderJson()},
243  };
244  return gpr_strdup(json.Dump().c_str());
245 }
246 
248  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
252  if (subchannel_node == nullptr ||
253  subchannel_node->type() !=
255  return nullptr;
256  }
258  {"subchannel", subchannel_node->RenderJson()},
259  };
260  return gpr_strdup(json.Dump().c_str());
261 }
262 
264  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
268  if (socket_node == nullptr ||
269  socket_node->type() !=
271  return nullptr;
272  }
274  {"socket", socket_node->RenderJson()},
275  };
276  return gpr_strdup(json.Dump().c_str());
277 }
grpc_core::Json::Array
std::vector< Json > Array
Definition: src/core/lib/json/json.h:55
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
regen-readme.it
it
Definition: regen-readme.py:15
grpc_core::channelz::ChannelzRegistry
Definition: channelz_registry.h:37
log.h
grpc_core::channelz::ChannelzRegistry::Get
static RefCountedPtr< BaseNode > Get(intptr_t uuid)
Definition: channelz_registry.h:43
grpc_channelz_get_channel
char * grpc_channelz_get_channel(intptr_t channel_id)
Definition: channelz_registry.cc:229
grpc_core::RefCountedPtr::get
T * get() const
Definition: ref_counted_ptr.h:146
grpc_core::RefCounted::RefIfNonZero
RefCountedPtr< Child > RefIfNonZero() GRPC_MUST_USE_RESULT
Definition: ref_counted.h:313
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
grpc_core::channelz::ChannelzRegistry::GetServers
static std::string GetServers(intptr_t start_server_id)
Definition: channelz_registry.h:55
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:111
grpc_core::channelz::BaseNode::EntityType::kSubchannel
@ kSubchannel
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_core::channelz::BaseNode::type
EntityType type() const
Definition: channelz.h:104
grpc_core::channelz::ChannelzRegistry::mu_
Mutex mu_
Definition: channelz_registry.h:92
grpc_core::ApplicationCallbackExecCtx
Definition: exec_ctx.h:283
grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel
@ kTopLevelChannel
channelz.h
grpc_core::channelz::ServerNode
Definition: channelz.h:239
grpc_core::channelz::ChannelzRegistry::Default
static ChannelzRegistry * Default()
Definition: channelz_registry.cc:46
string_util.h
channelz_registry.h
grpc_core::RefCountedPtr
Definition: ref_counted_ptr.h:35
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
array
Definition: undname.c:101
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
grpc_core::channelz::ChannelzRegistry::uuid_generator_
intptr_t uuid_generator_
Definition: channelz_registry.h:94
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc_core::channelz::ChannelzRegistry::InternalGetTopChannels
std::string InternalGetTopChannels(intptr_t start_channel_id)
Definition: channelz_registry.cc:77
grpc.h
grpc_core::channelz::BaseNode::uuid_
intptr_t uuid_
Definition: channelz.h:112
grpc_core::channelz::ChannelzRegistry::InternalLogAllEntities
void InternalLogAllEntities()
Definition: channelz_registry.cc:156
grpc_core::channelz::BaseNode
Definition: channelz.h:78
grpc_core::channelz::ChannelzRegistry::InternalGetServers
std::string InternalGetServers(intptr_t start_server_id)
Definition: channelz_registry.cc:117
grpc_core::channelz::ChannelzRegistry::GetTopChannels
static std::string GetTopChannels(intptr_t start_channel_id)
Definition: channelz_registry.h:49
grpc_channelz_get_server_sockets
char * grpc_channelz_get_server_sockets(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results)
Definition: channelz_registry.cc:208
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
json.h
grpc_core::ExecCtx
Definition: exec_ctx.h:97
grpc_channelz_get_server
char * grpc_channelz_get_server(intptr_t server_id)
Definition: channelz_registry.cc:192
grpc_core::channelz::BaseNode::EntityType::kInternalChannel
@ kInternalChannel
grpc_core::channelz::ChannelzRegistry::node_map_
std::map< intptr_t, BaseNode * > node_map_
Definition: channelz_registry.h:93
grpc_core::channelz::BaseNode::EntityType::kSocket
@ kSocket
grpc_core::Json::Object
std::map< std::string, Json > Object
Definition: src/core/lib/json/json.h:54
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
grpc_core::channelz::ChannelzRegistry::InternalGet
RefCountedPtr< BaseNode > InternalGet(intptr_t uuid)
Definition: channelz_registry.cc:64
grpc_core::channelz::ChannelzRegistry::InternalRegister
void InternalRegister(BaseNode *node)
Definition: channelz_registry.cc:51
grpc_channelz_get_top_channels
char * grpc_channelz_get_top_channels(intptr_t start_channel_id)
Definition: channelz_registry.cc:176
grpc_core::channelz::ServerNode::RenderServerSockets
std::string RenderServerSockets(intptr_t start_socket_id, intptr_t max_results)
Definition: src/core/lib/channel/channelz.cc:280
exec_ctx.h
channelz
void channelz(grpc_end2end_test_config config)
Definition: test/core/end2end/tests/channelz.cc:318
grpc_channelz_get_subchannel
char * grpc_channelz_get_subchannel(intptr_t subchannel_id)
Definition: channelz_registry.cc:247
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
grpc_core::Json
Definition: src/core/lib/json/json.h:37
grpc_channelz_get_socket
char * grpc_channelz_get_socket(intptr_t socket_id)
Definition: channelz_registry.cc:263
grpc_core::channelz::BaseNode::RenderJson
virtual Json RenderJson()=0
grpc_channelz_get_servers
char * grpc_channelz_get_servers(intptr_t start_server_id)
Definition: channelz_registry.cc:184
sync.h
grpc_core::Json::Dump
std::string Dump(int indent=0) const
Definition: json_writer.cc:336
grpc_core::channelz::ChannelzRegistry::InternalUnregister
void InternalUnregister(intptr_t uuid)
Definition: channelz_registry.cc:57
run_interop_tests.servers
servers
Definition: run_interop_tests.py:1288
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
port_platform.h
grpc_core::channelz::BaseNode::EntityType::kServer
@ kServer


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:53