tracing_perfspan/
lib.rs

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
use probe::probe;
use tracing::{level_filters::LevelFilter, span, Subscriber};
use tracing_subscriber::{
    layer::{Context, SubscriberExt},
    registry::LookupSpan,
    Layer,
};

/// Initialize tracing with PerfspanLayer.
///
/// Uses DEBUG as the default level for spans, but can be overridden by setting
/// the PERF_SPAN_LEVEL environment variable.
pub fn init() {
    let env_filter = tracing_subscriber::EnvFilter::builder()
        .with_default_directive(LevelFilter::DEBUG.into())
        .with_env_var("PERF_SPAN_LEVEL")
        .from_env_lossy();
    let layer = PerfspanLayer {}.with_filter(env_filter);
    let subscriber = tracing_subscriber::Registry::default().with(layer);
    tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
}

pub struct PerfspanLayer {}

impl<S> Layer<S> for PerfspanLayer
where
    S: Subscriber + for<'span> LookupSpan<'span>,
{
    fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
        if let Some(span) = ctx.span(id) {
            let name_size = span.name().len() as u16;
            let name = span.name().as_ptr();
            let span_id = span.id().into_u64();
            probe!(perfspan, enter, span_id, name_size, name);
        }
    }

    fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
        if let Some(span) = ctx.span(id) {
            let name_size = span.name().len() as u16;
            let name = span.name().as_ptr();
            let span_id = span.id().into_u64();
            probe!(perfspan, exit, span_id, name_size, name);
        }
    }
}