Skip to main content

tracing_tracy/
config.rs

1use client::Client;
2use tracing_subscriber::fmt::format::DefaultFields;
3use tracing_subscriber::fmt::FormatFields;
4
5/// Configuration of the [`TracyLayer`](super::TracyLayer) behaviour.
6///
7/// For most users [`DefaultConfig`] is going to be a good default choice, however advanced users
8/// can implement this trait manually to override the formatter used or to otherwise modify the
9/// behaviour of the `TracyLayer`.
10///
11/// # Examples
12///
13/// ```
14/// use tracing_subscriber::fmt::format::DefaultFields;
15///
16/// struct TracyLayerConfig {
17///     fmt: DefaultFields,
18/// }
19/// impl tracing_tracy::Config for TracyLayerConfig {
20///     type Formatter = DefaultFields;
21///     fn formatter(&self) -> &Self::Formatter {
22///         &self.fmt
23///     }
24///     // The boilerplate ends here
25///
26///     /// Collect 32 frames in stack traces.
27///     fn stack_depth(&self, _: &tracing::Metadata) -> u16 {
28///         32
29///     }
30///
31///     /// Do not format fields into zone names.
32///     fn format_fields_in_zone_name(&self) -> bool {
33///         false
34///     }
35///
36///     // etc.
37/// }
38/// ```
39///
40/// With this configuration `TracyLayer` will collect some call stacks and the formatting of the
41/// zone names is different from the `DefaultConfig`.
42pub trait Config {
43    type Formatter: for<'writer> FormatFields<'writer> + 'static;
44
45    /// Use a custom field formatting implementation.
46    fn formatter(&self) -> &Self::Formatter;
47
48    /// Specify the maximum number of stack frames that will be collected.
49    ///
50    /// Note that enabling callstack collection can and will introduce a non-trivial overhead at
51    /// every instrumentation point. Specifying 0 frames will disable stack trace collection.
52    ///
53    /// Default implementation returns `0`.
54    fn stack_depth(&self, metadata: &tracing_core::Metadata<'_>) -> u16 {
55        let _ = metadata;
56        0
57    }
58
59    /// Specify whether or not to include tracing span fields in the tracy zone name, or to emit
60    /// them as zone text.
61    ///
62    /// The former enables zone analysis along unique span field invocations, while the latter
63    /// aggregates every invocation of a given span into a single zone, irrespective of field
64    /// values.
65    ///
66    /// Default implementation returns `true`.
67    fn format_fields_in_zone_name(&self) -> bool {
68        true
69    }
70
71    /// Apply handling for errors detected by the [`TracyLayer`](super::TracyLayer).
72    ///
73    /// Fundamentally the way the tracing crate and the Tracy profiler work are somewhat
74    /// incompatible in certain ways. For instance, a `tracing::Span` can be created on one
75    /// thread and moved to another, where it is cleaned up. Tracy on the other hand expects that
76    /// its eqvivalent concept of zone remains entirely within a thread.
77    ///
78    /// Another example a limitation in `Tracy` where the message length or zone name cannot exceed
79    /// a certain (low) limit of bytes.
80    ///
81    /// Although `tracing_tracy` does it best to paper over these sorts of differences, it can’t
82    /// always make them invisible. In certain cases detecting these sorts of issues is
83    /// straightforward, and it is when `tracing_tracy` will invoke this method to enable users to
84    /// report the issues in whatever way they wish to.
85    ///
86    /// By default a message coloured in red is emitted to the tracy client.
87    fn on_error(&self, client: &Client, error: &'static str) {
88        client.color_message(error, 0xFF000000, 0);
89    }
90}
91
92/// A default configuration of the [`TracyLayer`](super::TracyLayer).
93///
94/// This type does not allow for any adjustment of the configuration. In order to customize
95/// the behaviour of the layer implement the [`Config`] trait for your own type.
96#[derive(Default)]
97pub struct DefaultConfig(DefaultFields);
98
99impl Config for DefaultConfig {
100    type Formatter = DefaultFields;
101    fn formatter(&self) -> &Self::Formatter {
102        &self.0
103    }
104}