1use std::{collections::HashMap, time::Duration};
16
17use chrono::{DateTime, Utc};
18use serde::{Deserialize, Serialize};
19
20use crate::heal_commands::HealResultItem;
21
22#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
23pub struct TraceType(u64);
24
25impl TraceType {
26 pub const OS: TraceType = TraceType(1 << 0);
28 pub const STORAGE: TraceType = TraceType(1 << 1);
29 pub const S3: TraceType = TraceType(1 << 2);
30 pub const INTERNAL: TraceType = TraceType(1 << 3);
31 pub const SCANNER: TraceType = TraceType(1 << 4);
32 pub const DECOMMISSION: TraceType = TraceType(1 << 5);
33 pub const HEALING: TraceType = TraceType(1 << 6);
34 pub const BATCH_REPLICATION: TraceType = TraceType(1 << 7);
35 pub const BATCH_KEY_ROTATION: TraceType = TraceType(1 << 8);
36 pub const BATCH_EXPIRE: TraceType = TraceType(1 << 9);
37 pub const REBALANCE: TraceType = TraceType(1 << 10);
38 pub const REPLICATION_RESYNC: TraceType = TraceType(1 << 11);
39 pub const BOOTSTRAP: TraceType = TraceType(1 << 12);
40 pub const FTP: TraceType = TraceType(1 << 13);
41 pub const ILM: TraceType = TraceType(1 << 14);
42
43 pub const ALL: TraceType = TraceType((1 << 15) - 1);
45
46 pub fn new(t: u64) -> Self {
47 Self(t)
48 }
49}
50
51impl TraceType {
52 pub fn contains(&self, x: &TraceType) -> bool {
53 (self.0 & x.0) == x.0
54 }
55
56 pub fn overlaps(&self, x: &TraceType) -> bool {
57 (self.0 & x.0) != 0
58 }
59
60 pub fn single_type(&self) -> bool {
61 todo!()
62 }
63
64 pub fn merge(&mut self, other: &TraceType) {
65 self.0 |= other.0
66 }
67
68 pub fn set_if(&mut self, b: bool, other: &TraceType) {
69 if b {
70 self.0 |= other.0
71 }
72 }
73
74 pub fn mask(&self) -> u64 {
75 self.0
76 }
77}
78
79#[derive(Debug, Default, Clone, Serialize, Deserialize)]
80pub struct TraceInfo {
81 #[serde(rename = "type")]
82 trace_type: u64,
83 #[serde(rename = "nodename")]
84 node_name: String,
85 #[serde(rename = "funcname")]
86 func_name: String,
87 #[serde(rename = "time")]
88 time: DateTime<Utc>,
89 #[serde(rename = "path")]
90 path: String,
91 #[serde(rename = "dur")]
92 duration: Duration,
93 #[serde(rename = "bytes", skip_serializing_if = "Option::is_none")]
94 bytes: Option<i64>,
95 #[serde(rename = "msg", skip_serializing_if = "Option::is_none")]
96 message: Option<String>,
97 #[serde(rename = "error", skip_serializing_if = "Option::is_none")]
98 error: Option<String>,
99 #[serde(rename = "custom", skip_serializing_if = "Option::is_none")]
100 custom: Option<HashMap<String, String>>,
101 #[serde(rename = "http", skip_serializing_if = "Option::is_none")]
102 http: Option<TraceHTTPStats>,
103 #[serde(rename = "healResult", skip_serializing_if = "Option::is_none")]
104 heal_result: Option<HealResultItem>,
105}
106
107impl TraceInfo {
108 pub fn mask(&self) -> u64 {
109 TraceType::new(self.trace_type).mask()
110 }
111}
112
113#[derive(Debug, Default, Clone, Serialize, Deserialize)]
114pub struct TraceInfoLegacy {
115 trace_info: TraceInfo,
116 #[serde(rename = "request")]
117 req_info: Option<TraceRequestInfo>,
118 #[serde(rename = "response")]
119 resp_info: Option<TraceResponseInfo>,
120 #[serde(rename = "stats")]
121 call_stats: Option<TraceCallStats>,
122 #[serde(rename = "storageStats")]
123 storage_stats: Option<StorageStats>,
124 #[serde(rename = "osStats")]
125 os_stats: Option<OSStats>,
126}
127
128#[derive(Debug, Default, Clone, Serialize, Deserialize)]
129pub struct StorageStats {
130 path: String,
131 duration: Duration,
132}
133
134#[derive(Debug, Default, Clone, Serialize, Deserialize)]
135pub struct OSStats {
136 path: String,
137 duration: Duration,
138}
139
140#[derive(Debug, Default, Clone, Serialize, Deserialize)]
141pub struct TraceHTTPStats {
142 req_info: TraceRequestInfo,
143 resp_info: TraceResponseInfo,
144 call_stats: TraceCallStats,
145}
146
147#[derive(Debug, Default, Clone, Serialize, Deserialize)]
148pub struct TraceCallStats {
149 input_bytes: i32,
150 output_bytes: i32,
151 latency: Duration,
152 time_to_first_byte: Duration,
153}
154
155#[derive(Debug, Default, Clone, Serialize, Deserialize)]
156pub struct TraceRequestInfo {
157 time: DateTime<Utc>,
158 proto: String,
159 method: String,
160 #[serde(skip_serializing_if = "Option::is_none")]
161 path: Option<String>,
162 #[serde(skip_serializing_if = "Option::is_none")]
163 raw_query: Option<String>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 headers: Option<HashMap<String, String>>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 body: Option<Vec<u8>>,
168 client: String,
169}
170
171#[derive(Debug, Default, Clone, Serialize, Deserialize)]
172pub struct TraceResponseInfo {
173 time: DateTime<Utc>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 headers: Option<HashMap<String, String>>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 body: Option<Vec<u8>>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 status_code: Option<i32>,
180}