Skip to main content

etdl_core/
telemetry.rs

1use std::fmt;
2
3#[derive(Debug)]
4pub struct Error {
5    message: String,
6}
7
8impl Error {
9    pub fn new(msg: impl Into<String>) -> Self {
10        Error {
11            message: msg.into(),
12        }
13    }
14}
15
16impl fmt::Display for Error {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        write!(f, "{}", self.message)
19    }
20}
21
22impl std::error::Error for Error {}
23
24pub type WorkflowError = Error;
25
26pub fn attach_node_span_attribute(node_id: &str) {
27    eprintln!("[etdl.telemetry] span attribute etdl.node.id={}", node_id);
28}
29
30pub fn emit_anomaly_event(
31    node_id: &str,
32    outcome: &str,
33    declared_probability: f64,
34    observed_frequency: f64,
35) {
36    eprintln!(
37        "[etdl.telemetry] SLA ANOMALY | node={} outcome={} declared={:.6} observed={:.6} deviation={:.6}",
38        node_id,
39        outcome,
40        declared_probability,
41        observed_frequency,
42        (observed_frequency - declared_probability).abs()
43    );
44}
45
46pub fn inject_traceparent(message_type: &str) -> String {
47    let trace_id = generate_trace_id();
48    let span_id = generate_span_id();
49    let traceparent = format!("00-{}-{}-01", trace_id, span_id);
50
51    eprintln!(
52        "[etdl.telemetry] inject traceparent into {} message: {}",
53        message_type, traceparent
54    );
55
56    traceparent
57}
58
59fn generate_trace_id() -> String {
60    use std::time::{SystemTime, UNIX_EPOCH};
61    let nanos = SystemTime::now()
62        .duration_since(UNIX_EPOCH)
63        .map(|d| d.as_nanos())
64        .unwrap_or(0);
65    format!("{:032x}", nanos)
66}
67
68fn generate_span_id() -> String {
69    use std::time::{SystemTime, UNIX_EPOCH};
70    let nanos = SystemTime::now()
71        .duration_since(UNIX_EPOCH)
72        .map(|d| d.as_nanos())
73        .unwrap_or(0);
74    format!("{:016x}", nanos.wrapping_mul(17))
75}