GRPC Core  18.0.0
channelz.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2018 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 
19 #ifndef GRPC_CORE_LIB_CHANNEL_CHANNELZ_H
20 #define GRPC_CORE_LIB_CHANNEL_CHANNELZ_H
21 
23 
24 #include <grpc/grpc.h>
25 
26 #include <set>
27 #include <string>
28 
29 #include "absl/container/inlined_vector.h"
30 #include "absl/types/optional.h"
31 
41 #include "src/core/lib/json/json.h"
42 
43 // Channel arg key for channelz node.
44 #define GRPC_ARG_CHANNELZ_CHANNEL_NODE "grpc.channelz_channel_node"
45 
46 // Channel arg key for indicating an internal channel.
47 #define GRPC_ARG_CHANNELZ_IS_INTERNAL_CHANNEL \
48  "grpc.channelz_is_internal_channel"
49 
52 #define GRPC_ENABLE_CHANNELZ_DEFAULT true
53 
58 #define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT (1024 * 4)
59 
60 namespace grpc_core {
61 
62 namespace channelz {
63 
64 class SocketNode;
65 class ListenSocketNode;
66 
67 namespace testing {
68 class CallCountingHelperPeer;
69 class ChannelNodePeer;
70 } // namespace testing
71 
72 // base class for all channelz entities
73 class BaseNode : public RefCounted<BaseNode> {
74  public:
75  // There are only four high level channelz entities. However, to support
76  // GetTopChannelsRequest, we split the Channel entity into two different
77  // types. All children of BaseNode must be one of these types.
78  enum class EntityType {
82  kServer,
83  kSocket,
84  };
85 
86  protected:
87  BaseNode(EntityType type, std::string name);
88 
89  public:
90  ~BaseNode() override;
91 
92  // All children must implement this function.
93  virtual Json RenderJson() = 0;
94 
95  // Renders the json and returns allocated string that must be freed by the
96  // caller.
97  std::string RenderJsonString();
98 
99  EntityType type() const { return type_; }
100  intptr_t uuid() const { return uuid_; }
101  const std::string& name() const { return name_; }
102 
103  private:
104  // to allow the ChannelzRegistry to set uuid_ under its lock.
105  friend class ChannelzRegistry;
106  const EntityType type_;
107  intptr_t uuid_;
108  std::string name_;
109 };
110 
111 // This class is a helper class for channelz entities that deal with Channels,
112 // Subchannels, and Servers, since those have similar proto definitions.
113 // This class has the ability to:
114 // - track calls_{started,succeeded,failed}
115 // - track last_call_started_timestamp
116 // - perform rendering of the above items
118  public:
120 
121  void RecordCallStarted();
122  void RecordCallFailed();
123  void RecordCallSucceeded();
124 
125  // Common rendering of the call count data and last_call_started_timestamp.
126  void PopulateCallCounts(Json::Object* json);
127 
128  private:
129  // testing peer friend.
131 
132  // TODO(soheil): add a proper PerCPU helper and use it here.
133  struct AtomicCounterData {
134  // Define the ctors so that we can use this structure in InlinedVector.
135  AtomicCounterData() = default;
136  AtomicCounterData(const AtomicCounterData& that)
137  : calls_started(that.calls_started.Load(MemoryOrder::RELAXED)),
138  calls_succeeded(that.calls_succeeded.Load(MemoryOrder::RELAXED)),
139  calls_failed(that.calls_failed.Load(MemoryOrder::RELAXED)),
140  last_call_started_cycle(
141  that.last_call_started_cycle.Load(MemoryOrder::RELAXED)) {}
142 
143  Atomic<int64_t> calls_started{0};
144  Atomic<int64_t> calls_succeeded{0};
145  Atomic<int64_t> calls_failed{0};
146  Atomic<gpr_cycle_counter> last_call_started_cycle{0};
147  // Make sure the size is exactly one cache line.
148  uint8_t padding[GPR_CACHELINE_SIZE - 3 * sizeof(Atomic<intptr_t>) -
149  sizeof(Atomic<gpr_cycle_counter>)];
150  };
151  // TODO(soheilhy,veblush): Revist this after abseil integration.
152  // This has a problem when using abseil inlined_vector because it
153  // carries an alignment attribute properly but our allocator doesn't
154  // respect this. To avoid UBSAN errors, this should be removed with
155  // abseil inlined_vector.
156  // GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE);
157 
158  struct CounterData {
159  int64_t calls_started = 0;
160  int64_t calls_succeeded = 0;
161  int64_t calls_failed = 0;
162  gpr_cycle_counter last_call_started_cycle = 0;
163  };
164 
165  // collects the sharded data into one CounterData struct.
166  void CollectData(CounterData* out);
167 
168  // Really zero-sized, but 0-sized arrays are illegal on MSVC.
169  absl::InlinedVector<AtomicCounterData, 1> per_cpu_counter_data_storage_;
170  size_t num_cores_ = 0;
171 };
172 
173 // Handles channelz bookkeeping for channels
174 class ChannelNode : public BaseNode {
175  public:
176  ChannelNode(std::string target, size_t channel_tracer_max_nodes,
177  bool is_internal_channel);
178 
179  // Returns the string description of the given connectivity state.
180  static const char* GetChannelConnectivityStateChangeString(
182 
183  Json RenderJson() override;
184 
185  // proxy methods to composed classes.
186  void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
187  trace_.AddTraceEvent(severity, data);
188  }
190  const grpc_slice& data,
191  RefCountedPtr<BaseNode> referenced_channel) {
192  trace_.AddTraceEventWithReference(severity, data,
193  std::move(referenced_channel));
194  }
195  void RecordCallStarted() { call_counter_.RecordCallStarted(); }
196  void RecordCallFailed() { call_counter_.RecordCallFailed(); }
197  void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
198 
200 
201  // TODO(roth): take in a RefCountedPtr to the child channel so we can retrieve
202  // the human-readable name.
203  void AddChildChannel(intptr_t child_uuid);
204  void RemoveChildChannel(intptr_t child_uuid);
205 
206  // TODO(roth): take in a RefCountedPtr to the child subchannel so we can
207  // retrieve the human-readable name.
208  void AddChildSubchannel(intptr_t child_uuid);
209  void RemoveChildSubchannel(intptr_t child_uuid);
210 
211  private:
212  // Allows the channel trace test to access trace_.
214 
215  void PopulateChildRefs(Json::Object* json);
216 
217  std::string target_;
218  CallCountingHelper call_counter_;
219  ChannelTrace trace_;
220 
221  // Least significant bit indicates whether the value is set. Remaining
222  // bits are a grpc_connectivity_state value.
223  Atomic<int> connectivity_state_{0};
224 
225  Mutex child_mu_; // Guards sets below.
226  std::set<intptr_t> child_channels_;
227  std::set<intptr_t> child_subchannels_;
228 };
229 
230 // Handles channelz bookkeeping for servers
231 class ServerNode : public BaseNode {
232  public:
233  explicit ServerNode(size_t channel_tracer_max_nodes);
234 
235  ~ServerNode() override;
236 
237  Json RenderJson() override;
238 
239  std::string RenderServerSockets(intptr_t start_socket_id,
240  intptr_t max_results);
241 
243 
244  void RemoveChildSocket(intptr_t child_uuid);
245 
247 
248  void RemoveChildListenSocket(intptr_t child_uuid);
249 
250  // proxy methods to composed classes.
251  void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) {
252  trace_.AddTraceEvent(severity, data);
253  }
255  const grpc_slice& data,
256  RefCountedPtr<BaseNode> referenced_channel) {
257  trace_.AddTraceEventWithReference(severity, data,
258  std::move(referenced_channel));
259  }
260  void RecordCallStarted() { call_counter_.RecordCallStarted(); }
261  void RecordCallFailed() { call_counter_.RecordCallFailed(); }
262  void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); }
263 
264  private:
265  CallCountingHelper call_counter_;
266  ChannelTrace trace_;
267  Mutex child_mu_; // Guards child maps below.
268  std::map<intptr_t, RefCountedPtr<SocketNode>> child_sockets_;
269  std::map<intptr_t, RefCountedPtr<ListenSocketNode>> child_listen_sockets_;
270 };
271 
272 #define GRPC_ARG_CHANNELZ_SECURITY "grpc.internal.channelz_security"
273 
274 // Handles channelz bookkeeping for sockets
275 class SocketNode : public BaseNode {
276  public:
277  struct Security : public RefCounted<Security> {
278  struct Tls {
279  // This is a workaround for https://bugs.llvm.org/show_bug.cgi?id=50346
280  Tls() {}
281 
282  enum class NameType { kUnset = 0, kStandardName = 1, kOtherName = 2 };
284  // Holds the value of standard_name or other_names if type is not kUnset.
285  std::string name;
286  std::string local_certificate;
287  std::string remote_certificate;
288 
289  Json RenderJson();
290  };
291  enum class ModelType { kUnset = 0, kTls = 1, kOther = 2 };
293  absl::optional<Tls> tls;
294  absl::optional<Json> other;
295 
296  Json RenderJson();
297 
298  grpc_arg MakeChannelArg() const;
299 
301  const grpc_channel_args* args);
302  };
303 
304  SocketNode(std::string local, std::string remote, std::string name,
305  RefCountedPtr<Security> security);
306  ~SocketNode() override {}
307 
308  Json RenderJson() override;
309 
313  streams_succeeded_.FetchAdd(1, MemoryOrder::RELAXED);
314  }
316  streams_failed_.FetchAdd(1, MemoryOrder::RELAXED);
317  }
318  void RecordMessagesSent(uint32_t num_sent);
319  void RecordMessageReceived();
321  keepalives_sent_.FetchAdd(1, MemoryOrder::RELAXED);
322  }
323 
324  const std::string& remote() { return remote_; }
325 
326  private:
327  Atomic<int64_t> streams_started_{0};
328  Atomic<int64_t> streams_succeeded_{0};
329  Atomic<int64_t> streams_failed_{0};
330  Atomic<int64_t> messages_sent_{0};
331  Atomic<int64_t> messages_received_{0};
332  Atomic<int64_t> keepalives_sent_{0};
333  Atomic<gpr_cycle_counter> last_local_stream_created_cycle_{0};
334  Atomic<gpr_cycle_counter> last_remote_stream_created_cycle_{0};
335  Atomic<gpr_cycle_counter> last_message_sent_cycle_{0};
336  Atomic<gpr_cycle_counter> last_message_received_cycle_{0};
337  std::string local_;
338  std::string remote_;
339  RefCountedPtr<Security> const security_;
340 };
341 
342 // Handles channelz bookkeeping for listen sockets
343 class ListenSocketNode : public BaseNode {
344  public:
345  ListenSocketNode(std::string local_addr, std::string name);
346  ~ListenSocketNode() override {}
347 
348  Json RenderJson() override;
349 
350  private:
351  std::string local_addr_;
352 };
353 
354 } // namespace channelz
355 } // namespace grpc_core
356 
357 #endif /* GRPC_CORE_LIB_CHANNEL_CHANNELZ_H */
T FetchAdd(Arg arg, MemoryOrder order=MemoryOrder::SEQ_CST)
Definition: atomic.h:71
Definition: json.h:38
std::map< std::string, Json > Object
Definition: json.h:55
Definition: sync.h:59
Definition: ref_counted.h:282
Definition: ref_counted_ptr.h:35
Definition: channelz.h:73
intptr_t uuid() const
Definition: channelz.h:100
EntityType
Definition: channelz.h:78
~BaseNode() override
Definition: channelz.cc:67
EntityType type() const
Definition: channelz.h:99
const std::string & name() const
Definition: channelz.h:101
BaseNode(EntityType type, std::string name)
Definition: channelz.cc:61
std::string RenderJsonString()
Definition: channelz.cc:69
Definition: channelz.h:117
CallCountingHelper()
Definition: channelz.cc:78
friend class testing::CallCountingHelperPeer
Definition: channelz.h:130
void RecordCallSucceeded()
Definition: channelz.cc:99
void PopulateCallCounts(Json::Object *json)
Definition: channelz.cc:123
void RecordCallFailed()
Definition: channelz.cc:94
void RecordCallStarted()
Definition: channelz.cc:86
Definition: channelz.h:174
void RemoveChildChannel(intptr_t child_uuid)
Definition: channelz.cc:238
Json RenderJson() override
Definition: channelz.cc:170
void RemoveChildSubchannel(intptr_t child_uuid)
Definition: channelz.cc:248
void AddChildSubchannel(intptr_t child_uuid)
Definition: channelz.cc:243
void RecordCallStarted()
Definition: channelz.h:195
void AddTraceEventWithReference(ChannelTrace::Severity severity, const grpc_slice &data, RefCountedPtr< BaseNode > referenced_channel)
Definition: channelz.h:189
friend class testing::ChannelNodePeer
Definition: channelz.h:213
static const char * GetChannelConnectivityStateChangeString(grpc_connectivity_state state)
Definition: channelz.cc:153
ChannelNode(std::string target, size_t channel_tracer_max_nodes, bool is_internal_channel)
Definition: channelz.cc:145
void RecordCallFailed()
Definition: channelz.h:196
void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice &data)
Definition: channelz.h:186
void RecordCallSucceeded()
Definition: channelz.h:197
void AddChildChannel(intptr_t child_uuid)
Definition: channelz.cc:233
void SetConnectivityState(grpc_connectivity_state state)
Definition: channelz.cc:227
Definition: channel_trace.h:42
Severity
Definition: channel_trace.h:47
void AddTraceEventWithReference(Severity severity, const grpc_slice &data, RefCountedPtr< BaseNode > referenced_entity)
Definition: channel_trace.cc:120
void AddTraceEvent(Severity severity, const grpc_slice &data)
Definition: channel_trace.cc:112
Definition: channelz_registry.h:38
Definition: channelz.h:343
Json RenderJson() override
Definition: channelz.cc:579
~ListenSocketNode() override
Definition: channelz.h:346
ListenSocketNode(std::string local_addr, std::string name)
Definition: channelz.cc:575
Definition: channelz.h:231
std::string RenderServerSockets(intptr_t start_socket_id, intptr_t max_results)
Definition: channelz.cc:282
void AddChildSocket(RefCountedPtr< SocketNode > node)
Definition: channelz.cc:262
ServerNode(size_t channel_tracer_max_nodes)
Definition: channelz.cc:257
Json RenderJson() override
Definition: channelz.cc:309
void RemoveChildSocket(intptr_t child_uuid)
Definition: channelz.cc:267
void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice &data)
Definition: channelz.h:251
void RemoveChildListenSocket(intptr_t child_uuid)
Definition: channelz.cc:277
void RecordCallFailed()
Definition: channelz.h:261
void AddTraceEventWithReference(ChannelTrace::Severity severity, const grpc_slice &data, RefCountedPtr< BaseNode > referenced_channel)
Definition: channelz.h:254
void RecordCallSucceeded()
Definition: channelz.h:262
~ServerNode() override
Definition: channelz.cc:260
void RecordCallStarted()
Definition: channelz.h:260
void AddChildListenSocket(RefCountedPtr< ListenSocketNode > node)
Definition: channelz.cc:272
Definition: channelz.h:275
void RecordMessageReceived()
Definition: channelz.cc:493
void RecordStreamSucceeded()
Definition: channelz.h:312
void RecordStreamFailed()
Definition: channelz.h:315
Json RenderJson() override
Definition: channelz.cc:499
void RecordStreamStartedFromRemote()
Definition: channelz.cc:482
void RecordStreamStartedFromLocal()
Definition: channelz.cc:476
const std::string & remote()
Definition: channelz.h:324
void RecordMessagesSent(uint32_t num_sent)
Definition: channelz.cc:488
SocketNode(std::string local, std::string remote, std::string name, RefCountedPtr< Security > security)
Definition: channelz.cc:469
void RecordKeepaliveSent()
Definition: channelz.h:320
~SocketNode() override
Definition: channelz.h:306
#define GPR_CACHELINE_SIZE
Definition: port_platform.h:476
grpc_connectivity_state
Connectivity state of a channel.
Definition: connectivity_state.h:27
Round Robin Policy.
Definition: backend_metric.cc:26
MemoryOrder
Definition: atomic.h:30
A single argument...
Definition: grpc_types.h:103
An array of arguments that can be passed around.
Definition: grpc_types.h:132
NameType type
Definition: channelz.h:283
Json RenderJson()
Definition: channelz.cc:347
std::string local_certificate
Definition: channelz.h:286
std::string name
Definition: channelz.h:285
std::string remote_certificate
Definition: channelz.h:287
ModelType type
Definition: channelz.h:292
absl::optional< Tls > tls
Definition: channelz.h:293
static RefCountedPtr< Security > GetFromChannelArgs(const grpc_channel_args *args)
Definition: channelz.cc:413
Json RenderJson()
Definition: channelz.cc:367
grpc_arg MakeChannelArg() const
Definition: channelz.cc:407
ModelType
Definition: channelz.h:291
absl::optional< Json > other
Definition: channelz.h:294
A grpc_slice s, if initialized, represents the byte range s.bytes[0..s.length-1].
Definition: slice.h:60