History

Merge pull request #2401 from GitoxideLabs/improvements

Sebastian Thiel committed 9 months ago

Commit ea9e2b92 parents e8612b5 7166aaf4 files · +42 −330Browse files

Unified · Split

4 files
  1. Cargo.lock +3 −3
  2. gix-trace/Cargo.toml +3 −3
  3. gix-trace/src/enabled.rs +34 −318
  4. gix-trace/src/lib.rs +2 −6
Cargo.lock+3−3
@@ -2456,7 +2456,7 @@ name = "gix-trace" · 2455 unmodified lines
2456version = "0.1.17"2456version = "0.1.17"
2457dependencies = [2457dependencies = [
2458 "document-features",2458 "document-features",
2459 "tracing-core",2459 "tracing",
2460]2460]
2461 2461
2462[[package]]2462[[package]]
@@ -5125,9 +5125,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" · 2662 unmodified lines
5125 5125
5126[[package]]5126[[package]]
5127name = "tracing"5127name = "tracing"
5128version = "0.1.43"5128version = "0.1.44"
5129source = "registry+https://github.com/rust-lang/crates.io-index"5129source = "registry+https://github.com/rust-lang/crates.io-index"
5130checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"5130checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
5131dependencies = [5131dependencies = [
5132 "pin-project-lite",5132 "pin-project-lite",
5133 "tracing-attributes",5133 "tracing-attributes",
gix-trace/Cargo.toml+3−3
@@ -20,18 +20,18 @@ test = false · 19 unmodified lines
20## Note that there is no default feature, as the application is supposed to opt-in via `gix-features` or using this crate directly.20## Note that there is no default feature, as the application is supposed to opt-in via `gix-features` or using this crate directly.
21default = []21default = []
22 22
23## Implement `tracing` with `tracing-core`, which provides applications with valuable performance details if they opt-in to it.23## Implement `tracing` with the `tracing` crate, which provides applications with valuable performance details if they opt-in to it.
24##24##
25## Note that this may have overhead as well, thus instrumentations should be used stategically, only providing coarse tracing by default and adding details25## Note that this may have overhead as well, thus instrumentations should be used stategically, only providing coarse tracing by default and adding details
26## only where needed while marking them with the appropriate level.26## only where needed while marking them with the appropriate level.
27tracing = ["dep:tracing-core"]27tracing = ["dep:tracing"]
28 28
29## If enabled, detailed tracing is also emitted, which can greatly increase insights but at a cost.29## If enabled, detailed tracing is also emitted, which can greatly increase insights but at a cost.
30tracing-detail = []30tracing-detail = []
31 31
32 32
33[dependencies]33[dependencies]
34tracing-core = { version = "0.1.36", optional = true }34tracing = { version = "0.1.44", optional = true, default-features = false, features = ["std"] }
35 35
36document-features = { version = "0.2.0", optional = true }36document-features = { version = "0.2.0", optional = true }
37 37
gix-trace/src/enabled.rs+34−318
@@ -1,34 +1,31 @@
1use tracing_core::{dispatcher::get_default as with_dispatcher, span, span::Id, Dispatch};1pub use tracing::field;
2// these are used later in macros.2
3pub use tracing_core::{field, metadata, Event, Metadata};3#[doc(hidden)]
4pub use tracing as __tracing;
4 5
5/// An entered span which will exit on drop.6/// An entered span which will exit on drop.
6#[derive(Clone)]
7pub struct Span {7pub struct Span {
8 id: Option<(Id, Dispatch, &'static Metadata<'static>)>,8 inner: Option<tracing::span::EnteredSpan>,
9}9}
10 10
11impl Span {11impl Clone for Span {
12 /// Create a new span.12 fn clone(&self) -> Self {
13 ///13 Self {
14 /// This constructor is typically invoked by the [`crate::span!`] macro.14 inner: self.inner.as_ref().map(|s| tracing::Span::clone(s).entered()),
15 pub fn new(
16 level: crate::Level,
17 meta: &'static Metadata<'static>,
18 values: &tracing_core::field::ValueSet<'_>,
19 ) -> Self {
20 if level > crate::MAX_LEVEL {
21 Self { id: None }
22 } else {
23 with_dispatcher(|dispatch| {
24 let id = dispatch.new_span(&tracing_core::span::Attributes::new(meta, values));
25 dispatch.enter(&id);
26 Self {
27 id: Some((id, dispatch.clone(), meta)),
28 }
29 })
30 }15 }
31 }16 }
17}
18
19impl Span {
20 /// Create a disabled span.
21 pub fn disabled() -> Self {
22 Self { inner: None }
23 }
24
25 /// Wrap an entered span from the `tracing` crate.
26 pub fn from_entered(span: tracing::span::EnteredSpan) -> Self {
27 Self { inner: Some(span) }
28 }
32 29
33 /// Record a single `field` to take `value`.30 /// Record a single `field` to take `value`.
34 ///31 ///
@@ -39,51 +36,19 @@ impl Span { · 4 unmodified lines
39 where36 where
40 V: field::Value,37 V: field::Value,
41 {38 {
42 if let Some((_, _, meta)) = &self.id {39 if let Some(inner) = &self.inner {
43 let fields = meta.fields();40 inner.record(field, value);
44 let field = fields
45 .field(field)
46 .unwrap_or_else(|| panic!("Field name '{field}' must be registered at creation time."));
47 self.record_all(&fields.value_set(&[(&field, Some(&value as &dyn field::Value))]));
48 }
49 self
50 }
51
52 fn record_all(&self, values: &field::ValueSet<'_>) -> &Self {
53 if let Some((id, dispatch, _)) = &self.id {
54 let record = span::Record::new(values);
55 dispatch.record(id, &record);
56 }41 }
57 self42 self
58 }43 }
59}44}
60 45
61impl Drop for Span {
62 fn drop(&mut self) {
63 if let Some((id, dispatch, _meta)) = self.id.take() {
64 dispatch.exit(&id);
65 dispatch.try_close(id);
66 }
67 }
68}
69
70#[doc(hidden)]
71pub struct MetaOnlyCallsite(pub &'static Metadata<'static>);
72
73impl tracing_core::callsite::Callsite for MetaOnlyCallsite {
74 fn set_interest(&self, _: tracing_core::subscriber::Interest) {}
75
76 fn metadata(&self) -> &Metadata<'_> {
77 self.0
78 }
79}
80
81#[doc(hidden)]46#[doc(hidden)]
82impl crate::Level {47impl crate::Level {
83 pub const fn into_tracing_level(self) -> tracing_core::Level {48 pub const fn into_tracing_level(self) -> tracing::Level {
84 match self {49 match self {
85 crate::Level::Coarse => tracing_core::Level::INFO,50 crate::Level::Coarse => tracing::Level::INFO,
86 crate::Level::Detail => tracing_core::Level::DEBUG,51 crate::Level::Detail => tracing::Level::DEBUG,
87 }52 }
88 }53 }
89}54}
@@ -91,26 +56,15 @@ impl crate::Level { · 1 unmodified line
91/// A macro to create a span.56/// A macro to create a span.
92#[macro_export]57#[macro_export]
93macro_rules! span {58macro_rules! span {
94 (target: $target:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {59 (target: $target:expr, $lvl:expr, $name:expr, $($fields:tt)*) => {{
95 {60 if $lvl > $crate::MAX_LEVEL {
96 static META: $crate::Metadata<'static> = {61 $crate::Span::disabled()
97 $crate::metadata! {62 } else {
98 name: $name,63 $crate::Span::from_entered(
99 target: $target,64 $crate::__tracing::span!(target: $target, $lvl.into_tracing_level(), $name, $($fields)*).entered()
100 level: $lvl.into_tracing_level(),
101 fields: $crate::fieldset!( $($fields)* ),
102 callsite: &$crate::MetaOnlyCallsite(&META),
103 kind: $crate::metadata::Kind::SPAN,
104 }
105 };
106
107 $crate::Span::new(
108 $lvl,
109 &META,
110 &$crate::valueset!(META.fields(), $($fields)*),
111 )65 )
112 }66 }
113 };67 }};
114 (target: $target:expr, $lvl:expr, $name:expr) => {68 (target: $target:expr, $lvl:expr, $name:expr) => {
115 $crate::span!(target: $target, $lvl, $name,)69 $crate::span!(target: $target, $lvl, $name,)
116 };70 };
@@ -135,27 +89,7 @@ macro_rules! span { · 18 unmodified lines
135#[macro_export]89#[macro_export]
136macro_rules! event {90macro_rules! event {
137 (target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> (91 (target: $target:expr, $lvl:expr, { $($fields:tt)* } )=> (
138 {92 $crate::__tracing::event!(target: $target, $lvl, $($fields)*)
139 static META: $crate::Metadata<'static> = {
140 $crate::metadata! {
141 name: concat!(
142 "event ",
143 file!(),
144 ":",
145 line!()
146 ),
147 target: $target,
148 level: $lvl,
149 fields: $crate::fieldset!( $($fields)* ),
150 callsite: &$crate::MetaOnlyCallsite(&META),
151 kind: $crate::metadata::Kind::EVENT,
152 }
153 };
154 $crate::Event::dispatch(
155 &META,
156 &$crate::valueset!(META.fields(), $($fields)*)
157 );
158 }
159 );93 );
160 (target: $target:expr, $lvl:expr, { $($fields:tt)* }, $($arg:tt)+ ) => (94 (target: $target:expr, $lvl:expr, { $($fields:tt)* }, $($arg:tt)+ ) => (
161 $crate::event!(95 $crate::event!(
@@ -218,221 +152,3 @@ macro_rules! event { · 56 unmodified lines
218 $crate::event!(target: module_path!(), $lvl, { $($arg)+ })152 $crate::event!(target: module_path!(), $lvl, { $($arg)+ })
219 );153 );
220}154}
221
222// Copied from`tracing`, would be nice to have it in `tracing-core`.
223#[doc(hidden)]
224#[macro_export]
225macro_rules! fieldset {
226 // == base case ==
227 (@ { $(,)* $($out:expr),* $(,)* } $(,)*) => {
228 &[ $($out),* ]
229 };
230
231 // == recursive cases (more tts) ==
232 (@ { $(,)* $($out:expr),* } $($k:ident).+ = ?$val:expr, $($rest:tt)*) => {
233 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
234 };
235 (@ { $(,)* $($out:expr),* } $($k:ident).+ = %$val:expr, $($rest:tt)*) => {
236 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
237 };
238 (@ { $(,)* $($out:expr),* } $($k:ident).+ = $val:expr, $($rest:tt)*) => {
239 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
240 };
241 // TODO(#1138): determine a new syntax for uninitialized span fields, and
242 // re-enable this.
243 // (@ { $($out:expr),* } $($k:ident).+ = _, $($rest:tt)*) => {
244 // $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
245 // };
246 (@ { $(,)* $($out:expr),* } ?$($k:ident).+, $($rest:tt)*) => {
247 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
248 };
249 (@ { $(,)* $($out:expr),* } %$($k:ident).+, $($rest:tt)*) => {
250 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
251 };
252 (@ { $(,)* $($out:expr),* } $($k:ident).+, $($rest:tt)*) => {
253 $crate::fieldset!(@ { $($out),*, stringify!($($k).+) } $($rest)*)
254 };
255
256 // Handle literal names
257 (@ { $(,)* $($out:expr),* } $k:literal = ?$val:expr, $($rest:tt)*) => {
258 $crate::fieldset!(@ { $($out),*, $k } $($rest)*)
259 };
260 (@ { $(,)* $($out:expr),* } $k:literal = %$val:expr, $($rest:tt)*) => {
261 $crate::fieldset!(@ { $($out),*, $k } $($rest)*)
262 };
263 (@ { $(,)* $($out:expr),* } $k:literal = $val:expr, $($rest:tt)*) => {
264 $crate::fieldset!(@ { $($out),*, $k } $($rest)*)
265 };
266
267 // Remainder is unparsable, but exists --- must be format args!
268 (@ { $(,)* $($out:expr),* } $($rest:tt)+) => {
269 $crate::fieldset!(@ { "message", $($out),*, })
270 };
271
272 // == entry ==
273 ($($args:tt)*) => {
274 $crate::fieldset!(@ { } $($args)*,)
275 };
276}
277
278// Copied from`tracing`, would be nice to have it in `tracing-core`.
279#[doc(hidden)]
280#[macro_export]
281macro_rules! valueset {
282
283 // === base case ===
284 (@ { $(,)* $($val:expr),* $(,)* }, $next:expr $(,)*) => {
285 &[ $($val),* ]
286 };
287
288 // === recursive case (more tts) ===
289
290 // TODO(#1138): determine a new syntax for uninitialized span fields, and
291 // re-enable this.
292 // (@{ $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = _, $($rest:tt)*) => {
293 // $crate::valueset!(@ { $($out),*, (&$next, None) }, $next, $($rest)*)
294 // };
295 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = ?$val:expr, $($rest:tt)*) => {
296 $crate::valueset!(
297 @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
298 $next,
299 $($rest)*
300 )
301 };
302 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = %$val:expr, $($rest:tt)*) => {
303 $crate::valueset!(
304 @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
305 $next,
306 $($rest)*
307 )
308 };
309 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = $val:expr, $($rest:tt)*) => {
310 $crate::valueset!(
311 @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
312 $next,
313 $($rest)*
314 )
315 };
316 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+, $($rest:tt)*) => {
317 $crate::valueset!(
318 @ { $($out),*, (&$next, Some(&$($k).+ as &dyn Value)) },
319 $next,
320 $($rest)*
321 )
322 };
323 (@ { $(,)* $($out:expr),* }, $next:expr, ?$($k:ident).+, $($rest:tt)*) => {
324 $crate::valueset!(
325 @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &dyn Value)) },
326 $next,
327 $($rest)*
328 )
329 };
330 (@ { $(,)* $($out:expr),* }, $next:expr, %$($k:ident).+, $($rest:tt)*) => {
331 $crate::valueset!(
332 @ { $($out),*, (&$next, Some(&display(&$($k).+) as &dyn Value)) },
333 $next,
334 $($rest)*
335 )
336 };
337 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = ?$val:expr) => {
338 $crate::valueset!(
339 @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
340 $next,
341 )
342 };
343 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = %$val:expr) => {
344 $crate::valueset!(
345 @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
346 $next,
347 )
348 };
349 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+ = $val:expr) => {
350 $crate::valueset!(
351 @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
352 $next,
353 )
354 };
355 (@ { $(,)* $($out:expr),* }, $next:expr, $($k:ident).+) => {
356 $crate::valueset!(
357 @ { $($out),*, (&$next, Some(&$($k).+ as &dyn Value)) },
358 $next,
359 )
360 };
361 (@ { $(,)* $($out:expr),* }, $next:expr, ?$($k:ident).+) => {
362 $crate::valueset!(
363 @ { $($out),*, (&$next, Some(&debug(&$($k).+) as &dyn Value)) },
364 $next,
365 )
366 };
367 (@ { $(,)* $($out:expr),* }, $next:expr, %$($k:ident).+) => {
368 $crate::valueset!(
369 @ { $($out),*, (&$next, Some(&display(&$($k).+) as &dyn Value)) },
370 $next,
371 )
372 };
373
374 // Handle literal names
375 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr, $($rest:tt)*) => {
376 $crate::valueset!(
377 @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
378 $next,
379 $($rest)*
380 )
381 };
382 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr, $($rest:tt)*) => {
383 $crate::valueset!(
384 @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
385 $next,
386 $($rest)*
387 )
388 };
389 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr, $($rest:tt)*) => {
390 $crate::valueset!(
391 @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
392 $next,
393 $($rest)*
394 )
395 };
396 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr) => {
397 $crate::valueset!(
398 @ { $($out),*, (&$next, Some(&debug(&$val) as &dyn Value)) },
399 $next,
400 )
401 };
402 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr) => {
403 $crate::valueset!(
404 @ { $($out),*, (&$next, Some(&display(&$val) as &dyn Value)) },
405 $next,
406 )
407 };
408 (@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr) => {
409 $crate::valueset!(
410 @ { $($out),*, (&$next, Some(&$val as &dyn Value)) },
411 $next,
412 )
413 };
414
415 // Remainder is unparsable, but exists --- must be format args!
416 (@ { $(,)* $($out:expr),* }, $next:expr, $($rest:tt)+) => {
417 $crate::valueset!(@ { (&$next, Some(&format_args!($($rest)+) as &dyn Value)), $($out),* }, $next, )
418 };
419
420 // === entry ===
421 ($fields:expr, $($kvs:tt)+) => {
422 {
423 #[allow(unused_imports)]
424 use $crate::field::{debug, display, Value};
425 let mut iter = $fields.iter();
426 $fields.value_set($crate::valueset!(
427 @ { },
428 iter.next().expect("FieldSet corrupted (this is a bug)"),
429 $($kvs)+
430 ))
431 }
432 };
433 ($fields:expr,) => {
434 {
435 $fields.value_set(&[])
436 }
437 };
438}
gix-trace/src/lib.rs+2−6
@@ -35,7 +35,7 @@ pub const MAX_LEVEL: Level = Level::Coarse; · 34 unmodified lines
35mod enabled;35mod enabled;
36 36
37#[cfg(feature = "tracing")]37#[cfg(feature = "tracing")]
38pub use enabled::{field, Span};38pub use enabled::{__tracing, field, Span};
39 39
40impl Span {40impl Span {
41 /// Execute `f` in with this span active, consuming it.41 /// Execute `f` in with this span active, consuming it.
@@ -44,10 +44,6 @@ impl Span { · 2 unmodified lines
44 }44 }
45}45}
46 46
47#[cfg(feature = "tracing")]
48#[doc(hidden)]
49pub use enabled::{metadata, Event, MetaOnlyCallsite, Metadata};
50
51#[cfg(not(feature = "tracing"))]47#[cfg(not(feature = "tracing"))]
52mod disabled;48mod disabled;
53#[cfg(not(feature = "tracing"))]49#[cfg(not(feature = "tracing"))]
@@ -56,7 +52,7 @@ pub use disabled::Span; · 2 unmodified lines
56///52///
57pub mod event {53pub mod event {
58 #[cfg(feature = "tracing")]54 #[cfg(feature = "tracing")]
59 pub use tracing_core::Level;55 pub use tracing::Level;
60 56
61 /// All available tracing levels for use in `event!()` macro.57 /// All available tracing levels for use in `event!()` macro.
62 #[cfg(not(feature = "tracing"))]58 #[cfg(not(feature = "tracing"))]