Skip to main content

rustfs_madmin/
trace.rs

1// Copyright 2024 RustFS Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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    // 定义一些常量
27    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    // MetricsAll must be last.
44    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}