1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::any::Any;
4use std::collections::HashMap;
5use std::sync::Arc;
6use url::Url;
7use uuid::Uuid;
8
9pub trait ProtocolLayer: Any + Send + Sync + std::fmt::Debug {
11 fn protocol_name(&self) -> &str;
12 fn as_any(&self) -> &dyn Any;
13 fn to_json(&self) -> serde_json::Value;
14}
15
16fn serialize_custom_layer<S>(
18 layer: &Arc<dyn ProtocolLayer>,
19 serializer: S,
20) -> Result<S::Ok, S::Error>
21where
22 S: Serializer,
23{
24 use serde::ser::SerializeStruct;
25 let mut state = serializer.serialize_struct("CustomLayer", 2)?;
26 state.serialize_field("protocol", layer.protocol_name())?;
27 state.serialize_field("data", &layer.to_json())?;
28 state.end()
29}
30
31fn deserialize_custom_layer<'de, D>(deserializer: D) -> Result<Arc<dyn ProtocolLayer>, D::Error>
33where
34 D: Deserializer<'de>,
35{
36 let value = serde_json::Value::deserialize(deserializer)?;
37
38 let protocol = value
40 .get("protocol")
41 .and_then(|v| v.as_str())
42 .unwrap_or("unknown")
43 .to_string();
44
45 let data = value
46 .get("data")
47 .cloned()
48 .unwrap_or(serde_json::Value::Null);
49
50 Ok(Arc::new(GenericProtocolLayer { protocol, data }))
51}
52
53#[derive(Debug)]
54struct GenericProtocolLayer {
55 protocol: String,
56 data: serde_json::Value,
57}
58
59impl ProtocolLayer for GenericProtocolLayer {
60 fn protocol_name(&self) -> &str {
61 &self.protocol
62 }
63 fn as_any(&self) -> &dyn Any {
64 self
65 }
66 fn to_json(&self) -> serde_json::Value {
67 self.data.clone()
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, Default)]
74pub struct ResilienceTrace {
75 #[serde(default)]
77 pub retry_count: u32,
78 #[serde(default)]
80 pub circuit_open: bool,
81 #[serde(default)]
83 pub budget_exceeded: bool,
84 #[serde(default, skip_serializing_if = "Vec::is_empty")]
86 pub upstream_errors: Vec<String>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct Flow {
93 pub id: Uuid,
94 pub start_time: DateTime<Utc>,
95 pub end_time: Option<DateTime<Utc>>,
96
97 pub network: NetworkInfo,
99
100 pub layer: Layer,
102
103 pub tags: Vec<String>,
105
106 #[serde(skip)]
108 pub meta: HashMap<String, String>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct NetworkInfo {
113 pub client_ip: String,
114 pub client_port: u16,
115 pub server_ip: String,
116 pub server_port: u16,
117 pub protocol: TransportProtocol,
118 pub tls: bool,
119 pub tls_version: Option<String>,
120 pub sni: Option<String>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
124pub enum TransportProtocol {
125 TCP,
126 UDP,
127 ICMP,
128 Unknown,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
135#[serde(tag = "type", content = "data")]
136pub enum Layer {
137 Http(HttpLayer),
138 WebSocket(WebSocketLayer),
139 Tcp(TcpLayer), Udp(UdpLayer), Quic(QuicLayer), #[serde(
143 serialize_with = "serialize_custom_layer",
144 deserialize_with = "deserialize_custom_layer"
145 )]
146 Custom(Arc<dyn ProtocolLayer>),
147 Unknown,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct UdpLayer {
152 pub payload_size: usize,
153 pub packet_count: usize,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct QuicLayer {
158 pub sni: Option<String>,
159 pub alpn: Option<String>,
160 pub version: Option<String>,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct HttpLayer {
167 pub request: HttpRequest,
168 pub response: Option<HttpResponse>,
169 pub error: Option<String>,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct HttpRequest {
174 pub method: String,
175 pub url: Url,
176 pub version: String, pub headers: Vec<(String, String)>, pub cookies: Vec<Cookie>,
179 pub query: Vec<(String, String)>,
180 pub body: Option<BodyData>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct HttpResponse {
185 pub status: u16,
186 pub status_text: String,
187 pub version: String,
188 pub headers: Vec<(String, String)>,
189 pub cookies: Vec<Cookie>,
190 pub body: Option<BodyData>,
191 pub timing: ResponseTiming,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct Cookie {
196 pub name: String,
197 pub value: String,
198 pub path: Option<String>,
199 pub domain: Option<String>,
200 pub expires: Option<String>,
201 pub http_only: Option<bool>,
202 pub secure: Option<bool>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct ResponseTiming {
207 pub time_to_first_byte: Option<u64>, pub time_to_last_byte: Option<u64>, pub connect_time_ms: Option<u64>,
211 pub ssl_time_ms: Option<u64>,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct WebSocketLayer {
219 pub handshake_request: HttpRequest,
220 pub handshake_response: HttpResponse,
221 pub messages: Vec<WebSocketMessage>,
222 pub closed: bool,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct WebSocketMessage {
227 pub id: Uuid,
228 pub timestamp: DateTime<Utc>,
229 pub direction: Direction, pub content: BodyData,
231 pub opcode: String, }
233
234#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
235pub enum Direction {
236 ClientToServer,
237 ServerToClient,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
243pub struct TcpLayer {
244 pub bytes_up: u64,
245 pub bytes_down: u64,
246 }
248
249#[derive(Debug, Clone, Serialize, Deserialize)]
252pub struct BodyData {
253 pub encoding: String,
255 pub content: String,
257 pub size: u64,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
263#[serde(tag = "type", content = "data")]
264pub enum FlowUpdate {
265 Full(Box<Flow>),
267 WebSocketMessage {
269 flow_id: String,
270 message: WebSocketMessage,
271 },
272 HttpBody {
274 flow_id: String,
275 direction: Direction,
276 body: BodyData,
277 },
278}