Skip to content

Commit

Permalink
feat: add LocalSpans::to_span_records()
Browse files Browse the repository at this point in the history
Signed-off-by: Andy Lok <[email protected]>
  • Loading branch information
andylokandy committed Jan 23, 2024
1 parent e62aca4 commit b099e24
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
19 changes: 19 additions & 0 deletions minitrace/src/collector/global_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use once_cell::sync::Lazy;
use parking_lot::Mutex;

use super::EventRecord;
use super::SpanContext;
use crate::collector::command::CollectCommand;
use crate::collector::command::CommitCollect;
use crate::collector::command::DropCollect;
Expand Down Expand Up @@ -416,6 +417,24 @@ impl GlobalCollector {
}
}

impl LocalSpansInner {
pub fn to_span_records(&self, parent: SpanContext) -> Vec<SpanRecord> {
let anchor: Anchor = Anchor::new();
let mut dangling_events = HashMap::new();
let mut records = Vec::new();
amend_local_span(
self,
parent.trace_id,
parent.span_id,
&mut records,
&mut dangling_events,
&anchor,
);
mount_events(&mut records, &mut dangling_events);
records
}
}

fn amend_local_span(
local_spans: &LocalSpansInner,
trace_id: TraceId,
Expand Down
75 changes: 75 additions & 0 deletions minitrace/src/local/local_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use minstant::Instant;
use crate::local::local_span_stack::LocalSpanStack;
use crate::local::local_span_stack::SpanLineHandle;
use crate::local::local_span_stack::LOCAL_SPAN_STACK;
use crate::prelude::SpanContext;
use crate::prelude::SpanRecord;
use crate::util::CollectToken;
use crate::util::RawSpans;

Expand Down Expand Up @@ -183,13 +185,64 @@ impl Drop for LocalCollector {
}
}

impl LocalSpans {
/// Converts the `LocalSpans` to `SpanRecord`s.
///
/// The converted spans will appear as if they were collected within the given parent context.
/// The parent of the top local span is set to the given parent.
///
/// This function is particularly useful when you want to manually collect the span records
/// without involving the global collector. This function does not require that the global
/// collector is set up by [`set_reporter()`].
///
/// # Example
///
/// ```rust
/// use minitrace::local::LocalCollector;
/// use minitrace::local::LocalSpans;
/// use minitrace::prelude::*;
///
/// // Collect local spans manually without a parent
/// let collector = LocalCollector::start();
/// let span = LocalSpan::enter_with_local_parent("a child span");
/// drop(span);
///
/// // Collect local spans into a LocalSpans instance
/// let local_spans: LocalSpans = collector.collect();
///
/// // Convert LocalSpans to SpanRecords with a given parent context
/// let parent_context = SpanContext::random();
/// let span_records = local_spans.to_span_records(parent_context);
///
/// // Now you can manually handle the span records
/// for record in span_records {
/// println!("{:?}", record);
/// }
/// ```
///
/// [`set_reporter()`]: crate::set_reporter
pub fn to_span_records(&self, parent: SpanContext) -> Vec<SpanRecord> {
#[cfg(not(feature = "enable"))]
{
vec![]
}

#[cfg(feature = "enable")]
{
self.inner.as_ref().to_span_records(parent)
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::collector::CollectTokenItem;
use crate::collector::SpanId;
use crate::prelude::LocalSpan;
use crate::prelude::TraceId;
use crate::util::tree::tree_str_from_raw_spans;
use crate::util::tree::tree_str_from_span_records;

#[test]
fn local_collector_basic() {
Expand Down Expand Up @@ -259,4 +312,26 @@ span1 []
"
);
}

#[test]
fn local_spans_to_span_record() {
let collector = LocalCollector::start();
let span1 = LocalSpan::enter_with_local_parent("span1").with_property(|| ("k1", "v1"));
let span2 = LocalSpan::enter_with_local_parent("span2").with_property(|| ("k2", "v2"));
drop(span2);
drop(span1);

let local_spans: LocalSpans = collector.collect();

let parent_context = SpanContext::random();
let span_records = local_spans.to_span_records(parent_context);

assert_eq!(
tree_str_from_span_records(span_records),
r#"
span1 [("k1", "v1")]
span2 [("k2", "v2")]
"#
);
}
}

0 comments on commit b099e24

Please sign in to comment.