pub struct SpanRecord {Show 15 fields
pub trace_id: [u8; 16],
pub span_id: [u8; 8],
pub parent_span_id: Option<[u8; 8]>,
pub span_name: String,
pub span_kind: SpanKind,
pub start_time_nanos: u64,
pub end_time_nanos: u64,
pub duration_nanos: u64,
pub logical_clock: u64,
pub status_code: StatusCode,
pub status_message: String,
pub attributes_json: String,
pub resource_json: String,
pub process_id: u32,
pub thread_id: u64,
}Expand description
Span record compatible with trueno-db Parquet storage
This is the canonical schema for all spans recorded by renacer. Each span represents a single operation (syscall, function call, GPU kernel, etc.) with complete metadata for causal analysis.
§Example
use renacer::span_record::{SpanRecord, SpanKind, StatusCode};
use std::collections::HashMap;
let span = SpanRecord {
trace_id: [0x4b, 0xf9, 0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9,
0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9, 0x2f, 0x3c],
span_id: [0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7],
parent_span_id: None,
span_name: "read".to_string(),
span_kind: SpanKind::Internal,
start_time_nanos: 1700000000000000000,
end_time_nanos: 1700000000000050000,
duration_nanos: 50000,
logical_clock: 42,
status_code: StatusCode::Ok,
status_message: String::new(),
attributes_json: r#"{"syscall.name":"read","syscall.fd":3,"syscall.bytes":1024}"#.to_string(),
resource_json: r#"{"service.name":"renacer","process.pid":1234}"#.to_string(),
process_id: 1234,
thread_id: 1234,
};Fields§
§trace_id: [u8; 16]W3C Trace Context trace ID (128-bit / 16 bytes)
Format: 32 hex characters (e.g., 4bf92f3c7b644bf92f3c7b644bf92f3c)
This is the “golden thread” that links all operations across the entire pipeline (Rust binary → transpilation → syscalls).
span_id: [u8; 8]W3C Trace Context span ID (64-bit / 8 bytes)
Format: 16 hex characters (e.g., 00f067aa0ba902b7)
Uniquely identifies this span within the trace.
parent_span_id: Option<[u8; 8]>Parent span ID (if this span has a parent)
Noneindicates this is a root spanSome(id)indicates this span is a child of another span
span_name: StringHuman-readable span name (e.g., “read”, “write”, “GPU kernel”, “HTTP GET”)
Should follow OpenTelemetry semantic conventions:
- Syscalls: use syscall name (e.g., “read”, “write”)
- Functions: use function name (e.g., “
process_request”) - HTTP: use “HTTP {method}” (e.g., “HTTP GET”)
span_kind: SpanKindSpan kind (internal, server, client, producer, consumer)
Indicates the role of this span in the request flow.
start_time_nanos: u64Start time in nanoseconds since UNIX epoch
This is the physical timestamp (subject to clock skew).
Use logical_clock for causal ordering.
end_time_nanos: u64End time in nanoseconds since UNIX epoch
This is the physical timestamp (subject to clock skew).
Use logical_clock for causal ordering.
duration_nanos: u64Span duration in nanoseconds (end_time - start_time)
This is a computed field for query convenience.
logical_clock: u64Lamport logical clock timestamp
This provides a mathematical guarantee of causal ordering:
if event A → B (happens-before), then logical_clock(A) < logical_clock(B).
Use this for:
- Critical path analysis (longest path in causal graph)
- Detecting race conditions (concurrent events have incomparable clocks)
- Cross-process ordering (even with clock skew)
status_code: StatusCodeSpan status code (unset, ok, error)
status_message: StringSpan status message (empty if OK, error message if ERROR)
attributes_json: StringSpan attributes as JSON string
This contains all key-value metadata about the span:
- Syscall arguments:
{"syscall.name":"read","syscall.fd":3,"syscall.bytes":1024} - File paths:
{"file.path":"/etc/passwd","file.line":42} - HTTP:
{"http.method":"GET","http.url":"https://example.com"}
Stored as JSON to maintain flat Parquet schema (no nested columns).
resource_json: StringResource attributes as JSON string
This contains metadata about the execution environment:
{"service.name":"renacer","process.pid":1234,"host.name":"server1"}
Stored as JSON to maintain flat Parquet schema.
process_id: u32Process ID (for filtering by process)
thread_id: u64Thread ID (for filtering by thread)
Implementations§
Source§impl SpanRecord
impl SpanRecord
Sourcepub fn new(
trace_id: [u8; 16],
span_id: [u8; 8],
parent_span_id: Option<[u8; 8]>,
span_name: String,
span_kind: SpanKind,
start_time_nanos: u64,
end_time_nanos: u64,
logical_clock: u64,
status_code: StatusCode,
status_message: String,
attributes: HashMap<String, String>,
resource: HashMap<String, String>,
process_id: u32,
thread_id: u64,
) -> Self
pub fn new( trace_id: [u8; 16], span_id: [u8; 8], parent_span_id: Option<[u8; 8]>, span_name: String, span_kind: SpanKind, start_time_nanos: u64, end_time_nanos: u64, logical_clock: u64, status_code: StatusCode, status_message: String, attributes: HashMap<String, String>, resource: HashMap<String, String>, process_id: u32, thread_id: u64, ) -> Self
Create a new SpanRecord with computed duration
§Arguments
trace_id- W3C Trace Context trace ID (16 bytes)span_id- W3C Trace Context span ID (8 bytes)parent_span_id- Parent span ID (None for root spans)span_name- Human-readable span namespan_kind- Span kind (internal, server, client, etc.)start_time_nanos- Start time in nanoseconds since UNIX epochend_time_nanos- End time in nanoseconds since UNIX epochlogical_clock- Lamport logical clock timestampstatus_code- Span status codestatus_message- Span status messageattributes- Span attributes (will be serialized to JSON)resource- Resource attributes (will be serialized to JSON)process_id- Process IDthread_id- Thread ID
§Example
use renacer::span_record::{SpanRecord, SpanKind, StatusCode};
use std::collections::HashMap;
let mut attributes = HashMap::new();
attributes.insert("syscall.name".to_string(), "read".to_string());
attributes.insert("syscall.fd".to_string(), "3".to_string());
let mut resource = HashMap::new();
resource.insert("service.name".to_string(), "renacer".to_string());
let span = SpanRecord::new(
[0x4b, 0xf9, 0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9,
0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9, 0x2f, 0x3c],
[0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7],
None,
"read".to_string(),
SpanKind::Internal,
1700000000000000000,
1700000000000050000,
42,
StatusCode::Ok,
String::new(),
attributes,
resource,
1234,
1234,
);
assert_eq!(span.duration_nanos, 50000);Sourcepub fn parse_attributes(&self) -> HashMap<String, String>
pub fn parse_attributes(&self) -> HashMap<String, String>
Parse attributes from JSON string
§Returns
HashMap of attribute key-value pairs, or empty map if parse fails.
Sourcepub fn parse_resource(&self) -> HashMap<String, String>
pub fn parse_resource(&self) -> HashMap<String, String>
Parse resource attributes from JSON string
§Returns
HashMap of resource key-value pairs, or empty map if parse fails.
Sourcepub fn trace_id_hex(&self) -> String
pub fn trace_id_hex(&self) -> String
Get trace ID as hex string (W3C Trace Context format)
§Example
use renacer::span_record::{SpanRecord, SpanKind, StatusCode};
use std::collections::HashMap;
let span = SpanRecord::new(
[0x4b, 0xf9, 0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9,
0x2f, 0x3c, 0x7b, 0x64, 0x4b, 0xf9, 0x2f, 0x3c],
[0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7],
None,
"test".to_string(),
SpanKind::Internal,
0, 0, 0,
StatusCode::Ok,
String::new(),
HashMap::new(),
HashMap::new(),
0, 0,
);
assert_eq!(span.trace_id_hex(), "4bf92f3c7b644bf92f3c7b644bf92f3c");Sourcepub fn span_id_hex(&self) -> String
pub fn span_id_hex(&self) -> String
Get span ID as hex string (W3C Trace Context format)
Sourcepub fn parent_span_id_hex(&self) -> Option<String>
pub fn parent_span_id_hex(&self) -> Option<String>
Get parent span ID as hex string (W3C Trace Context format)
Trait Implementations§
Source§impl Clone for SpanRecord
impl Clone for SpanRecord
Source§fn clone(&self) -> SpanRecord
fn clone(&self) -> SpanRecord
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SpanRecord
impl Debug for SpanRecord
Source§impl<'de> Deserialize<'de> for SpanRecord
impl<'de> Deserialize<'de> for SpanRecord
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for SpanRecord
impl PartialEq for SpanRecord
Source§fn eq(&self, other: &SpanRecord) -> bool
fn eq(&self, other: &SpanRecord) -> bool
self and other values to be equal, and is used by ==.