canic_core/workflow/metrics/
query.rs

1use crate::{
2    dto::{
3        metrics::{
4            AccessMetricEntry, DelegationMetricEntry, EndpointHealth, HttpMetricEntry,
5            IccMetricEntry, SystemMetricEntry, TimerMetricEntry,
6        },
7        page::{Page, PageRequest},
8    },
9    ops::{
10        perf::PerfOps,
11        runtime::metrics::{
12            MetricsOps,
13            mapper::{
14                AccessMetricEntryMapper, DelegationMetricEntryMapper, EndpointHealthMapper,
15                HttpMetricEntryMapper, IccMetricEntryMapper, SystemMetricEntryMapper,
16                TimerMetricEntryMapper,
17            },
18        },
19    },
20    perf::PerfEntry,
21    workflow::view::paginate::paginate_vec,
22};
23
24///
25/// MetricsQuery
26///
27/// Read-only query façade over metric snapshots.
28/// Responsible for mapping, sorting, and pagination only.
29///
30
31pub struct MetricsQuery;
32
33impl MetricsQuery {
34    #[must_use]
35    pub fn system_snapshot() -> Vec<SystemMetricEntry> {
36        let snapshot = MetricsOps::system_snapshot();
37        let mut entries = SystemMetricEntryMapper::record_to_view(snapshot.entries);
38
39        entries.sort_by(|a, b| a.kind.cmp(&b.kind));
40
41        entries
42    }
43
44    #[must_use]
45    pub fn icc_page(page: PageRequest) -> Page<IccMetricEntry> {
46        let snapshot = MetricsOps::icc_snapshot();
47        let mut entries = IccMetricEntryMapper::record_to_view(snapshot.entries);
48
49        entries.sort_by(|a, b| {
50            a.target
51                .as_slice()
52                .cmp(b.target.as_slice())
53                .then_with(|| a.method.cmp(&b.method))
54        });
55
56        paginate_vec(entries, page)
57    }
58
59    #[must_use]
60    pub fn http_page(page: PageRequest) -> Page<HttpMetricEntry> {
61        let snapshot = MetricsOps::http_snapshot();
62        let mut entries = HttpMetricEntryMapper::record_to_view(snapshot.entries);
63
64        entries.sort_by(|a, b| a.method.cmp(&b.method).then_with(|| a.label.cmp(&b.label)));
65
66        paginate_vec(entries, page)
67    }
68
69    #[must_use]
70    pub fn timer_page(page: PageRequest) -> Page<TimerMetricEntry> {
71        let snapshot = MetricsOps::timer_snapshot();
72        let mut entries = TimerMetricEntryMapper::record_to_view(snapshot.entries);
73
74        entries.sort_by(|a, b| {
75            a.mode
76                .cmp(&b.mode)
77                .then_with(|| a.delay_ms.cmp(&b.delay_ms))
78                .then_with(|| a.label.cmp(&b.label))
79        });
80
81        paginate_vec(entries, page)
82    }
83
84    #[must_use]
85    pub fn access_page(page: PageRequest) -> Page<AccessMetricEntry> {
86        let snapshot = MetricsOps::access_snapshot();
87        let mut entries = AccessMetricEntryMapper::record_to_view(snapshot.entries);
88
89        entries.sort_by(|a, b| {
90            a.endpoint
91                .cmp(&b.endpoint)
92                .then_with(|| a.kind.cmp(&b.kind))
93        });
94
95        paginate_vec(entries, page)
96    }
97
98    #[must_use]
99    pub fn delegation_page(page: PageRequest) -> Page<DelegationMetricEntry> {
100        let snapshot = MetricsOps::delegation_snapshot();
101        let mut entries = DelegationMetricEntryMapper::record_to_view(snapshot.entries);
102
103        entries.sort_by(|a, b| a.authority.as_slice().cmp(b.authority.as_slice()));
104
105        paginate_vec(entries, page)
106    }
107
108    #[must_use]
109    pub fn perf_page(page: PageRequest) -> Page<PerfEntry> {
110        let snapshot = PerfOps::snapshot();
111        paginate_vec(snapshot.entries, page)
112    }
113
114    #[must_use]
115    pub fn endpoint_health_page(
116        page: PageRequest,
117        exclude_endpoint: Option<&str>,
118    ) -> Page<EndpointHealth> {
119        let snapshot = MetricsOps::endpoint_health_snapshot();
120        let mut entries = EndpointHealthMapper::record_to_view(
121            snapshot.attempts,
122            snapshot.results,
123            snapshot.access,
124            exclude_endpoint,
125        );
126
127        entries.sort_by(|a, b| a.endpoint.cmp(&b.endpoint));
128
129        paginate_vec(entries, page)
130    }
131}