1use std::collections::HashMap;
10use std::sync::atomic::{AtomicU64, Ordering};
11use trace_weft_core::{EventId, EventKind, EventRecord, RunId, SpanId, TraceId};
12use uuid::Uuid;
13
14static EVENT_SEQ: AtomicU64 = AtomicU64::new(0);
16
17pub struct EventBuilder {
18 event: EventRecord,
19}
20
21impl EventBuilder {
22 pub fn new(kind: EventKind, name: impl Into<String>) -> Self {
23 let now = std::time::SystemTime::now()
24 .duration_since(std::time::UNIX_EPOCH)
25 .unwrap_or_default()
26 .as_millis() as u64;
27
28 let mut event = EventRecord {
29 event_id: EventId(Uuid::now_v7()),
30 trace_id: TraceId(Uuid::now_v7()),
31 run_id: RunId(Uuid::now_v7()),
32 parent_span_id: None,
33 seq: 0,
34 event_kind: kind,
35 name: name.into(),
36 timestamp: now,
37 attributes: HashMap::new(),
38 schema_version: "1.0".to_string(),
39 };
40
41 if let Some(ctx) = crate::context::current_span_context() {
43 event.trace_id = ctx.trace_id;
44 event.run_id = ctx.run_id;
45 event.parent_span_id = Some(ctx.span_id);
46 }
47
48 Self { event }
49 }
50
51 pub fn with_parent(mut self, trace_id: TraceId, run_id: RunId, parent_id: SpanId) -> Self {
53 self.event.trace_id = trace_id;
54 self.event.run_id = run_id;
55 self.event.parent_span_id = Some(parent_id);
56 self
57 }
58
59 pub fn attribute(mut self, key: impl Into<String>, value: serde_json::Value) -> Self {
60 self.event.attributes.insert(key.into(), value);
61 self
62 }
63
64 pub fn attributes(mut self, attrs: HashMap<String, serde_json::Value>) -> Self {
65 self.event.attributes.extend(attrs);
66 self
67 }
68
69 pub async fn record(mut self) {
71 self.event.seq = EVENT_SEQ.fetch_add(1, Ordering::Relaxed);
72 crate::record_event(self.event).await;
73 }
74}
75
76pub fn event(kind: EventKind, name: impl Into<String>) -> EventBuilder {
78 EventBuilder::new(kind, name)
79}