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}