etdl-core 0.1.1

ETDL runtime: BranchMonitor, retry policies, SLA anomaly detection, chaos injection, and telemetry for reliability-aware event-driven services
Documentation
use std::fmt;

#[derive(Debug)]
pub struct Error {
    message: String,
}

impl Error {
    pub fn new(msg: impl Into<String>) -> Self {
        Error {
            message: msg.into(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl std::error::Error for Error {}

pub type WorkflowError = Error;

pub fn attach_node_span_attribute(node_id: &str) {
    eprintln!("[etdl.telemetry] span attribute etdl.node.id={}", node_id);
}

pub fn emit_anomaly_event(
    node_id: &str,
    outcome: &str,
    declared_probability: f64,
    observed_frequency: f64,
) {
    eprintln!(
        "[etdl.telemetry] SLA ANOMALY | node={} outcome={} declared={:.6} observed={:.6} deviation={:.6}",
        node_id,
        outcome,
        declared_probability,
        observed_frequency,
        (observed_frequency - declared_probability).abs()
    );
}

pub fn inject_traceparent(message_type: &str) -> String {
    let trace_id = generate_trace_id();
    let span_id = generate_span_id();
    let traceparent = format!("00-{}-{}-01", trace_id, span_id);

    eprintln!(
        "[etdl.telemetry] inject traceparent into {} message: {}",
        message_type, traceparent
    );

    traceparent
}

fn generate_trace_id() -> String {
    use std::time::{SystemTime, UNIX_EPOCH};
    let nanos = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|d| d.as_nanos())
        .unwrap_or(0);
    format!("{:032x}", nanos)
}

fn generate_span_id() -> String {
    use std::time::{SystemTime, UNIX_EPOCH};
    let nanos = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|d| d.as_nanos())
        .unwrap_or(0);
    format!("{:016x}", nanos.wrapping_mul(17))
}