Skip to main content

canic_core/workflow/metrics/
query.rs

1use crate::{
2    dto::{
3        metrics::{
4            AccessMetricEntry, DelegationMetricEntry, EndpointHealth, HttpMetricEntry,
5            IccMetricEntry, RootCapabilityMetricEntry, 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, RootCapabilityMetricEntryMapper,
16                SystemMetricEntryMapper, 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 root_capability_page(page: PageRequest) -> Page<RootCapabilityMetricEntry> {
111        let snapshot = MetricsOps::root_capability_snapshot();
112        let mut entries = RootCapabilityMetricEntryMapper::record_to_view(snapshot.entries);
113
114        entries.sort_by(|a, b| {
115            a.capability
116                .cmp(&b.capability)
117                .then_with(|| a.event.cmp(&b.event))
118        });
119
120        paginate_vec(entries, page)
121    }
122
123    #[must_use]
124    pub fn perf_page(page: PageRequest) -> Page<PerfEntry> {
125        let snapshot = PerfOps::snapshot();
126        paginate_vec(snapshot.entries, page)
127    }
128
129    #[must_use]
130    pub fn endpoint_health_page(
131        page: PageRequest,
132        exclude_endpoint: Option<&str>,
133    ) -> Page<EndpointHealth> {
134        let snapshot = MetricsOps::endpoint_health_snapshot();
135        let mut entries = EndpointHealthMapper::record_to_view(
136            snapshot.attempts,
137            snapshot.results,
138            snapshot.access,
139            exclude_endpoint,
140        );
141
142        entries.sort_by(|a, b| a.endpoint.cmp(&b.endpoint));
143
144        paginate_vec(entries, page)
145    }
146}