1#[cfg(feature = "tracing")]
6mod fuchsia;
7#[cfg(feature = "tracing")]
8pub mod __backend {
9 pub use crate::fuchsia::*;
10}
11
12#[cfg(not(feature = "tracing"))]
13mod noop;
14#[cfg(not(feature = "tracing"))]
15pub mod __backend {
16 pub use crate::noop::*;
17}
18
19pub use __backend::{Id, TraceFutureExt};
20
21#[macro_export]
26macro_rules! duration {
27 ($category:expr, $name:expr $(, $key:expr => $val:expr)*) => {
28 let args;
29 let _scope = {
30 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
31 if $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE)
32 .is_some()
33 {
34 args = [$($crate::__backend::ArgValue::of($key, $val)),*];
35 Some($crate::__backend::duration($category, $name, &args))
36 } else {
37 None
38 }
39 };
40 }
41}
42
43#[macro_export]
47macro_rules! flow_begin {
48 ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {{
49 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
50 if let Some(context) =
51 $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE)
52 {
53 $crate::__backend::flow_begin(&context, $name, ($flow_id).into(),
54 &[$($crate::__backend::ArgValue::of($key, $val)),*])
55 }
56 }}
57}
58
59#[macro_export]
63macro_rules! flow_step {
64 ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {{
65 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
66 if let Some(context) =
67 $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE)
68 {
69 $crate::__backend::flow_step(&context, $name, ($flow_id).into(),
70 &[$($crate::__backend::ArgValue::of($key, $val)),*])
71 }
72 }}
73}
74
75#[macro_export]
79macro_rules! flow_end {
80 ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {{
81 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
82 if let Some(context) =
83 $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE)
84 {
85 $crate::__backend::flow_end(&context, $name, ($flow_id).into(),
86 &[$($crate::__backend::ArgValue::of($key, $val)),*])
87 }
88 }}
89}
90
91#[macro_export]
95macro_rules! trace_future_args {
96 ($category:expr, $name:expr $(, $key:expr => $val:expr)*) => {{
97 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
98 let context = $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE);
99 let args = if context.is_some() {
100 vec![$($crate::__backend::ArgValue::of($key, $val)),*]
101 } else {
102 vec![]
103 };
104 $crate::__backend::trace_future_args(context, $category, $name, args)
105 }}
106}
107
108#[cfg(test)]
109mod tests {
110 use crate::TraceFutureExt;
111
112 #[fuchsia::test]
113 fn test_duration() {
114 let trace_only_var = 6;
115 duration!(c"category", c"name");
116 duration!(c"category", c"name", "arg" => 5);
117 duration!(c"category", c"name", "arg" => 5, "arg2" => trace_only_var);
118 }
119
120 #[fuchsia::test]
121 fn test_flow_begin() {
122 let trace_only_var = 6;
123 let flow_id = 5u64;
124 flow_begin!(c"category", c"name", flow_id);
125 flow_begin!(c"category", c"name", flow_id, "arg" => 5);
126 flow_begin!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
127 }
128
129 #[fuchsia::test]
130 fn test_flow_step() {
131 let trace_only_var = 6;
132 let flow_id = 5u64;
133 flow_step!(c"category", c"name", flow_id);
134 flow_step!(c"category", c"name", flow_id, "arg" => 5);
135 flow_step!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
136 }
137
138 #[fuchsia::test]
139 fn test_flow_end() {
140 let trace_only_var = 6;
141 let flow_id = 5u64;
142 flow_end!(c"category", c"name", flow_id);
143 flow_end!(c"category", c"name", flow_id, "arg" => 5);
144 flow_end!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
145 }
146
147 #[fuchsia::test]
148 async fn test_trace_future() {
149 let value = async move { 5 }.trace(trace_future_args!(c"category", c"name")).await;
150 assert_eq!(value, 5);
151
152 let value =
153 async move { 5 }.trace(trace_future_args!(c"category", c"name", "arg1" => 6)).await;
154 assert_eq!(value, 5);
155
156 let trace_only_var = 7;
157 let value = async move { 5 }
158 .trace(trace_future_args!(c"category", c"name", "arg1" => 6, "ar2" => trace_only_var))
159 .await;
160 assert_eq!(value, 5);
161 }
162
163 #[fuchsia::test]
164 fn test_arg_types() {
165 duration!(c"category", c"name", "bool" => true);
166 duration!(c"category", c"name", "i32" => 5i32, "u32" => 5u32);
167 duration!(c"category", c"name", "i64" => 5i64, "u64" => 5u64);
168 duration!(c"category", c"name", "isize" => 5isize, "usize" => 5usize);
169 duration!(c"category", c"name", "f64" => 5f64);
170
171 let owned_str = "test-str".to_owned();
172 duration!(c"category", c"name", "str" => owned_str.as_str());
173
174 let mut value = 5u64;
175 duration!(c"category", c"name", "const-ptr" => &value as *const u64);
176 duration!(c"category", c"name", "mut-ptr" => &mut value as *mut u64);
177 }
178}