From d33e2fdcf140e29ae6a0cb64cb924b1b374f82fb Mon Sep 17 00:00:00 2001 From: overtrue Date: Fri, 21 Aug 2026 23:53:31 +0800 Subject: [PATCH] chore(madmin): remove dead trace structs, keep TraceType bitflag helper only TraceInfo, TraceInfoLegacy, TraceHTTPStats, TraceCallStats, TraceRequestInfo, TraceResponseInfo, StorageStats, and OSStats are unreferenced outside trace.rs. Trim to TraceType + its bitflag operations which are actively used by service_commands.rs and profile_admin.rs. -139 lines (215 -> 76 lines) --- crates/madmin/src/trace.rs | 170 +++++++------------------------------ 1 file changed, 32 insertions(+), 138 deletions(-) diff --git a/crates/madmin/src/trace.rs b/crates/madmin/src/trace.rs index 1c63d81e5..9863973c6 100644 --- a/crates/madmin/src/trace.rs +++ b/crates/madmin/src/trace.rs @@ -12,18 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::HashMap, time::Duration}; - -use jiff::Timestamp; use serde::{Deserialize, Serialize}; -use crate::heal_commands::HealResultItem; - +/// Bitflag helper for service trace categories. +/// +/// Each variant occupies a single bit so that a `TraceType` value can represent +/// an arbitrary combination of categories via bitwise OR. #[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)] pub struct TraceType(u64); impl TraceType { - // Define some constants pub const OS: TraceType = TraceType(1 << 0); pub const STORAGE: TraceType = TraceType(1 << 1); pub const S3: TraceType = TraceType(1 << 2); @@ -40,15 +38,13 @@ impl TraceType { pub const FTP: TraceType = TraceType(1 << 13); pub const ILM: TraceType = TraceType(1 << 14); - // MetricsAll must be last. + /// All trace categories combined. Must be updated when adding new variants. pub const ALL: TraceType = TraceType((1 << 15) - 1); pub fn new(t: u64) -> Self { Self(t) } -} -impl TraceType { pub fn contains(&self, x: &TraceType) -> bool { (self.0 & x.0) == x.0 } @@ -76,140 +72,38 @@ impl TraceType { } } -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceInfo { - #[serde(rename = "type")] - trace_type: u64, - #[serde(rename = "nodename")] - node_name: String, - #[serde(rename = "funcname")] - func_name: String, - #[serde(rename = "time")] - time: Timestamp, - #[serde(rename = "path")] - path: String, - #[serde(rename = "dur")] - duration: Duration, - #[serde(rename = "bytes", skip_serializing_if = "Option::is_none")] - bytes: Option, - #[serde(rename = "msg", skip_serializing_if = "Option::is_none")] - message: Option, - #[serde(rename = "error", skip_serializing_if = "Option::is_none")] - error: Option, - #[serde(rename = "custom", skip_serializing_if = "Option::is_none")] - custom: Option>, - #[serde(rename = "http", skip_serializing_if = "Option::is_none")] - http: Option, - #[serde(rename = "healResult", skip_serializing_if = "Option::is_none")] - heal_result: Option, -} - -impl TraceInfo { - pub fn mask(&self) -> u64 { - TraceType::new(self.trace_type).mask() - } -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceInfoLegacy { - trace_info: TraceInfo, - #[serde(rename = "request")] - req_info: Option, - #[serde(rename = "response")] - resp_info: Option, - #[serde(rename = "stats")] - call_stats: Option, - #[serde(rename = "storageStats")] - storage_stats: Option, - #[serde(rename = "osStats")] - os_stats: Option, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct StorageStats { - path: String, - duration: Duration, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct OSStats { - path: String, - duration: Duration, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceHTTPStats { - req_info: TraceRequestInfo, - resp_info: TraceResponseInfo, - call_stats: TraceCallStats, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceCallStats { - input_bytes: i32, - output_bytes: i32, - latency: Duration, - time_to_first_byte: Duration, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceRequestInfo { - time: Timestamp, - proto: String, - method: String, - #[serde(skip_serializing_if = "Option::is_none")] - path: Option, - #[serde(skip_serializing_if = "Option::is_none")] - raw_query: Option, - #[serde(skip_serializing_if = "Option::is_none")] - headers: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - body: Option>, - client: String, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct TraceResponseInfo { - time: Timestamp, - #[serde(skip_serializing_if = "Option::is_none")] - headers: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - body: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - status_code: Option, -} - #[cfg(test)] mod tests { use super::*; #[test] - fn trace_timestamps_serialize_as_rfc3339_utc() { - let timestamp = Timestamp::constant(1_700_000_000, 123_456_000); - let trace = TraceInfo { - time: timestamp, - http: Some(TraceHTTPStats { - req_info: TraceRequestInfo { - time: timestamp, - ..Default::default() - }, - resp_info: TraceResponseInfo { - time: timestamp, - ..Default::default() - }, - ..Default::default() - }), - ..Default::default() - }; + fn trace_type_contains_and_overlaps() { + let mut combined = TraceType::default(); + combined.merge(&TraceType::S3); + combined.merge(&TraceType::HEALING); - let value = serde_json::to_value(trace).expect("trace should serialize"); - assert_eq!(value["time"], "2023-11-14T22:13:20.123456Z"); - assert_eq!(value["http"]["req_info"]["time"], "2023-11-14T22:13:20.123456Z"); - assert_eq!(value["http"]["resp_info"]["time"], "2023-11-14T22:13:20.123456Z"); - let trace: TraceInfo = serde_json::from_value(value).expect("trace should deserialize"); - assert_eq!(trace.time, timestamp); - let http = trace.http.expect("http trace should deserialize"); - assert_eq!(http.req_info.time, timestamp); - assert_eq!(http.resp_info.time, timestamp); + assert!(combined.contains(&TraceType::S3)); + assert!(combined.contains(&TraceType::HEALING)); + assert!(!combined.contains(&TraceType::SCANNER)); + assert!(combined.overlaps(&TraceType::S3)); + assert!(combined.overlaps(&TraceType::HEALING)); + assert!(!combined.overlaps(&TraceType::SCANNER)); + } + + #[test] + fn trace_type_set_if() { + let mut tt = TraceType::default(); + tt.set_if(true, &TraceType::OS); + tt.set_if(false, &TraceType::S3); + assert!(tt.contains(&TraceType::OS)); + assert!(!tt.contains(&TraceType::S3)); + } + + #[test] + fn trace_type_single_type() { + assert!(TraceType::S3.single_type()); + let mut combined = TraceType::S3; + combined.merge(&TraceType::HEALING); + assert!(!combined.single_type()); } }