Skip to main content

sui_kvstore/bigtable/
metrics.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::sync::Arc;
5
6use prometheus::GaugeVec;
7use prometheus::HistogramVec;
8use prometheus::IntCounterVec;
9use prometheus::Registry;
10use prometheus::register_gauge_vec_with_registry;
11use prometheus::register_histogram_vec_with_registry;
12use prometheus::register_int_counter_vec_with_registry;
13
14pub(crate) struct KvMetrics {
15    pub kv_get_success: IntCounterVec,
16    pub kv_get_not_found: IntCounterVec,
17    pub kv_get_errors: IntCounterVec,
18    pub kv_get_latency_ms: HistogramVec,
19    pub kv_get_batch_size: HistogramVec,
20    pub kv_get_latency_ms_per_key: HistogramVec,
21    pub kv_get_stream_poll_wait_ms: HistogramVec,
22    pub kv_get_stream_poll_wait_ms_per_key: HistogramVec,
23    pub kv_scan_success: IntCounterVec,
24    pub kv_scan_not_found: IntCounterVec,
25    pub kv_scan_error: IntCounterVec,
26    pub kv_scan_latency_ms: HistogramVec,
27    pub kv_bt_chunk_latency_ms: HistogramVec,
28    pub kv_bt_read_rows_started_total: IntCounterVec,
29    pub kv_bt_read_rows_retries_total: IntCounterVec,
30    pub kv_bt_read_rows_gap_timeouts_total: IntCounterVec,
31    pub kv_bt_chunk_rows_returned_count: IntCounterVec,
32    pub kv_bt_chunk_rows_seen_count: IntCounterVec,
33    pub kv_bt_flow_control_effective_qps: GaugeVec,
34    pub kv_bt_flow_control_last_observation_start_qps: GaugeVec,
35    pub kv_bt_flow_control_write_latency_window_avg_ms: GaugeVec,
36    pub kv_bt_flow_control_write_latency_baseline_ms: GaugeVec,
37    pub kv_bt_flow_control_throttle_ms: HistogramVec,
38    pub kv_bt_flow_control_server_feedback_total: IntCounterVec,
39    pub kv_bt_flow_control_latency_feedback_total: IntCounterVec,
40    pub kv_bt_flow_control_events_total: IntCounterVec,
41}
42
43impl KvMetrics {
44    pub(crate) fn new(registry: &Registry) -> Arc<Self> {
45        Arc::new(Self {
46            kv_get_success: register_int_counter_vec_with_registry!(
47                "kv_get_success",
48                "Number of successful fetches from kv store",
49                &["client", "table"],
50                registry,
51            )
52            .unwrap(),
53            kv_get_not_found: register_int_counter_vec_with_registry!(
54                "kv_get_not_found",
55                "Number of fetches from kv store that returned not found",
56                &["client", "table"],
57                registry,
58            )
59            .unwrap(),
60            kv_get_errors: register_int_counter_vec_with_registry!(
61                "kv_get_errors",
62                "Number of fetches from kv store that returned an error",
63                &["client", "table"],
64                registry,
65            )
66            .unwrap(),
67            kv_get_latency_ms: register_histogram_vec_with_registry!(
68                "kv_get_latency_ms",
69                "Latency of fetches from kv store",
70                &["client", "table"],
71                prometheus::exponential_buckets(1.0, 1.6, 24)
72                    .unwrap()
73                    .to_vec(),
74                registry,
75            )
76            .unwrap(),
77            kv_get_batch_size: register_histogram_vec_with_registry!(
78                "kv_get_batch_size",
79                "Number of keys fetched per batch from kv store",
80                &["client", "table"],
81                prometheus::exponential_buckets(1.0, 1.6, 20)
82                    .unwrap()
83                    .to_vec(),
84                registry,
85            )
86            .unwrap(),
87            kv_get_latency_ms_per_key: register_histogram_vec_with_registry!(
88                "kv_get_latency_ms_per_key",
89                "Latency of fetches from kv store per key",
90                &["client", "table"],
91                prometheus::exponential_buckets(1.0, 1.6, 24)
92                    .unwrap()
93                    .to_vec(),
94                registry,
95            )
96            .unwrap(),
97            kv_get_stream_poll_wait_ms: register_histogram_vec_with_registry!(
98                "kv_get_stream_poll_wait_ms",
99                "Accumulated demand-visible supply wait for a successfully drained streamed BigTable multi-get: ReadRows RPC open time plus time from downstream polling for a row until that demand returns a row or natural EOF. Excludes idle time after delivering a row and before the next downstream poll. May include BigTable service time, network transit, gRPC decoding, and executor scheduling while demand is pending; pair with kv_bt_chunk_latency_ms for BigTable frontend latency. Observed only after natural successful EOF, so errors, early drops, cancellations, and item-limit truncation are absent and create survivorship bias.",
100                &["client", "table"],
101                prometheus::exponential_buckets(1.0, 1.6, 24)
102                    .unwrap()
103                    .to_vec(),
104                registry,
105            )
106            .unwrap(),
107            kv_get_stream_poll_wait_ms_per_key: register_histogram_vec_with_registry!(
108                "kv_get_stream_poll_wait_ms_per_key",
109                "Accumulated demand-visible supply wait per requested key for a successfully drained streamed BigTable multi-get: ReadRows RPC open time plus downstream-active row poll-to-ready time, divided by requested keys. Excludes idle time between delivered rows and later demand. May include BigTable service time, network transit, gRPC decoding, and executor scheduling; pair with kv_bt_chunk_latency_ms. Observed only after natural successful EOF, so errors, early drops, cancellations, and item-limit truncation are absent and create survivorship bias.",
110                &["client", "table"],
111                prometheus::exponential_buckets(1.0, 1.6, 24)
112                    .unwrap()
113                    .to_vec(),
114                registry,
115            )
116            .unwrap(),
117            kv_scan_success: register_int_counter_vec_with_registry!(
118                "kv_scan_success",
119                "Number of successful scans from kv store",
120                &["client", "table"],
121                registry,
122            )
123            .unwrap(),
124            kv_scan_not_found: register_int_counter_vec_with_registry!(
125                "kv_scan_not_found",
126                "Number of fetches from kv store that returned not found",
127                &["client", "table"],
128                registry,
129            )
130            .unwrap(),
131            kv_scan_error: register_int_counter_vec_with_registry!(
132                "kv_scan_error",
133                "Number of scans from kv store that returned an error",
134                &["client", "table"],
135                registry,
136            )
137            .unwrap(),
138            kv_scan_latency_ms: register_histogram_vec_with_registry!(
139                "kv_scan_latency_ms",
140                "Latency of scans from kv store",
141                &["client", "table"],
142                prometheus::exponential_buckets(1.0, 1.6, 24)
143                    .unwrap()
144                    .to_vec(),
145                registry,
146            )
147            .unwrap(),
148            kv_bt_chunk_latency_ms: register_histogram_vec_with_registry!(
149                "kv_bt_chunk_latency_ms",
150                "Reported BigTable latency for a single chunk",
151                &["client", "table"],
152                prometheus::exponential_buckets(1.0, 1.6, 24)
153                    .unwrap()
154                    .to_vec(),
155                registry,
156            )
157            .unwrap(),
158            kv_bt_read_rows_started_total: register_int_counter_vec_with_registry!(
159                "kv_bt_read_rows_started_total",
160                "ReadRows RPCs initiated per table; incremented at RPC start, covering point multi-gets and range scans alike",
161                &["client", "table"],
162                registry,
163            )
164            .unwrap(),
165            kv_bt_read_rows_retries_total: register_int_counter_vec_with_registry!(
166                "kv_bt_read_rows_retries_total",
167                "ReadRows attempts started after an earlier attempt of the same read failed, by reason: gap_timeout (no response message within the gap timeout), quarantine (the attempt's channel was quarantined), other (an Unavailable status, a stream BigTable refused with a GOAWAY, a stream cut off by its connection failing, or a request never sent because its connection closed). Each retry is a ReadRows RPC beyond kv_bt_read_rows_started_total and resumes after the last row already returned",
168                &["client", "table", "reason"],
169                registry,
170            )
171            .unwrap(),
172            kv_bt_read_rows_gap_timeouts_total: register_int_counter_vec_with_registry!(
173                "kv_bt_read_rows_gap_timeouts_total",
174                "ReadRows attempts abandoned because the caller waited longer than the gap timeout for the next response message, by phase: headers (waiting for the response to start) or body (waiting for a later message)",
175                &["client", "table", "phase"],
176                registry,
177            )
178            .unwrap(),
179            kv_bt_chunk_rows_returned_count: register_int_counter_vec_with_registry!(
180                "kv_bt_chunk_rows_returned_count",
181                "Reported BigTable rows returned count for a single chunk",
182                &["client", "table"],
183                registry,
184            )
185            .unwrap(),
186            kv_bt_chunk_rows_seen_count: register_int_counter_vec_with_registry!(
187                "kv_bt_chunk_rows_seen_count",
188                "Reported BigTable rows seen count for a single chunk",
189                &["client", "table"],
190                registry,
191            )
192            .unwrap(),
193            kv_bt_flow_control_effective_qps: register_gauge_vec_with_registry!(
194                "kv_bt_flow_control_effective_qps",
195                "Effective MutateRows admission limit in requests per second",
196                &["client"],
197                registry,
198            )
199            .unwrap(),
200            kv_bt_flow_control_last_observation_start_qps: register_gauge_vec_with_registry!(
201                "kv_bt_flow_control_last_observation_start_qps",
202                "MutateRows start rate from the most recently completed feedback observation; may remain unchanged between observations",
203                &["client"],
204                registry,
205            )
206            .unwrap(),
207            kv_bt_flow_control_write_latency_window_avg_ms: register_gauge_vec_with_registry!(
208                "kv_bt_flow_control_write_latency_window_avg_ms",
209                "Window-average MutateRows RPC latency observed by BigTable batch-write flow control",
210                &["client"],
211                registry,
212            )
213            .unwrap(),
214            kv_bt_flow_control_write_latency_baseline_ms: register_gauge_vec_with_registry!(
215                "kv_bt_flow_control_write_latency_baseline_ms",
216                "Learned healthy-baseline MutateRows RPC latency used for flow-control classification",
217                &["client"],
218                registry,
219            )
220            .unwrap(),
221            kv_bt_flow_control_throttle_ms: register_histogram_vec_with_registry!(
222                "kv_bt_flow_control_throttle_ms",
223                "Time spent waiting for BigTable adaptive batch-write flow-control admission",
224                &["client"],
225                prometheus::exponential_buckets(1.0, 1.6, 32)
226                    .unwrap()
227                    .to_vec(),
228                registry,
229            )
230            .unwrap(),
231            kv_bt_flow_control_server_feedback_total: register_int_counter_vec_with_registry!(
232                "kv_bt_flow_control_server_feedback_total",
233                "Valid Bigtable MutateRows RateLimitInfo messages by factor direction (decrease, neutral, or increase) and client handling outcome (queued or rejected)",
234                &["client", "direction", "outcome"],
235                registry,
236            )
237            .unwrap(),
238            kv_bt_flow_control_latency_feedback_total: register_int_counter_vec_with_registry!(
239                "kv_bt_flow_control_latency_feedback_total",
240                "Latency-derived feedback generated by Bigtable adaptive batch-write flow control (decrease, reanchor, or increase)",
241                &["client", "direction"],
242                registry,
243            )
244            .unwrap(),
245            kv_bt_flow_control_events_total: register_int_counter_vec_with_registry!(
246                "kv_bt_flow_control_events_total",
247                "BigTable adaptive batch-write flow-control feedback and observation lifecycle events",
248                &["client", "event"],
249                registry,
250            )
251            .unwrap(),
252        })
253    }
254}