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, Scope, 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! instant {
48 ($category:expr, $name:expr, $scope: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::instant(&context, $name, $scope,
54 &[$($crate::__backend::ArgValue::of($key, $val)),*])
55 }
56 }}
57}
58
59#[macro_export]
63macro_rules! flow_begin {
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_begin(&context, $name, ($flow_id).into(),
70 &[$($crate::__backend::ArgValue::of($key, $val)),*])
71 }
72 }}
73}
74
75#[macro_export]
79macro_rules! flow_step {
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_step(&context, $name, ($flow_id).into(),
86 &[$($crate::__backend::ArgValue::of($key, $val)),*])
87 }
88 }}
89}
90
91#[macro_export]
95macro_rules! flow_end {
96 ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {{
97 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
98 if let Some(context) =
99 $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE)
100 {
101 $crate::__backend::flow_end(&context, $name, ($flow_id).into(),
102 &[$($crate::__backend::ArgValue::of($key, $val)),*])
103 }
104 }}
105}
106
107#[macro_export]
111macro_rules! trace_future_args {
112 ($category:expr, $name:expr $(, $key:expr => $val:expr)*) => {{
113 static CACHE: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
114 let context = $crate::__backend::TraceCategoryContext::acquire_cached($category, &CACHE);
115 let args = if context.is_some() {
116 vec![$($crate::__backend::ArgValue::of($key, $val)),*]
117 } else {
118 vec![]
119 };
120 $crate::__backend::trace_future_args(context, $category, $name, args)
121 }}
122}
123
124#[cfg(test)]
125mod tests {
126 use crate::{Scope, TraceFutureExt};
127
128 #[fuchsia::test]
129 fn test_duration() {
130 let trace_only_var = 6;
131 duration!(c"category", c"name");
132 duration!(c"category", c"name", "arg" => 5);
133 duration!(c"category", c"name", "arg" => 5, "arg2" => trace_only_var);
134 }
135
136 #[fuchsia::test]
137 fn test_instant() {
138 let trace_only_var = 6;
139 instant!(c"category", c"name", Scope::Thread);
140 instant!(c"category", c"name", Scope::Thread, "arg" => 5);
141 instant!(c"category", c"name", Scope::Thread, "arg" => 5, "arg2" => trace_only_var);
142 }
143
144 #[fuchsia::test]
145 fn test_flow_begin() {
146 let trace_only_var = 6;
147 let flow_id = 5u64;
148 flow_begin!(c"category", c"name", flow_id);
149 flow_begin!(c"category", c"name", flow_id, "arg" => 5);
150 flow_begin!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
151 }
152
153 #[fuchsia::test]
154 fn test_flow_step() {
155 let trace_only_var = 6;
156 let flow_id = 5u64;
157 flow_step!(c"category", c"name", flow_id);
158 flow_step!(c"category", c"name", flow_id, "arg" => 5);
159 flow_step!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
160 }
161
162 #[fuchsia::test]
163 fn test_flow_end() {
164 let trace_only_var = 6;
165 let flow_id = 5u64;
166 flow_end!(c"category", c"name", flow_id);
167 flow_end!(c"category", c"name", flow_id, "arg" => 5);
168 flow_end!(c"category", c"name", flow_id, "arg" => 5, "arg2" => trace_only_var);
169 }
170
171 #[fuchsia::test]
172 async fn test_trace_future() {
173 let value = async move { 5 }.trace(trace_future_args!(c"category", c"name")).await;
174 assert_eq!(value, 5);
175
176 let value =
177 async move { 5 }.trace(trace_future_args!(c"category", c"name", "arg1" => 6)).await;
178 assert_eq!(value, 5);
179
180 let trace_only_var = 7;
181 let value = async move { 5 }
182 .trace(trace_future_args!(c"category", c"name", "arg1" => 6, "ar2" => trace_only_var))
183 .await;
184 assert_eq!(value, 5);
185 }
186
187 #[fuchsia::test]
188 fn test_arg_types() {
189 duration!(c"category", c"name", "bool" => true);
190 duration!(c"category", c"name", "i32" => 5i32, "u32" => 5u32);
191 duration!(c"category", c"name", "i64" => 5i64, "u64" => 5u64);
192 duration!(c"category", c"name", "isize" => 5isize, "usize" => 5usize);
193 duration!(c"category", c"name", "f64" => 5f64);
194
195 let owned_str = "test-str".to_owned();
196 duration!(c"category", c"name", "str" => owned_str.as_str());
197
198 let mut value = 5u64;
199 duration!(c"category", c"name", "const-ptr" => &value as *const u64);
200 duration!(c"category", c"name", "mut-ptr" => &mut value as *mut u64);
201 }
202}