ic_backup/ops/persistence/download_journal/metrics/
mod.rs1use super::DownloadJournalGuard;
4pub use ic_metrics::{MeasurementHistogram, MeasurementSummary};
9use std::{
10 sync::PoisonError,
11 time::{Duration, Instant},
12};
13
14const EMPTY_CHUNK_HISTOGRAM: MeasurementHistogram<4> =
15 match MeasurementHistogram::new([0, 32 * 1024, 256 * 1024, 1024 * 1024]) {
16 Ok(histogram) => histogram,
17 Err(_) => panic!("prepared chunk bounds must be strictly increasing"),
18 };
19
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct IcSnapshotLocalMetrics {
34 verification_success_ns: MeasurementSummary,
35 verification_failure_ns: MeasurementSummary,
36 upload_metadata_success_ns: MeasurementSummary,
37 upload_metadata_failure_ns: MeasurementSummary,
38 upload_data_success_ns: MeasurementSummary,
39 upload_data_failure_ns: MeasurementSummary,
40 prepared_chunk_bytes: MeasurementHistogram<4>,
41}
42
43impl Default for IcSnapshotLocalMetrics {
44 fn default() -> Self {
45 Self {
46 verification_success_ns: MeasurementSummary::EMPTY,
47 verification_failure_ns: MeasurementSummary::EMPTY,
48 upload_metadata_success_ns: MeasurementSummary::EMPTY,
49 upload_metadata_failure_ns: MeasurementSummary::EMPTY,
50 upload_data_success_ns: MeasurementSummary::EMPTY,
51 upload_data_failure_ns: MeasurementSummary::EMPTY,
52 prepared_chunk_bytes: EMPTY_CHUNK_HISTOGRAM,
53 }
54 }
55}
56
57impl IcSnapshotLocalMetrics {
58 #[must_use]
60 pub const fn verification_success_ns(self) -> MeasurementSummary {
61 self.verification_success_ns
62 }
63 #[must_use]
65 pub const fn verification_failure_ns(self) -> MeasurementSummary {
66 self.verification_failure_ns
67 }
68 #[must_use]
70 pub const fn upload_metadata_success_ns(self) -> MeasurementSummary {
71 self.upload_metadata_success_ns
72 }
73 #[must_use]
75 pub const fn upload_metadata_failure_ns(self) -> MeasurementSummary {
76 self.upload_metadata_failure_ns
77 }
78 #[must_use]
80 pub const fn upload_data_success_ns(self) -> MeasurementSummary {
81 self.upload_data_success_ns
82 }
83 #[must_use]
85 pub const fn upload_data_failure_ns(self) -> MeasurementSummary {
86 self.upload_data_failure_ns
87 }
88 #[must_use]
90 pub const fn prepared_chunk_bytes(self) -> MeasurementSummary {
91 self.prepared_chunk_bytes.summary()
92 }
93 #[must_use]
102 pub const fn prepared_chunk_bytes_histogram(self) -> MeasurementHistogram<4> {
103 self.prepared_chunk_bytes
104 }
105
106 fn record(
107 &mut self,
108 operation: LocalOperation,
109 elapsed: Duration,
110 succeeded: bool,
111 chunk_bytes: Option<usize>,
112 ) {
113 let duration = u64::try_from(elapsed.as_nanos()).unwrap_or(u64::MAX);
114 let summary = match (operation, succeeded) {
115 (LocalOperation::Verification, true) => &mut self.verification_success_ns,
116 (LocalOperation::Verification, false) => &mut self.verification_failure_ns,
117 (LocalOperation::UploadMetadata, true) => &mut self.upload_metadata_success_ns,
118 (LocalOperation::UploadMetadata, false) => &mut self.upload_metadata_failure_ns,
119 (LocalOperation::UploadData, true) => &mut self.upload_data_success_ns,
120 (LocalOperation::UploadData, false) => &mut self.upload_data_failure_ns,
121 };
122 summary.record(duration);
123 if let (LocalOperation::UploadData, true, Some(bytes)) = (operation, succeeded, chunk_bytes)
124 {
125 self.prepared_chunk_bytes
126 .record(u64::try_from(bytes).unwrap_or(u64::MAX));
127 }
128 }
129}
130
131#[derive(Clone, Copy)]
132pub(super) enum LocalOperation {
133 Verification,
134 UploadMetadata,
135 UploadData,
136}
137
138impl DownloadJournalGuard<'_> {
139 #[must_use]
147 pub fn ic_snapshot_metrics(&self) -> IcSnapshotLocalMetrics {
148 *self
149 .ic_snapshot_metrics
150 .lock()
151 .unwrap_or_else(PoisonError::into_inner)
152 }
153
154 pub(super) fn record_ic_snapshot_metrics(
155 &self,
156 operation: LocalOperation,
157 started: Instant,
158 succeeded: bool,
159 chunk_bytes: Option<usize>,
160 ) {
161 let elapsed = started.elapsed();
162 self.ic_snapshot_metrics
163 .lock()
164 .unwrap_or_else(PoisonError::into_inner)
165 .record(operation, elapsed, succeeded, chunk_bytes);
166 }
167}
168
169#[cfg(test)]
170mod tests;