Crates.io | tracing-tunnel |
lib.rs | tracing-tunnel |
version | 0.2.0-beta.1 |
source | src |
created_at | 2022-12-09 11:55:10.901856 |
updated_at | 2024-03-03 09:52:35.542286 |
description | Tunnelling tracing information across API boundary |
homepage | |
repository | https://github.com/slowli/tracing-toolbox |
max_upload_size | |
id | 733208 |
size | 106,183 |
This crate provides tracing infrastructure helpers allowing to transfer tracing events across an API boundary:
TracingEventSender
is a tracing Subscriber
that converts tracing events
into (de)serializable presentation that can be sent elsewhere using a customizable hook.TracingEventReceiver
consumes events produced by a TracingEventSender
and relays them
to the tracing infrastructure. It is assumed that the source of events may outlive
both the lifetime of a particular TracingEventReceiver
instance, and the lifetime
of the program encapsulating the receiver. To deal with this, the receiver provides
the means to persist / restore its state.This solves the problem of having dynamic call sites for tracing spans / events, i.e., ones not known during compilation. This may occur if call sites are defined in dynamically loaded modules the execution of which is embedded into the program, such as WASM modules.
See the crate docs for the details about the crate design and potential use cases.
Add this to your Crate.toml
:
[dependencies]
tracing-tunnel = "0.2.0-beta.1"
Note that the both pieces of functionality described above are gated behind opt-in features; consult the crate docs for details.
use std::sync::mpsc;
use tracing_tunnel::{TracingEvent, TracingEventSender, TracingEventReceiver};
// Let's collect tracing events using an MPSC channel.
let (events_sx, events_rx) = mpsc::sync_channel(10);
let subscriber = TracingEventSender::new(move |event| {
events_sx.send(event).ok();
});
tracing::subscriber::with_default(subscriber, || {
tracing::info_span!("test", num = 42_i64).in_scope(|| {
tracing::warn!("I feel disturbance in the Force...");
});
});
let events: Vec<TracingEvent> = events_rx.iter().collect();
println!("{events:?}");
// Do something with events...
use std::sync::mpsc;
use tracing_tunnel::{
LocalSpans, PersistedMetadata, PersistedSpans, TracingEvent, TracingEventReceiver,
};
tracing_subscriber::fmt().pretty().init();
fn replay_events(events: &[TracingEvent]) {
let mut spans = PersistedSpans::default();
let mut local_spans = LocalSpans::default();
let mut receiver = TracingEventReceiver::default();
for event in events {
if let Err(err) = receiver.try_receive(event.clone()) {
tracing::warn!(%err, "received invalid tracing event");
}
}
// Persist the resulting receiver state. There are two pieces
// of the state: metadata and alive spans. The spans are further split
// into the persisted and local parts.
let metadata = receiver.persist_metadata();
let (spans, local_spans) = receiver.persist();
// Store `metadata` and `spans`, e.g., in a DB, and `local_spans`
// in a local data struct such as `HashMap` keyed by the executable ID.
}
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in tracing-toolbox
by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.