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))
}