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::DEBUG` 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;
}