1use 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}