1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
//! the test span library provides you with two functions:
//!
//! `get_logs()` that returns [`prelude::Records`]
//!
//! `get_span()` that returns a [`prelude::Span`],
//! Which can be serialized and used with [insta](https://crates.io/crates/insta) for snapshot tests.
//! Refer to the tests.rs file to see how it behaves.
//!
//! Example:
//! ```ignore
//! #[test_span]
//! async fn test_it_works() {
//! futures::join!(do_stuff(), do_stuff())
//! }
//!
//! #[tracing::instrument(name = "do_stuff", level = "info")]
//! async fn do_stuff() -> u8 {
//! // ...
//! do_stuff2().await;
//! }
//!
//! #[tracing::instrument(
//! name = "do_stuff2",
//! target = "my_crate::an_other_target",
//! level = "info"
//! )]
//! async fn do_stuff_2(number: u8) -> u8 {
//! // ...
//! }
//! ```
//! ```text
//! `get_span()` will provide you with:
//!
//! ┌──────┐
//! │ root │
//! └──┬───┘
//! │
//! ┌───────┴───────┐
//! ▼ ▼
//! ┌──────────┐ ┌──────────┐
//! │ do_stuff │ │ do_stuff │
//! └────┬─────┘ └─────┬────┘
//! │ │
//! │ │
//! ▼ ▼
//! ┌───────────┐ ┌───────────┐
//! │ do_stuff2 │ │ do_stuff2 │
//! └───────────┘ └───────────┘
//! ```
use layer::Layer;
use once_cell::sync::Lazy;
use std::sync::{Arc, Mutex};
use tracing::Id;
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt};
type LazyMutex<T> = Lazy<Arc<Mutex<T>>>;
mod attribute;
mod layer;
mod log;
mod record;
mod report;
pub use record::{Record, RecordValue};
pub use report::{Filter, Records, Report, Span};
static INIT: Lazy<()> = Lazy::new(|| {
tracing_subscriber::registry()
.with(Layer {})
.try_init().expect("couldn't set test-span subscriber as a default, maybe tracing has already been initialized somewhere else ?")
});
/// `init_default` is the default way to call `with_targets`,
/// it sets up `Level::INFO` and looks for environment variables to filter spans.
pub fn init() {
Lazy::force(&INIT);
}
/// Unlike its `get_logs` counterpart provided by the trace_span macro,
/// `get_all_logs` will return all of the module's tests logs.
pub fn get_all_logs(filter: &Filter) -> Records {
let logs = layer::ALL_LOGS.lock().unwrap().clone();
Records::new(logs.all_records_for_filter(filter))
}
/// Returns both the output of `get_spans_for_root` and `get_logs_for_root`
pub fn get_telemetry_for_root(root_id: &Id, filter: &Filter) -> (Span, Records) {
let report = Report::from_root(root_id.into_u64());
(report.spans(filter), report.logs(filter))
}
/// Returns a `Span`, a Tree containing all the spans that are children of `root_id`.
///
/// This function filters the `Span` children and `Records`,
/// to only return the ones that match the set verbosity level
pub fn get_spans_for_root(root_id: &Id, filter: &Filter) -> Span {
Report::from_root(root_id.into_u64()).spans(filter)
}
/// Returns Records, which is a Vec, containing all entries recorded by children of `root_id`.
///
/// This function filters the `Records`to only return the ones that match the set verbosity level.
///
/// / ! \ Logs recorded in spawned threads won't appear here / ! \ use `get_all_logs` instead.
pub fn get_logs_for_root(root_id: &Id, filter: &Filter) -> Records {
Report::from_root(root_id.into_u64()).logs(filter)
}
pub mod prelude {
pub use crate::{get_all_logs, get_logs_for_root, get_spans_for_root, get_telemetry_for_root};
pub use test_span_macro::test_span;
}
pub mod reexports {
pub use daggy;
pub use serde;
pub use tracing;
pub use tracing_futures;
pub use tracing_subscriber;
}