tracing_profile/layers/
init_tracing.rs1use cfg_if::cfg_if;
4use thiserror::Error;
5use tracing::{level_filters::LevelFilter, Subscriber};
6use tracing_subscriber::filter::EnvFilter;
7use tracing_subscriber::{
8 filter::Filtered,
9 layer::SubscriberExt,
10 util::{SubscriberInitExt, TryInitError},
11 Layer,
12};
13
14use crate::{PrintTreeConfig, PrintTreeLayer};
15
16trait WithEnvFilter<S: Subscriber>: Layer<S> + Sized {
17 fn with_env_filter(self) -> Filtered<Self, EnvFilter, S> {
18 let env_level_filter = EnvFilter::builder()
19 .with_default_directive(LevelFilter::DEBUG.into())
20 .from_env_lossy();
21
22 self.with_filter(env_level_filter)
23 }
24}
25
26impl<S: Subscriber, T: Layer<S>> WithEnvFilter<S> for T {}
27
28#[derive(Debug, Error)]
29pub enum Error {
30 #[error("failed to initialize tracing: {0}")]
31 TryInit(#[from] TryInitError),
32 #[cfg(feature = "perfetto")]
33 #[error("failed to initialize Perfetto: {0}")]
34 Perfetto(#[from] perfetto_sys::Error),
35 #[cfg(feature = "perf_counters")]
36 #[error("failed to initialize PerfCounters: {0}")]
37 PerfCounters(#[from] std::io::Error),
38 #[cfg(feature = "gen_filename")]
39 #[error("failed to initialize filename builder: {0}")]
40 FilenameBuilder(#[from] crate::filename_builder::FilenameBuilderError),
41}
42
43#[cfg(feature = "gen_filename")]
45mod filename_support {
46 pub use crate::filename_builder::TraceFilenameBuilder;
47 pub type BuilderOption = Option<TraceFilenameBuilder>;
48}
49
50#[cfg(not(feature = "gen_filename"))]
51mod filename_support {
52 pub type BuilderOption = Option<()>;
53}
54
55use filename_support::BuilderOption;
56
57fn init_tracing_internal(_builder: BuilderOption) -> Result<impl Drop, Error> {
69 let (layer, guard) = PrintTreeLayer::new(PrintTreeConfig::default());
71 let layer = tracing_subscriber::registry().with(layer.with_env_filter());
72
73 let (layer, guard) = {
75 cfg_if! {
76 if #[cfg(feature = "perfetto")] {
77 let (new_layer, new_guard) = match _builder {
78 None => {
79 crate::PerfettoLayer::new_from_env()?
80 }
81 Some(builder) => {
82 crate::PerfettoLayer::new_from_env_with_builder(builder)
83 .map_err(Error::Perfetto)?
84 }
85 };
86 (layer.with(new_layer.with_env_filter()), crate::data::GuardWrapper::wrap(guard, new_guard))
87 } else {
88 (layer, guard)
89 }
90 }
91 };
92
93 let (layer, guard) = {
95 cfg_if! {
96 if #[cfg(feature = "ittapi")] {
97 (layer.with(crate::IttApiLayer::new().with_env_filter()), guard)
98 } else {
99 (layer, guard)
100 }
101 }
102 };
103
104 let (layer, guard) = {
106 cfg_if! {
107 if #[cfg(feature = "tracy")] {
108 (layer.with(crate::TracyLayer::default().with_env_filter()), guard)
109 } else {
110 (layer, guard)
111 }
112 }
113 };
114
115 let (layer, guard) = {
117 cfg_if! {
118 if #[cfg(feature = "perf_counters")] {
119 (layer.with(
120 crate::PrintPerfCountersLayer::new(vec![
121 ("instructions".to_string(), crate::PerfHardwareEvent::INSTRUCTIONS.into()),
122 ("cycles".to_string(), crate::PerfHardwareEvent::CPU_CYCLES.into()),
123 ])?
124 .with_env_filter(),
125 ), guard)
126 } else {
127 (layer, guard)
128 }
129 }
130 };
131
132 match layer.try_init() {
134 Ok(()) => {
135 }
137 Err(_) => {
138 }
142 }
143
144 Ok(guard)
145}
146
147pub fn init_tracing() -> Result<impl Drop, Error> {
157 init_tracing_internal(None)
158}
159
160#[cfg(feature = "gen_filename")]
178pub fn init_tracing_with_builder(
179 builder: crate::filename_builder::TraceFilenameBuilder,
180) -> Result<impl Drop, Error> {
181 init_tracing_internal(Some(builder))
182}