Skip to main content

atomr_telemetry/
dto.rs

1//! Serde DTOs shared between the telemetry bus, REST handlers, and the
2//! React dashboard. Kept in one file so the whole wire format is visible
3//! at a glance.
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ActorStatus {
9    pub path: String,
10    pub parent: Option<String>,
11    pub actor_type: String,
12    pub mailbox_depth: u64,
13    pub spawned_at: String,
14    /// Optional host annotation supplied by the application via
15    /// [`crate::actor_registry::ActorRegistry::set_host`]. Single-process
16    /// systems leave this `None`; cluster-aware demos use it to group
17    /// actors by their owning cluster member on the dashboard's
18    /// Topology page.
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub host: Option<String>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ActorTreeNode {
25    pub path: String,
26    pub name: String,
27    pub actor_type: String,
28    pub mailbox_depth: u64,
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub host: Option<String>,
31    pub children: Vec<ActorTreeNode>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, Default)]
35pub struct ActorSnapshot {
36    pub total: u64,
37    pub roots: Vec<ActorTreeNode>,
38    pub flat: Vec<ActorStatus>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct DeadLetterRecord {
43    pub seq: u64,
44    pub recipient: String,
45    pub sender: Option<String>,
46    pub message_type: String,
47    pub message_preview: String,
48    pub timestamp: String,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, Default)]
52pub struct ClusterMemberInfo {
53    pub address: String,
54    pub status: String,
55    pub roles: Vec<String>,
56    pub reachable: bool,
57    pub up_number: i32,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, Default)]
61pub struct ClusterStateInfo {
62    pub self_address: Option<String>,
63    pub leader: Option<String>,
64    pub members: Vec<ClusterMemberInfo>,
65    pub unreachable: Vec<String>,
66    pub reachability_records: Vec<ReachabilityRecord>,
67    pub gossip_version: Vec<(String, u64)>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ReachabilityRecord {
72    pub observer: String,
73    pub subject: String,
74    pub status: String,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct ClusterMembershipDiff {
79    pub added: Vec<ClusterMemberInfo>,
80    pub updated: Vec<ClusterMemberInfo>,
81    pub removed: Vec<String>,
82    pub became_unreachable: Vec<String>,
83    pub became_reachable: Vec<String>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize, Default)]
87pub struct ShardRegionInfo {
88    pub region_id: String,
89    pub shard_count: usize,
90    pub shards: Vec<String>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, Default)]
94pub struct ShardingSnapshot {
95    pub regions: Vec<ShardRegionInfo>,
96    pub allocations: Vec<(String, String)>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct ShardingEvent {
101    pub region_id: String,
102    pub shard_id: String,
103    pub event: String,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, Default)]
107pub struct PersistenceSnapshot {
108    pub journals: Vec<JournalInfo>,
109    pub total_events: u64,
110    pub recent_writes: Vec<JournalWriteInfo>,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize, Default)]
114pub struct JournalInfo {
115    pub name: String,
116    pub persistence_ids: Vec<PersistenceIdStat>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct PersistenceIdStat {
121    pub persistence_id: String,
122    pub highest_sequence_nr: u64,
123    pub event_count: u64,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct JournalWriteInfo {
128    pub journal: String,
129    pub persistence_id: String,
130    pub sequence_nr: u64,
131    pub timestamp: String,
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize, Default)]
135pub struct RemoteSnapshot {
136    pub associations: Vec<RemoteAssociationInfo>,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct RemoteAssociationInfo {
141    pub remote_address: String,
142    pub state: String,
143    pub inbound_bytes: u64,
144    pub outbound_bytes: u64,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize, Default)]
148pub struct StreamsSnapshot {
149    pub running_graphs: u64,
150    pub total_started: u64,
151    pub total_finished: u64,
152    pub active: Vec<StreamGraphInfo>,
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct StreamGraphInfo {
157    pub id: u64,
158    pub name: String,
159    pub started_at: String,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, Default)]
163pub struct DDataSnapshot {
164    pub keys: Vec<String>,
165    pub total_updates: u64,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
169pub struct NodeSnapshot {
170    pub node: String,
171    pub generated_at: String,
172    pub actors: ActorSnapshot,
173    pub dead_letters: Vec<DeadLetterRecord>,
174    pub cluster: ClusterStateInfo,
175    pub sharding: ShardingSnapshot,
176    pub persistence: PersistenceSnapshot,
177    pub remote: RemoteSnapshot,
178    pub streams: StreamsSnapshot,
179    pub ddata: DDataSnapshot,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct OverviewSnapshot {
184    pub node: String,
185    pub generated_at: String,
186    pub actor_count: u64,
187    pub dead_letter_count: u64,
188    pub cluster_member_count: usize,
189    pub cluster_unreachable_count: usize,
190    pub remote_association_count: usize,
191    pub running_graphs: u64,
192    pub persistence_event_count: u64,
193    pub ddata_key_count: usize,
194}