starweaver_runtime/trace/
types.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use starweaver_core::TraceContext;
6
7#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
9#[serde(rename_all = "snake_case")]
10pub enum TraceLevel {
11 #[default]
13 Info,
14 Debug,
16}
17
18#[allow(clippy::trivially_copy_pass_by_ref)]
19const fn is_default_trace_level(level: &TraceLevel) -> bool {
20 matches!(level, TraceLevel::Info)
21}
22
23#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
25#[serde(rename_all = "snake_case")]
26pub enum SpanKind {
27 #[default]
29 Internal,
30 Client,
32 Server,
34}
35
36#[allow(clippy::trivially_copy_pass_by_ref)]
37const fn is_default_span_kind(kind: &SpanKind) -> bool {
38 matches!(kind, SpanKind::Internal)
39}
40
41#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
43#[serde(rename_all = "snake_case")]
44pub enum SpanStatus {
45 Open,
47 Ok,
49 Error {
51 error_type: String,
53 },
54}
55
56#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
58pub struct SpanEvent {
59 pub name: String,
61 #[serde(default, skip_serializing_if = "is_default_trace_level")]
63 pub level: TraceLevel,
64 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
66 pub attributes: BTreeMap<String, Value>,
67}
68
69impl SpanEvent {
70 #[must_use]
72 pub fn new(name: impl Into<String>) -> Self {
73 Self {
74 name: name.into(),
75 level: TraceLevel::Info,
76 attributes: BTreeMap::new(),
77 }
78 }
79
80 #[must_use]
82 pub const fn debug(mut self) -> Self {
83 self.level = TraceLevel::Debug;
84 self
85 }
86
87 #[must_use]
89 pub fn with_attribute(mut self, key: impl Into<String>, value: Value) -> Self {
90 self.attributes.insert(key.into(), value);
91 self
92 }
93}
94
95#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
97pub struct SpanSpec {
98 pub name: String,
100 #[serde(default, skip_serializing_if = "is_default_span_kind")]
102 pub kind: SpanKind,
103 #[serde(default, skip_serializing_if = "is_default_trace_level")]
105 pub level: TraceLevel,
106 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
108 pub attributes: BTreeMap<String, Value>,
109}
110
111impl SpanSpec {
112 #[must_use]
114 pub fn new(name: impl Into<String>) -> Self {
115 Self {
116 name: name.into(),
117 kind: SpanKind::Internal,
118 level: TraceLevel::Info,
119 attributes: BTreeMap::new(),
120 }
121 }
122
123 #[must_use]
125 pub const fn with_kind(mut self, kind: SpanKind) -> Self {
126 self.kind = kind;
127 self
128 }
129
130 #[must_use]
132 pub const fn debug(mut self) -> Self {
133 self.level = TraceLevel::Debug;
134 self
135 }
136
137 #[must_use]
139 pub fn with_attribute(mut self, key: impl Into<String>, value: Value) -> Self {
140 self.attributes.insert(key.into(), value);
141 self
142 }
143}
144
145#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
147pub struct RecordedSpan {
148 pub span_id: String,
150 pub trace_id: String,
152 #[serde(default, skip_serializing_if = "Option::is_none")]
154 pub parent_span_id: Option<String>,
155 pub name: String,
157 #[serde(default, skip_serializing_if = "is_default_span_kind")]
159 pub kind: SpanKind,
160 #[serde(default, skip_serializing_if = "is_default_trace_level")]
162 pub level: TraceLevel,
163 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
165 pub attributes: BTreeMap<String, Value>,
166 #[serde(default, skip_serializing_if = "Vec::is_empty")]
168 pub events: Vec<SpanEvent>,
169 pub status: SpanStatus,
171}
172
173#[derive(Clone, Debug)]
175pub struct SpanHandle {
176 context: TraceContext,
177 span_id: String,
178}
179
180impl SpanHandle {
181 pub(super) fn new(context: TraceContext, span_id: impl Into<String>) -> Self {
182 Self {
183 context,
184 span_id: span_id.into(),
185 }
186 }
187
188 #[must_use]
190 pub const fn context(&self) -> &TraceContext {
191 &self.context
192 }
193
194 #[must_use]
196 pub fn into_context(self) -> TraceContext {
197 self.context
198 }
199
200 #[must_use]
202 pub fn span_id(&self) -> &str {
203 &self.span_id
204 }
205}