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                .then_with(|| a.predicate.cmp(&b.predicate))
94        });
95
96        paginate_vec(entries, page)
97    }
98
99    #[must_use]
100    pub fn delegation_page(page: PageRequest) -> Page<DelegationMetricEntry> {
101        let snapshot = MetricsOps::delegation_snapshot();
102        let mut entries = DelegationMetricEntryMapper::record_to_view(snapshot.entries);
103
104        entries.sort_by(|a, b| a.authority.as_slice().cmp(b.authority.as_slice()));
105
106        paginate_vec(entries, page)
107    }
108
109    #[must_use]
110    pub fn perf_page(page: PageRequest) -> Page<PerfEntry> {
111        let snapshot = PerfOps::snapshot();
112        paginate_vec(snapshot.entries, page)
113    }
114
115    #[must_use]
116    pub fn endpoint_health_page(
117        page: PageRequest,
118        exclude_endpoint: Option<&str>,
119    ) -> Page<EndpointHealth> {
120        let snapshot = MetricsOps::endpoint_health_snapshot();
121        let mut entries = EndpointHealthMapper::record_to_view(
122            snapshot.attempts,
123            snapshot.results,
124            snapshot.access,
125            exclude_endpoint,
126        );
127
128        entries.sort_by(|a, b| a.endpoint.cmp(&b.endpoint));
129
130        paginate_vec(entries, page)
131    }
132}