1#[derive(Copy, Clone, Eq, PartialEq, Debug)]
16pub enum StatsMetricType {
17 Counter,
19 Gauge,
21 Timestamp,
23}
24
25#[derive(Copy, Clone, Eq, PartialEq, Debug)]
36pub struct MetricSpec {
37 pub name: &'static str,
39 pub kind: StatsMetricType,
41 pub description: &'static str,
43}
44
45macro_rules! define_codec {
46 (
47 $enum_name:ident, $codec_const:ident,
48 $codec_doc:literal,
49 $variant_doc:literal,
50 { $( $variant:ident, $name:literal, $kind:ident, $desc:literal );* $(;)? }
51 ) => {
52 #[doc = $variant_doc]
53 #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
58 #[repr(usize)]
59 pub enum $enum_name {
60 $(
61 #[doc = $desc]
62 $variant
63 ),*
64 }
65
66 impl $enum_name {
67 #[doc = concat!(
72 "```\nuse dynomite::stats::", stringify!($enum_name),
73 ";\nassert!(!", stringify!($enum_name), "::ALL.is_empty());\n```"
74 )]
75 pub const ALL: &'static [$enum_name] = &[ $( Self::$variant ),* ];
76
77 #[doc = concat!(
82 "```\nuse dynomite::stats::", stringify!($enum_name),
83 ";\nlet name = ", stringify!($enum_name),
84 "::ALL[0].name();\nassert!(!name.is_empty());\n```"
85 )]
86 pub fn name(self) -> &'static str {
87 match self { $( Self::$variant => $name ),* }
88 }
89
90 #[doc = concat!(
95 "```\nuse dynomite::stats::{", stringify!($enum_name),
96 ", StatsMetricType};\nlet k = ", stringify!($enum_name),
97 "::ALL[0].kind();\nassert!(matches!(k, StatsMetricType::Counter | StatsMetricType::Gauge | StatsMetricType::Timestamp));\n```"
98 )]
99 pub fn kind(self) -> StatsMetricType {
100 match self { $( Self::$variant => StatsMetricType::$kind ),* }
101 }
102
103 #[doc = concat!(
108 "```\nuse dynomite::stats::", stringify!($enum_name),
109 ";\nlet d = ", stringify!($enum_name),
110 "::ALL[0].description();\nassert!(!d.is_empty());\n```"
111 )]
112 pub fn description(self) -> &'static str {
113 match self { $( Self::$variant => $desc ),* }
114 }
115
116 #[doc = concat!(
121 "```\nuse dynomite::stats::", stringify!($enum_name),
122 ";\nassert_eq!(", stringify!($enum_name),
123 "::ALL[0].index(), 0);\n```"
124 )]
125 pub fn index(self) -> usize {
126 self as usize
127 }
128 }
129
130 #[doc = $codec_doc]
131 #[doc = concat!(
135 "```\nuse dynomite::stats::", stringify!($codec_const),
136 ";\nassert!(!", stringify!($codec_const), ".is_empty());\n```"
137 )]
138 pub const $codec_const: &[MetricSpec] = &[
139 $(
140 MetricSpec {
141 name: $name,
142 kind: StatsMetricType::$kind,
143 description: $desc,
144 }
145 ),*
146 ];
147 };
148}
149
150define_codec!(
151 PoolField, POOL_CODEC,
152 "Const slice of every pool metric descriptor in declaration order.",
153 "Typed handle for a pool metric.",
154 {
155 ClientEof, "client_eof", Counter, "# eof on client connections";
156 ClientErr, "client_err", Counter, "# errors on client connections";
157 ClientConnections, "client_connections", Gauge, "# active client connections";
158 ClientReadRequests, "client_read_requests", Counter, "# client read requests";
159 ClientWriteRequests, "client_write_requests", Counter, "# client write responses";
160 ClientDroppedRequests, "client_dropped_requests", Counter, "# client dropped requests";
161 ClientNonQuorumWResponses, "client_non_quorum_w_responses", Counter, "# client non quorum write responses";
162 ClientNonQuorumRResponses, "client_non_quorum_r_responses", Counter, "# client non quorum read responses";
163 ServerEjects, "server_ejects", Counter, "# times backend server was ejected";
164 DnodeClientEof, "dnode_client_eof", Counter, "# eof on dnode client connections";
165 DnodeClientErr, "dnode_client_err", Counter, "# errors on dnode client connections";
166 DnodeClientConnections, "dnode_client_connections", Gauge, "# active dnode client connections";
167 DnodeClientInQueue, "dnode_client_in_queue", Gauge, "# dnode client requests in incoming queue";
168 DnodeClientInQueueBytes, "dnode_client_in_queue_bytes", Gauge, "current dnode client request bytes in incoming queue";
169 DnodeClientOutQueue, "dnode_client_out_queue", Gauge, "# dnode client requests in outgoing queue";
170 DnodeClientOutQueueBytes, "dnode_client_out_queue_bytes", Gauge, "current dnode client request bytes in outgoing queue";
171 PeerDroppedRequests, "peer_dropped_requests", Counter, "# local dc peer dropped requests";
172 PeerTimedoutRequests, "peer_timedout_requests", Counter, "# local dc peer timedout requests";
173 RemotePeerDroppedRequests,"remote_peer_dropped_requests", Counter, "# remote dc peer dropped requests";
174 RemotePeerTimedoutRequests,"remote_peer_timedout_requests", Counter, "# remote dc peer timedout requests";
175 RemotePeerFailoverRequests,"remote_peer_failover_requests", Counter, "# remote dc peer failover requests";
176 PeerEof, "peer_eof", Counter, "# eof on peer connections";
177 PeerErr, "peer_err", Counter, "# errors on peer connections";
178 PeerTimedout, "peer_timedout", Counter, "# timeouts on local dc peer connections";
179 RemotePeerTimedout, "remote_peer_timedout", Counter, "# timeouts on remote dc peer connections";
180 PeerConnections, "peer_connections", Gauge, "# active peer connections";
181 PeerForwardError, "peer_forward_error", Gauge, "# times we encountered a peer forwarding error";
182 PeerRequests, "peer_requests", Counter, "# peer requests";
183 PeerRequestBytes, "peer_request_bytes", Counter, "total peer request bytes";
184 PeerResponses, "peer_responses", Counter, "# peer respones";
185 PeerResponseBytes, "peer_response_bytes", Counter, "total peer response bytes";
186 PeerEjectedAt, "peer_ejected_at", Timestamp, "timestamp when peer was ejected";
187 PeerEjects, "peer_ejects", Counter, "# times a peer was ejected";
188 PeerInQueue, "peer_in_queue", Gauge, "# local dc peer requests in incoming queue";
189 RemotePeerInQueue, "remote_peer_in_queue", Gauge, "# remote dc peer requests in incoming queue";
190 PeerInQueueBytes, "peer_in_queue_bytes", Gauge, "current peer request bytes in incoming queue";
191 RemotePeerInQueueBytes, "remote_peer_in_queue_bytes", Gauge, "current peer request bytes in incoming queue to remote DC";
192 PeerOutQueue, "peer_out_queue", Gauge, "# local dc peer requests in outgoing queue";
193 RemotePeerOutQueue, "remote_peer_out_queue", Gauge, "# remote dc peer requests in outgoing queue";
194 PeerOutQueueBytes, "peer_out_queue_bytes", Gauge, "current peer request bytes in outgoing queue";
195 RemotePeerOutQueueBytes, "remote_peer_out_queue_bytes", Gauge, "current peer request bytes in outgoing queue to remote DC";
196 PeerMismatchRequests, "peer_mismatch_requests", Counter, "current dnode peer mismatched messages";
197 ForwardError, "forward_error", Counter, "# times we encountered a forwarding error";
198 Fragments, "fragments", Counter, "# fragments created from a multi-vector request";
199 StatsCount, "stats_count", Counter, "# stats request";
200});
201
202define_codec!(
203 ServerField, SERVER_CODEC,
204 "Const slice of every server metric descriptor in declaration order.",
205 "Typed handle for a server metric.",
206 {
207 ServerEof, "server_eof", Counter, "# eof on server connections";
208 ServerErr, "server_err", Counter, "# errors on server connections";
209 ServerTimedout, "server_timedout", Counter, "# timeouts on server connections";
210 ServerEjectedAt, "server_ejected_at", Timestamp, "timestamp when server was ejected in usec since epoch";
211 ServerDroppedRequests, "server_dropped_requests", Counter, "# server dropped requests";
212 ServerTimedoutRequests, "server_timedout_requests", Counter, "# server timedout requests";
213 ReadRequests, "read_requests", Counter, "# read requests";
214 ReadRequestBytes, "read_request_bytes", Counter, "total read request bytes";
215 WriteRequests, "write_requests", Counter, "# write requests";
216 WriteRequestBytes, "write_request_bytes", Counter, "total write request bytes";
217 ReadResponses, "read_responses", Counter, "# read respones";
218 ReadResponseBytes, "read_response_bytes", Counter, "total read response bytes";
219 WriteResponses, "write_responses", Counter, "# write respones";
220 WriteResponseBytes, "write_response_bytes", Counter, "total write response bytes";
221 InQueue, "in_queue", Gauge, "# requests in incoming queue";
222 InQueueBytes, "in_queue_bytes", Gauge, "current request bytes in incoming queue";
223 OutQueue, "out_queue", Gauge, "# requests in outgoing queue";
224 OutQueueBytes, "out_queue_bytes", Gauge, "current request bytes in outgoing queue";
225 RedisReqGet, "redis_req_get", Counter, "# Redis get";
226 RedisReqSet, "redis_req_set", Counter, "# Redis set";
227 RedisReqDel, "redis_req_del", Counter, "# Redis del";
228 RedisReqIncrDecr, "redis_req_incr_decr", Counter, "# Redis incr or decr";
229 RedisReqKeys, "redis_req_keys", Counter, "# Redis keys";
230 RedisReqMget, "redis_req_mget", Counter, "# Redis mget";
231 RedisReqScan, "redis_req_scan", Counter, "# Redis scan";
232 RedisReqSort, "redis_req_sort", Counter, "# Redis sort";
233 RedisReqLreqm, "redis_req_lreqm", Counter, "# Redis lreqm";
234 RedisReqSunion, "redis_req_sunion", Counter, "# Redis sunion";
235 RedisReqPing, "redis_req_ping", Counter, "# Redis ping";
236 RedisReqLists, "redis_req_lists", Counter, "# Redis lists";
237 RedisReqSets, "redis_req_sets", Counter, "# Redis sets";
238 RedisReqHashes, "redis_req_hashes", Counter, "# Redis hashes";
239 RedisReqSortedsets, "redis_req_sortedsets", Counter, "# Redis sortedsets";
240 RedisReqOther, "redis_req_other", Counter, "# Redis other";
241});
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246
247 #[test]
248 fn pool_codec_indexes_align_with_variants() {
249 for (i, variant) in PoolField::ALL.iter().copied().enumerate() {
250 assert_eq!(variant.index(), i);
251 assert_eq!(variant.name(), POOL_CODEC[i].name);
252 assert_eq!(variant.kind(), POOL_CODEC[i].kind);
253 assert_eq!(variant.description(), POOL_CODEC[i].description);
254 }
255 }
256
257 #[test]
258 fn server_codec_indexes_align_with_variants() {
259 for (i, variant) in ServerField::ALL.iter().copied().enumerate() {
260 assert_eq!(variant.index(), i);
261 assert_eq!(variant.name(), SERVER_CODEC[i].name);
262 assert_eq!(variant.kind(), SERVER_CODEC[i].kind);
263 assert_eq!(variant.description(), SERVER_CODEC[i].description);
264 }
265 }
266
267 #[test]
268 fn pool_kinds_match_c_codec() {
269 assert_eq!(PoolField::ClientConnections.kind(), StatsMetricType::Gauge);
270 assert_eq!(PoolField::ClientEof.kind(), StatsMetricType::Counter);
271 assert_eq!(PoolField::PeerEjectedAt.kind(), StatsMetricType::Timestamp);
272 }
273
274 #[test]
275 fn pool_codec_has_expected_count() {
276 assert_eq!(POOL_CODEC.len(), PoolField::ALL.len());
277 }
278
279 #[test]
280 fn server_codec_has_expected_count() {
281 assert_eq!(SERVER_CODEC.len(), ServerField::ALL.len());
282 }
283}