use crate::sdk;
use crate::trace::{IdGenerator, SpanId, TraceId};
use std::time::{Duration, UNIX_EPOCH};
#[derive(Debug, Default)]
pub struct XrayIdGenerator {
sdk_default_generator: sdk::trace::IdGenerator,
}
impl IdGenerator for XrayIdGenerator {
fn new_trace_id(&self) -> TraceId {
let mut default_trace_id: String =
format!("{:024x}", self.sdk_default_generator.new_trace_id());
default_trace_id.truncate(24);
let epoch_time_seconds: u64 = crate::time::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_else(|_| Duration::from_secs(0))
.as_secs();
TraceId::from_hex(format!("{:08x}{}", epoch_time_seconds, default_trace_id).as_str())
.unwrap_or(TraceId::INVALID)
}
fn new_span_id(&self) -> SpanId {
self.sdk_default_generator.new_span_id()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread::sleep;
#[test]
fn test_trace_id_generation() {
let before: u64 = crate::time::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
sleep(Duration::from_secs(1));
let generator: XrayIdGenerator = XrayIdGenerator::default();
let trace_id: TraceId = generator.new_trace_id();
sleep(Duration::from_secs(1));
let after: u64 = crate::time::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let trace_as_hex: String = format!("{:032x}", trace_id);
let (timestamp, _xray_id) = trace_as_hex.split_at(8_usize);
let trace_time: u64 = u64::from_str_radix(timestamp, 16).unwrap();
assert!(before <= trace_time);
assert!(after >= trace_time);
}
}