1 // Copyright 2021 TiKV Project Authors. Licensed under Apache-2.0.
2
3 //! Channelz provides channel level debug information. In short, There are four types of
4 //! top level entities: channel, subchannel, socket and server. All entities are
5 //! identified by an positive unique integer, which is allocated in order. For more
6 //! explanation, see https://github.com/grpc/proposal/blob/master/A14-channelz.md.
7 //!
8 //! A full support requires a service that allow remote querying. But for now it's
9 //! too complicated to add full support. Because gRPC C core exposes the information
10 //! using JSON format, and there is no protobuf library that supports parsing json
11 //! format in Rust. So this module only provides safe APIs to access the informations.
12
13 use std::ffi::CStr;
14 use std::{cmp, str};
15
16 macro_rules! visit {
17 ($ptr:expr, $visitor:ident) => {{
18 let s_ptr = $ptr;
19 let res;
20 if !s_ptr.is_null() {
21 let c_s = CStr::from_ptr(s_ptr);
22 // It's json string, so it must be utf8 compatible.
23 let s = str::from_utf8_unchecked(c_s.to_bytes());
24 res = $visitor(s);
25 grpcio_sys::gpr_free(s_ptr as _);
26 } else {
27 res = $visitor("");
28 }
29 res
30 }};
31 }
32
33 /// Gets all root channels (i.e. channels the application has directly created). This
34 /// does not include subchannels nor non-top level channels.
get_top_channels<V, R>(start_channel_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,35 pub fn get_top_channels<V, R>(start_channel_id: u64, visitor: V) -> R
36 where
37 V: FnOnce(&str) -> R,
38 {
39 unsafe {
40 visit!(
41 grpcio_sys::grpc_channelz_get_top_channels(start_channel_id as _),
42 visitor
43 )
44 }
45 }
46
47 /// Gets all servers that exist in the process.
get_servers<V, R>(start_server_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,48 pub fn get_servers<V, R>(start_server_id: u64, visitor: V) -> R
49 where
50 V: FnOnce(&str) -> R,
51 {
52 unsafe {
53 visit!(
54 grpcio_sys::grpc_channelz_get_servers(start_server_id as _),
55 visitor
56 )
57 }
58 }
59
60 /// Returns a single Server, or else an empty string.
get_server<V, R>(server_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,61 pub fn get_server<V, R>(server_id: u64, visitor: V) -> R
62 where
63 V: FnOnce(&str) -> R,
64 {
65 unsafe {
66 visit!(
67 grpcio_sys::grpc_channelz_get_server(server_id as _),
68 visitor
69 )
70 }
71 }
72
73 /// Gets all server sockets that exist in the server.
get_server_sockets<V, R>( server_id: u64, start_socket_id: u64, max_results: usize, visitor: V, ) -> R where V: FnOnce(&str) -> R,74 pub fn get_server_sockets<V, R>(
75 server_id: u64,
76 start_socket_id: u64,
77 max_results: usize,
78 visitor: V,
79 ) -> R
80 where
81 V: FnOnce(&str) -> R,
82 {
83 let max_results = cmp::min(isize::MAX as usize, max_results) as isize;
84 unsafe {
85 visit!(
86 grpcio_sys::grpc_channelz_get_server_sockets(
87 server_id as _,
88 start_socket_id as _,
89 max_results
90 ),
91 visitor
92 )
93 }
94 }
95
96 /// Returns a single Channel, or else an empty string.
get_channel<V, R>(channel_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,97 pub fn get_channel<V, R>(channel_id: u64, visitor: V) -> R
98 where
99 V: FnOnce(&str) -> R,
100 {
101 unsafe {
102 visit!(
103 grpcio_sys::grpc_channelz_get_channel(channel_id as _),
104 visitor
105 )
106 }
107 }
108
109 /// Returns a single Subchannel, or else an empty string.
get_subchannel<V, R>(subchannel_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,110 pub fn get_subchannel<V, R>(subchannel_id: u64, visitor: V) -> R
111 where
112 V: FnOnce(&str) -> R,
113 {
114 unsafe {
115 visit!(
116 grpcio_sys::grpc_channelz_get_subchannel(subchannel_id as _),
117 visitor
118 )
119 }
120 }
121
122 /// Returns a single Socket, or else an empty string.
get_socket<V, R>(socket_id: u64, visitor: V) -> R where V: FnOnce(&str) -> R,123 pub fn get_socket<V, R>(socket_id: u64, visitor: V) -> R
124 where
125 V: FnOnce(&str) -> R,
126 {
127 unsafe {
128 visit!(
129 grpcio_sys::grpc_channelz_get_socket(socket_id as _),
130 visitor
131 )
132 }
133 }
134