Skip to main content

chunked_wal/
stat.rs

1use std::fmt;
2use std::fmt::Formatter;
3
4use crate::ChunkId;
5use crate::num::format_pad9_u64;
6
7/// Aggregated flush worker metrics.
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
9pub struct FlushMetrics {
10    /// Number of write batches processed by the flush worker.
11    pub batch_count: u64,
12    /// Number of batches that required a filesystem sync.
13    pub sync_batch_count: u64,
14    /// Number of write requests included in all batches.
15    pub write_request_count: u64,
16    /// Total bytes written by the flush worker.
17    pub write_bytes: u64,
18    /// Number of callbacks sent after write batches.
19    pub callback_count: u64,
20    /// Number of times the flush worker intentionally waited for batching.
21    pub group_wait_count: u64,
22    /// Total intentional group-commit wait time, in microseconds.
23    pub group_wait_us: u64,
24    /// Maximum intentional group-commit wait time, in microseconds.
25    pub group_wait_max_us: u64,
26    /// Total request queue wait before a batch starts writing, in
27    /// microseconds.
28    pub queued_wait_us: u64,
29    /// Maximum request queue wait before a batch starts writing, in
30    /// microseconds.
31    pub queued_wait_max_us: u64,
32    /// Total file write time, in microseconds.
33    pub write_us: u64,
34    /// Maximum file write time for one batch, in microseconds.
35    pub write_max_us: u64,
36    /// Total filesystem sync time, in microseconds.
37    pub sync_us: u64,
38    /// Maximum filesystem sync time for one batch, in microseconds.
39    pub sync_max_us: u64,
40    /// Total batch processing time, in microseconds.
41    pub batch_us: u64,
42    /// Maximum batch processing time, in microseconds.
43    pub batch_max_us: u64,
44    /// Largest number of write requests in one batch.
45    pub batch_size_max: u64,
46    /// Largest number of bytes written by one batch.
47    pub batch_bytes_max: u64,
48    /// Number of write requests in the latest batch.
49    pub last_batch_size: u64,
50    /// Number of bytes written by the latest batch.
51    pub last_batch_bytes: u64,
52    /// Number of callbacks sent by the latest batch.
53    pub last_callback_count: u64,
54    /// Filesystem sync duration of the latest batch, in microseconds.
55    pub last_sync_us: u64,
56    /// Request queue wait maximum of the latest batch, in microseconds.
57    pub last_queued_wait_max_us: u64,
58    /// Intentional group-commit wait latency percentiles, in microseconds.
59    pub group_wait_percentiles: FlushLatencyPercentiles,
60    /// Per-batch max request queue wait latency percentiles, in microseconds.
61    pub queued_wait_percentiles: FlushLatencyPercentiles,
62    /// File write latency percentiles, in microseconds.
63    pub write_percentiles: FlushLatencyPercentiles,
64    /// Filesystem sync latency percentiles, in microseconds.
65    pub sync_percentiles: FlushLatencyPercentiles,
66    /// Whole batch processing latency percentiles, in microseconds.
67    pub batch_percentiles: FlushLatencyPercentiles,
68}
69
70/// Percentiles for one flush worker latency dimension.
71#[derive(Debug, Clone, Default, PartialEq, Eq)]
72pub struct FlushLatencyPercentiles {
73    pub p50_us: u64,
74    pub p90_us: u64,
75    pub p99_us: u64,
76}
77
78/// Statistics about a single chunk in the WAL.
79#[derive(Debug, Clone)]
80pub struct ChunkStat<Chkp> {
81    /// Unique identifier for this chunk.
82    pub chunk_id: ChunkId,
83    /// Number of records stored in this chunk.
84    pub records_count: u64,
85    /// Global offset of the first record in this chunk.
86    pub global_start: u64,
87    /// Global offset after the last record in this chunk.
88    pub global_end: u64,
89    /// Size of the chunk in bytes.
90    pub size: u64,
91    /// Checkpoint stored for this chunk.
92    pub log_state: Chkp,
93}
94
95impl<Chkp> fmt::Display for ChunkStat<Chkp>
96where Chkp: fmt::Debug
97{
98    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99        write!(
100            f,
101            "ChunkStat({}){{records: {}, [{}, {}), size: {}, log_state: {:?}}}",
102            self.chunk_id,
103            self.records_count,
104            format_pad9_u64(self.global_start),
105            format_pad9_u64(self.global_end),
106            format_pad9_u64(self.size),
107            self.log_state
108        )
109    }
110}
111
112#[cfg(test)]
113mod tests {
114    use crate::ChunkId;
115    use crate::stat::ChunkStat;
116    use crate::stat::FlushLatencyPercentiles;
117    use crate::stat::FlushMetrics;
118
119    #[test]
120    fn test_chunk_stat_display() {
121        let stat = ChunkStat {
122            chunk_id: ChunkId(12),
123            records_count: 3,
124            global_start: 12,
125            global_end: 45,
126            size: 33,
127            log_state: "checkpoint",
128        };
129
130        assert_eq!(
131            "ChunkStat(ChunkId(00_000_000_000_000_000_012)){records: 3, [000_000_012, 000_000_045), size: 000_000_033, log_state: \"checkpoint\"}",
132            stat.to_string()
133        );
134    }
135
136    #[test]
137    fn test_flush_metrics_default_clone_eq() {
138        let metrics = FlushMetrics {
139            batch_count: 1,
140            sync_batch_count: 2,
141            write_request_count: 3,
142            write_bytes: 4,
143            callback_count: 5,
144            group_wait_count: 6,
145            group_wait_us: 7,
146            group_wait_max_us: 8,
147            queued_wait_us: 9,
148            queued_wait_max_us: 10,
149            write_us: 11,
150            write_max_us: 12,
151            sync_us: 13,
152            sync_max_us: 14,
153            batch_us: 15,
154            batch_max_us: 16,
155            batch_size_max: 17,
156            batch_bytes_max: 18,
157            last_batch_size: 19,
158            last_batch_bytes: 20,
159            last_callback_count: 21,
160            last_sync_us: 22,
161            last_queued_wait_max_us: 23,
162            group_wait_percentiles: FlushLatencyPercentiles {
163                p50_us: 24,
164                p90_us: 25,
165                p99_us: 26,
166            },
167            queued_wait_percentiles: FlushLatencyPercentiles::default(),
168            write_percentiles: FlushLatencyPercentiles::default(),
169            sync_percentiles: FlushLatencyPercentiles::default(),
170            batch_percentiles: FlushLatencyPercentiles::default(),
171        };
172
173        assert_eq!(metrics, metrics.clone());
174        assert_eq!(
175            FlushLatencyPercentiles {
176                p50_us: 0,
177                p90_us: 0,
178                p99_us: 0,
179            },
180            FlushLatencyPercentiles::default()
181        );
182    }
183}