console_subscriber/
builder.rs

1use super::{ConsoleLayer, Server};
2#[cfg(unix)]
3use std::path::Path;
4use std::{
5    net::{IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
6    path::PathBuf,
7    thread,
8    time::Duration,
9};
10use tokio::runtime;
11use tracing::Subscriber;
12use tracing_subscriber::{
13    filter::{self, FilterFn},
14    layer::{Layer, SubscriberExt},
15    prelude::*,
16    registry::LookupSpan,
17};
18
19/// Builder for configuring [`ConsoleLayer`]s.
20#[derive(Clone, Debug)]
21pub struct Builder {
22    /// The maximum capacity for the channel of events from the subscriber to
23    /// the aggregator task.
24    pub(super) event_buffer_capacity: usize,
25
26    /// The maximum number of updates to buffer per-client before the client is
27    /// dropped.
28    pub(super) client_buffer_capacity: usize,
29
30    /// The interval between publishing updates to clients.
31    pub(crate) publish_interval: Duration,
32
33    /// How long to retain data for completed events.
34    pub(crate) retention: Duration,
35
36    /// The address on which to serve the RPC server.
37    pub(super) server_addr: ServerAddr,
38
39    /// If and where to save a recording of the events.
40    pub(super) recording_path: Option<PathBuf>,
41
42    /// The filter environment variable to use for `tracing` events.
43    pub(super) filter_env_var: String,
44
45    /// Whether to trace events coming from the subscriber thread
46    self_trace: bool,
47
48    /// The maximum value for the task poll duration histogram.
49    ///
50    /// Any polls exceeding this duration will be clamped to this value. Higher
51    /// values will result in more memory usage.
52    pub(super) poll_duration_max: Duration,
53
54    /// The maximum value for the task scheduled duration histogram.
55    ///
56    /// Any scheduled times exceeding this duration will be clamped to this
57    /// value. Higher values will result in more memory usage.
58    pub(super) scheduled_duration_max: Duration,
59
60    /// Whether to enable the grpc-web support.
61    #[cfg(feature = "grpc-web")]
62    enable_grpc_web: bool,
63}
64
65impl Default for Builder {
66    fn default() -> Self {
67        Self {
68            event_buffer_capacity: ConsoleLayer::DEFAULT_EVENT_BUFFER_CAPACITY,
69            client_buffer_capacity: ConsoleLayer::DEFAULT_CLIENT_BUFFER_CAPACITY,
70            publish_interval: ConsoleLayer::DEFAULT_PUBLISH_INTERVAL,
71            retention: ConsoleLayer::DEFAULT_RETENTION,
72            poll_duration_max: ConsoleLayer::DEFAULT_POLL_DURATION_MAX,
73            scheduled_duration_max: ConsoleLayer::DEFAULT_SCHEDULED_DURATION_MAX,
74            server_addr: ServerAddr::Tcp(SocketAddr::new(Server::DEFAULT_IP, Server::DEFAULT_PORT)),
75            recording_path: None,
76            filter_env_var: "RUST_LOG".to_string(),
77            self_trace: false,
78            #[cfg(feature = "grpc-web")]
79            enable_grpc_web: false,
80        }
81    }
82}
83
84impl Builder {
85    /// Sets the maximum capacity for the channel of events sent from subscriber
86    /// layers to the aggregator task.
87    ///
88    /// When this channel is at capacity, additional events will be dropped.
89    ///
90    /// By default, this is [`ConsoleLayer::DEFAULT_EVENT_BUFFER_CAPACITY`].
91    pub fn event_buffer_capacity(self, event_buffer_capacity: usize) -> Self {
92        Self {
93            event_buffer_capacity,
94            ..self
95        }
96    }
97
98    /// Sets the maximum capacity of updates to buffer for each subscribed
99    /// client, if that client is not reading from the RPC stream.
100    ///
101    /// When this channel is at capacity, the client may be disconnected.
102    ///
103    /// By default, this is [`ConsoleLayer::DEFAULT_CLIENT_BUFFER_CAPACITY`].
104    pub fn client_buffer_capacity(self, client_buffer_capacity: usize) -> Self {
105        Self {
106            client_buffer_capacity,
107            ..self
108        }
109    }
110
111    /// Sets how frequently updates are published to clients.
112    ///
113    /// A shorter duration will allow clients to update more frequently, but may
114    /// result in the program spending more time preparing task data updates.
115    ///
116    /// By default, this is [`ConsoleLayer::DEFAULT_PUBLISH_INTERVAL`].
117    /// Methods like [`init`][`crate::init`] and [`spawn`][`crate::spawn`] will
118    /// take the value from the `TOKIO_CONSOLE_PUBLISH_INTERVAL` [environment
119    /// variable] before falling back on that default.
120    ///
121    /// [environment variable]: `Builder::with_default_env`
122    pub fn publish_interval(self, publish_interval: Duration) -> Self {
123        Self {
124            publish_interval,
125            ..self
126        }
127    }
128
129    /// Sets how long data is retained for completed tasks.
130    ///
131    /// A longer duration will allow more historical data to be replayed by
132    /// clients, but will result in increased memory usage. A shorter duration
133    /// will reduce memory usage, but less historical data from completed tasks
134    /// will be retained.
135    ///
136    /// By default, this is [`ConsoleLayer::DEFAULT_RETENTION`]. Methods
137    /// like [`init`][`crate::init`] and [`spawn`][`crate::spawn`] will take the
138    /// value from the `TOKIO_CONSOLE_RETENTION` [environment variable] before
139    /// falling back on that default.
140    ///
141    /// [environment variable]: `Builder::with_default_env`
142    pub fn retention(self, retention: Duration) -> Self {
143        Self { retention, ..self }
144    }
145
146    /// Sets the socket address on which to serve the RPC server.
147    ///
148    /// By default, the server is bound on the IP address [`Server::DEFAULT_IP`]
149    /// on port [`Server::DEFAULT_PORT`]. Methods like
150    /// [`init`][`crate::init`] and [`spawn`][`crate::spawn`] will parse the
151    /// socket address from the `TOKIO_CONSOLE_BIND` [environment variable]
152    /// before falling back on constructing a socket address from those
153    /// defaults.
154    ///
155    /// The socket address can be either a TCP socket address, a
156    /// [Unix domain socket] (UDS) address, or a [Vsock] address.
157    /// Unix domain sockets are only supported on Unix-compatible operating systems,
158    /// such as Linux, BSDs, and macOS. Vsock addresses are only available when the
159    /// "vsock" feature is enabled and are supported on platforms with vsock capability.
160    ///
161    /// Each call to this method will overwrite the previously set value.
162    ///
163    /// # Examples
164    ///
165    /// Connect to the TCP address `localhost:1234`:
166    ///
167    /// ```
168    /// # use console_subscriber::Builder;
169    /// use std::net::Ipv4Addr;
170    /// let builder = Builder::default().server_addr((Ipv4Addr::LOCALHOST, 1234));
171    /// ```
172    ///
173    /// Connect to the UDS address `/tmp/tokio-console`:
174    ///
175    /// ```
176    /// # use console_subscriber::Builder;
177    /// # #[cfg(unix)]
178    /// use std::path::Path;
179    ///
180    /// // Unix domain sockets are only available on Unix-compatible operating systems.
181    /// #[cfg(unix)]
182    /// let builder = Builder::default().server_addr(Path::new("/tmp/tokio-console"));
183    /// ```
184    ///
185    /// Connect using a vsock connection (requires the "vsock" feature):
186    ///
187    /// ```
188    /// # use console_subscriber::Builder;
189    /// # #[cfg(feature = "vsock")]
190    /// let builder = Builder::default().server_addr(tokio_vsock::VsockAddr::new(tokio_vsock::VMADDR_CID_ANY, 6669));
191    /// ```
192    ///
193    /// [environment variable]: `Builder::with_default_env`
194    /// [Unix domain socket]: https://en.wikipedia.org/wiki/Unix_domain_socket
195    /// [Vsock]: https://docs.rs/tokio-vsock/latest/tokio_vsock/
196    pub fn server_addr(self, server_addr: impl Into<ServerAddr>) -> Self {
197        Self {
198            server_addr: server_addr.into(),
199            ..self
200        }
201    }
202
203    /// Sets the path to record the events to the file system.
204    ///
205    /// By default, this is initially `None`. Methods like
206    /// [`init`][`crate::init`] and [`spawn`][`crate::spawn`] will take the
207    /// value from the `TOKIO_CONSOLE_RECORD_PATH` [environment variable] before
208    /// falling back on that default.
209    ///
210    /// [environment variable]: `Builder::with_default_env`
211    pub fn recording_path(self, path: impl Into<PathBuf>) -> Self {
212        Self {
213            recording_path: Some(path.into()),
214            ..self
215        }
216    }
217
218    /// Sets the environment variable used to configure which `tracing` events
219    /// are logged to stdout.
220    ///
221    /// The [`Builder::init`] method configures the default `tracing`
222    /// subscriber. In addition to a [`ConsoleLayer`], the subscriber
223    /// constructed by `init` includes a [`fmt::Layer`] for logging events to
224    /// stdout. What `tracing` events that layer will log is determined by the
225    /// value of an environment variable; this method configures which
226    /// environment variable is read to determine the log filter.
227    ///
228    /// This environment variable does not effect what spans and events are
229    /// recorded by the [`ConsoleLayer`]. Therefore, this method will have no
230    /// effect if the builder is used with [`Builder::spawn`] or
231    /// [`Builder::build`].
232    ///
233    /// The default environment variable is `RUST_LOG`. See [here] for details
234    /// on the syntax for configuring the filter.
235    ///
236    /// [`fmt::Layer`]: https://docs.rs/tracing-subscriber/0.3/tracing_subscriber/fmt/index.html
237    /// [here]: https://docs.rs/tracing-subscriber/0.3/tracing_subscriber/filter/targets/struct.Targets.html
238    pub fn filter_env_var(self, filter_env_var: impl Into<String>) -> Self {
239        Self {
240            filter_env_var: filter_env_var.into(),
241            ..self
242        }
243    }
244
245    /// Sets the maximum value for task poll duration histograms.
246    ///
247    /// Any poll durations exceeding this value will be clamped down to this
248    /// duration and recorded as an outlier.
249    ///
250    /// By default, this is [one second]. Higher values will increase per-task
251    /// memory usage.
252    ///
253    /// [one second]: ConsoleLayer::DEFAULT_POLL_DURATION_MAX
254    pub fn poll_duration_histogram_max(self, max: Duration) -> Self {
255        Self {
256            poll_duration_max: max,
257            ..self
258        }
259    }
260
261    /// Sets the maximum value for task scheduled duration histograms.
262    ///
263    /// Any scheduled duration (the time from a task being woken until it is next
264    /// polled) exceeding this value will be clamped down to this duration
265    /// and recorded as an outlier.
266    ///
267    /// By default, this is [one second]. Higher values will increase per-task
268    /// memory usage.
269    ///
270    /// [one second]: ConsoleLayer::DEFAULT_SCHEDULED_DURATION_MAX
271    pub fn scheduled_duration_histogram_max(self, max: Duration) -> Self {
272        Self {
273            scheduled_duration_max: max,
274            ..self
275        }
276    }
277
278    /// Sets whether tasks, resources, and async ops from the console
279    /// subscriber thread are recorded.
280    ///
281    /// By default, events from the console subscriber are discarded and
282    /// not exported to clients.
283    pub fn enable_self_trace(self, self_trace: bool) -> Self {
284        Self { self_trace, ..self }
285    }
286
287    /// Sets whether to enable the grpc-web support.
288    ///
289    /// By default, this is `false`. If enabled, the console subscriber will
290    /// serve the gRPC-Web protocol in addition to the standard gRPC protocol.
291    /// This is useful for serving the console subscriber to web clients.
292    /// Please be aware that the current default server port is set to 6669.
293    /// However, certain browsers may restrict this port due to security reasons.
294    /// If you encounter issues with this, consider changing the port to an
295    /// alternative one that is not commonly blocked by browsers.
296    ///
297    /// [`serve_with_grpc_web`] is used to provide more advanced configuration
298    /// for the gRPC-Web server.
299    ///
300    /// [`serve_with_grpc_web`]: crate::Server::serve_with_grpc_web
301    #[cfg(feature = "grpc-web")]
302    pub fn enable_grpc_web(self, enable_grpc_web: bool) -> Self {
303        Self {
304            enable_grpc_web,
305            ..self
306        }
307    }
308
309    /// Completes the builder, returning a [`ConsoleLayer`] and [`Server`] task.
310    pub fn build(self) -> (ConsoleLayer, Server) {
311        ConsoleLayer::build(self)
312    }
313
314    /// Configures this builder from a standard set of environment variables:
315    ///
316    /// | **Environment Variable**         | **Purpose**                                                  | **Default Value** |
317    /// |----------------------------------|--------------------------------------------------------------|-------------------|
318    /// | `TOKIO_CONSOLE_RETENTION`        | The duration of seconds to accumulate completed tracing data | 3600s (1h)        |
319    /// | `TOKIO_CONSOLE_BIND`             | a HOST:PORT description, such as `localhost:1234`            | `127.0.0.1:6669`  |
320    /// | `TOKIO_CONSOLE_PUBLISH_INTERVAL` | The duration to wait between sending updates to the console  | 1000ms (1s)       |
321    /// | `TOKIO_CONSOLE_RECORD_PATH`      | The file path to save a recording                            | None              |
322    pub fn with_default_env(mut self) -> Self {
323        if let Some(retention) = duration_from_env("TOKIO_CONSOLE_RETENTION") {
324            self.retention = retention;
325        }
326
327        if let Ok(bind) = std::env::var("TOKIO_CONSOLE_BIND") {
328            self.server_addr = ServerAddr::Tcp(
329                bind.to_socket_addrs()
330                    .expect(
331                        "TOKIO_CONSOLE_BIND must be formatted as HOST:PORT, such as localhost:4321",
332                    )
333                    .next()
334                    .expect("tokio console could not resolve TOKIO_CONSOLE_BIND"),
335            );
336        }
337
338        if let Some(interval) = duration_from_env("TOKIO_CONSOLE_PUBLISH_INTERVAL") {
339            self.publish_interval = interval;
340        }
341
342        if let Ok(path) = std::env::var("TOKIO_CONSOLE_RECORD_PATH") {
343            self.recording_path = Some(path.into());
344        }
345
346        if let Some(capacity) = usize_from_env("TOKIO_CONSOLE_BUFFER_CAPACITY") {
347            self.event_buffer_capacity = capacity;
348        }
349
350        self
351    }
352
353    /// Initializes the console [tracing `Subscriber`][sub] and starts the console
354    /// subscriber [`Server`] on its own background thread.
355    ///
356    /// This function represents the easiest way to get started using
357    /// tokio-console.
358    ///
359    /// In addition to the [`ConsoleLayer`], which collects instrumentation data
360    /// consumed by the console, the default [`Subscriber`][sub] initialized by this
361    /// function also includes a [`tracing_subscriber::fmt`] layer, which logs
362    /// tracing spans and events to stdout. Which spans and events are logged will
363    /// be determined by an environment variable, which defaults to `RUST_LOG`.
364    /// The [`Builder::filter_env_var`] method can be used to override the
365    /// environment variable used to configure the log filter.
366    ///
367    /// **Note**: this function sets the [default `tracing` subscriber][default]
368    /// for your application. If you need to add additional layers to a subscriber,
369    /// see [`spawn`].
370    ///
371    /// # Panics
372    ///
373    /// * If the subscriber's background thread could not be spawned.
374    /// * If the [default `tracing` subscriber][default] has already been set.
375    ///
376    /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
377    /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
378    /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
379    /// [`Server`]: crate::Server
380    ///
381    /// # Configuration
382    ///
383    /// Tokio console subscriber is configured with sensible defaults for most
384    /// use cases. If you need to tune these parameters, several environmental
385    /// configuration variables are available:
386    ///
387    /// | **Environment Variable**            | **Purpose**                                                               | **Default Value** |
388    /// |-------------------------------------|---------------------------------------------------------------------------|-------------------|
389    /// | `TOKIO_CONSOLE_RETENTION`           | The number of seconds to accumulate completed tracing data                | 3600s (1h)        |
390    /// | `TOKIO_CONSOLE_BIND`                | A HOST:PORT description, such as `localhost:1234`                         | `127.0.0.1:6669`  |
391    /// | `TOKIO_CONSOLE_PUBLISH_INTERVAL`    | The number of milliseconds to wait between sending updates to the console | 1000ms (1s)       |
392    /// | `TOKIO_CONSOLE_RECORD_PATH`         | The file path to save a recording                                         | None              |
393    /// | `RUST_LOG`                          | Configures what events are logged events. See [`Targets`] for details.    | "error"           |
394    ///
395    /// If the "env-filter" crate feature flag is enabled, the `RUST_LOG`
396    /// environment variable will be parsed using the [`EnvFilter`] type from
397    /// `tracing-subscriber`. If the "env-filter" feature is **not** enabled, the
398    /// [`Targets`] filter is used instead. The `EnvFilter` type accepts all the
399    /// same syntax as `Targets`, but with the added ability to filter dynamically
400    /// on span field values. See the documentation for those types for details.
401    ///
402    /// # Further customization
403    ///
404    /// To add additional layers or replace the format layer, replace
405    /// `console_subscriber::Builder::init` with:
406    ///
407    /// ```rust
408    /// use tracing_subscriber::prelude::*;
409    ///
410    /// let console_layer = console_subscriber::ConsoleLayer::builder().spawn();
411    ///
412    /// tracing_subscriber::registry()
413    ///     .with(console_layer)
414    ///     .with(tracing_subscriber::fmt::layer())
415    /// //  .with(..potential additional layer..)
416    ///     .init();
417    /// ```
418    ///
419    /// [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.Targets.html
420    /// [`EnvFilter`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.EnvFilter.html
421    pub fn init(self) {
422        #[cfg(feature = "env-filter")]
423        type Filter = filter::EnvFilter;
424        #[cfg(not(feature = "env-filter"))]
425        type Filter = filter::Targets;
426
427        let fmt_filter = std::env::var(&self.filter_env_var)
428            .ok()
429            .and_then(|log_filter| match log_filter.parse::<Filter>() {
430                Ok(targets) => Some(targets),
431                Err(e) => {
432                    eprintln!(
433                        "failed to parse filter environment variable `{}={:?}`: {}",
434                        &self.filter_env_var, log_filter, e
435                    );
436                    None
437                }
438            })
439            .unwrap_or_else(|| {
440                "error"
441                    .parse::<Filter>()
442                    .expect("`error` filter should always parse successfully")
443            });
444
445        let console_layer = self.spawn();
446
447        tracing_subscriber::registry()
448            .with(console_layer)
449            .with(tracing_subscriber::fmt::layer().with_filter(fmt_filter))
450            .init();
451    }
452
453    /// Returns a new `tracing` [`Layer`] consisting of a [`ConsoleLayer`]
454    /// and a [filter] that enables the spans and events required by the console.
455    ///
456    /// This function spawns the console subscriber's [`Server`] in its own Tokio
457    /// runtime in a background thread.
458    ///
459    /// Unlike [`init`], this function does not set the default subscriber, allowing
460    /// additional [`Layer`]s to be added.
461    ///
462    /// [subscriber]: https://docs.rs/tracing/latest/tracing/subscriber/trait.Subscriber.html
463    /// [filter]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html
464    /// [`Layer`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html
465    /// [`Server`]: crate::Server
466    ///
467    /// # Panics
468    ///
469    /// * If the subscriber's background thread could not be spawned.
470    ///
471    /// # Configuration
472    ///
473    /// `console_subscriber::build` supports all of the environmental
474    /// configuration described at [`console_subscriber::init`].
475    ///
476    /// # Differences from `init`
477    ///
478    /// Unlike [`console_subscriber::init`], this function does *not* add a
479    /// [`tracing_subscriber::fmt`] layer to the configured `Subscriber`. This means
480    /// that this function will not log spans and events based on the value of the
481    /// `RUST_LOG` environment variable. Instead, a user-provided [`fmt::Layer`] can
482    /// be added in order to customize the log format.
483    ///
484    /// You must call [`.init()`] on the final subscriber in order to [set the
485    /// subscriber as the default][default].
486    ///
487    /// # Examples
488    ///
489    /// ```rust
490    /// use tracing_subscriber::prelude::*;
491    ///
492    /// let console_layer = console_subscriber::ConsoleLayer::builder()
493    ///     .with_default_env()
494    ///     .spawn();
495    ///
496    /// tracing_subscriber::registry()
497    ///     .with(console_layer)
498    ///     .with(tracing_subscriber::fmt::layer())
499    /// //  .with(...)
500    ///     .init();
501    /// ```
502    /// [`.init()`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/util/trait.SubscriberInitExt.html
503    /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
504    /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
505    /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
506    /// [`fmt::Layer`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/struct.Layer.html
507    /// [`console_subscriber::init`]: crate::init()
508    #[must_use = "a `Layer` must be added to a `tracing::Subscriber` in order to be used"]
509    pub fn spawn<S>(self) -> impl Layer<S>
510    where
511        S: Subscriber + for<'a> LookupSpan<'a>,
512    {
513        fn console_filter(meta: &tracing::Metadata<'_>) -> bool {
514            // events will have *targets* beginning with "runtime"
515            if meta.is_event() {
516                return meta.target().starts_with("runtime") || meta.target().starts_with("tokio");
517            }
518
519            // spans will have *names* beginning with "runtime". for backwards
520            // compatibility with older Tokio versions, enable anything with the `tokio`
521            // target as well.
522            meta.name().starts_with("runtime.") || meta.target().starts_with("tokio")
523        }
524
525        let self_trace = self.self_trace;
526        #[cfg(feature = "grpc-web")]
527        let enable_grpc_web = self.enable_grpc_web;
528
529        let (layer, server) = self.build();
530        let filter =
531            FilterFn::new(console_filter as for<'r, 's> fn(&'r tracing::Metadata<'s>) -> bool);
532        let layer = layer.with_filter(filter);
533
534        thread::Builder::new()
535            .name("console_subscriber".into())
536            .spawn(move || {
537                let _subscriber_guard;
538                if !self_trace {
539                    _subscriber_guard = tracing::subscriber::set_default(
540                        tracing_core::subscriber::NoSubscriber::default(),
541                    );
542                }
543                let runtime = runtime::Builder::new_current_thread()
544                    .enable_io()
545                    .enable_time()
546                    .build()
547                    .expect("console subscriber runtime initialization failed");
548                runtime.block_on(async move {
549                    #[cfg(feature = "grpc-web")]
550                    if enable_grpc_web {
551                        server
552                            .serve_with_grpc_web(tonic::transport::Server::builder())
553                            .await
554                            .expect("console subscriber server failed");
555                        return;
556                    }
557
558                    server
559                        .serve()
560                        .await
561                        .expect("console subscriber server failed")
562                });
563            })
564            .expect("console subscriber could not spawn thread");
565
566        layer
567    }
568}
569
570/// Specifies the address on which a [`Server`] should listen.
571///
572/// This type is passed as an argument to the [`Builder::server_addr`]
573/// method, and may be either a TCP socket address, or a [Unix domain socket]
574/// (UDS) address. Unix domain sockets are only supported on Unix-compatible
575/// operating systems, such as Linux, BSDs, and macOS.
576///
577/// [`Server`]: crate::Server
578/// [Unix domain socket]: https://en.wikipedia.org/wiki/Unix_domain_socket
579#[derive(Clone, Debug)]
580#[non_exhaustive]
581pub enum ServerAddr {
582    /// A TCP address.
583    Tcp(SocketAddr),
584    /// A Unix socket address.
585    #[cfg(unix)]
586    Unix(PathBuf),
587    /// A vsock address.
588    #[cfg(feature = "vsock")]
589    Vsock(tokio_vsock::VsockAddr),
590}
591
592impl From<SocketAddr> for ServerAddr {
593    fn from(addr: SocketAddr) -> ServerAddr {
594        ServerAddr::Tcp(addr)
595    }
596}
597
598impl From<SocketAddrV4> for ServerAddr {
599    fn from(addr: SocketAddrV4) -> ServerAddr {
600        ServerAddr::Tcp(addr.into())
601    }
602}
603
604impl From<SocketAddrV6> for ServerAddr {
605    fn from(addr: SocketAddrV6) -> ServerAddr {
606        ServerAddr::Tcp(addr.into())
607    }
608}
609
610impl<I> From<(I, u16)> for ServerAddr
611where
612    I: Into<IpAddr>,
613{
614    fn from(pieces: (I, u16)) -> ServerAddr {
615        ServerAddr::Tcp(pieces.into())
616    }
617}
618
619#[cfg(unix)]
620impl From<PathBuf> for ServerAddr {
621    fn from(path: PathBuf) -> ServerAddr {
622        ServerAddr::Unix(path)
623    }
624}
625
626#[cfg(unix)]
627impl<'a> From<&'a Path> for ServerAddr {
628    fn from(path: &'a Path) -> ServerAddr {
629        ServerAddr::Unix(path.to_path_buf())
630    }
631}
632
633#[cfg(feature = "vsock")]
634impl From<tokio_vsock::VsockAddr> for ServerAddr {
635    fn from(addr: tokio_vsock::VsockAddr) -> ServerAddr {
636        ServerAddr::Vsock(addr)
637    }
638}
639
640/// Initializes the console [tracing `Subscriber`][sub] and starts the console
641/// subscriber [`Server`] on its own background thread.
642///
643/// This function represents the easiest way to get started using
644/// tokio-console.
645///
646/// In addition to the [`ConsoleLayer`], which collects instrumentation data
647/// consumed by the console, the default [`Subscriber`][sub] initialized by this
648/// function also includes a [`tracing_subscriber::fmt`] layer, which logs
649/// tracing spans and events to stdout. Which spans and events are logged will
650/// be determined by the `RUST_LOG` environment variable.
651///
652/// **Note**: this function sets the [default `tracing` subscriber][default]
653/// for your application. If you need to add additional layers to a subscriber,
654/// see [`spawn`].
655///
656/// # Panics
657///
658/// * If the subscriber's background thread could not be spawned.
659/// * If the [default `tracing` subscriber][default] has already been set.
660///
661/// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
662/// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
663/// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
664/// [`Server`]: crate::Server
665///
666/// # Configuration
667///
668/// Tokio console subscriber is configured with sensible defaults for most
669/// use cases. If you need to tune these parameters, several environmental
670/// configuration variables are available:
671///
672/// | **Environment Variable**            | **Purpose**                                                               | **Default Value** |
673/// |-------------------------------------|---------------------------------------------------------------------------|-------------------|
674/// | `TOKIO_CONSOLE_RETENTION`           | The number of seconds to accumulate completed tracing data                | 3600s (1h)        |
675/// | `TOKIO_CONSOLE_BIND`                | A HOST:PORT description, such as `localhost:1234`                         | `127.0.0.1:6669`  |
676/// | `TOKIO_CONSOLE_PUBLISH_INTERVAL`    | The number of milliseconds to wait between sending updates to the console | 1000ms (1s)       |
677/// | `TOKIO_CONSOLE_RECORD_PATH`         | The file path to save a recording                                         | None              |
678/// | `RUST_LOG`                          | Configures what events are logged events. See [`Targets`] for details.    | "error"           |
679///
680/// If the "env-filter" crate feature flag is enabled, the `RUST_LOG`
681/// environment variable will be parsed using the [`EnvFilter`] type from
682/// `tracing-subscriber`. If the "env-filter" feature is **not** enabled, the
683/// [`Targets`] filter is used instead. The `EnvFilter` type accepts all the
684/// same syntax as `Targets`, but with the added ability to filter dynamically
685/// on span field values. See the documentation for those types for details.
686///
687/// # Further customization
688///
689/// To add additional layers or replace the format layer, replace
690/// `console_subscriber::init` with:
691///
692/// ```rust
693/// use tracing_subscriber::prelude::*;
694///
695/// let console_layer = console_subscriber::spawn();
696///
697/// tracing_subscriber::registry()
698///     .with(console_layer)
699///     .with(tracing_subscriber::fmt::layer())
700/// //  .with(..potential additional layer..)
701///     .init();
702/// ```
703///
704/// Calling `console_subscriber::init` is equivalent to the following:
705/// ```rust
706/// use console_subscriber::ConsoleLayer;
707///
708/// ConsoleLayer::builder().with_default_env().init();
709/// ```
710///
711/// [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.Targets.html
712/// [`EnvFilter`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.EnvFilter.html
713pub fn init() {
714    ConsoleLayer::builder().with_default_env().init();
715}
716
717/// Returns a new `tracing_subscriber` [`Layer`] configured with a [`ConsoleLayer`]
718/// and a [filter] that enables the spans and events required by the console.
719///
720/// This function spawns the console subscriber's [`Server`] in its own Tokio
721/// runtime in a background thread.
722///
723/// Unlike [`init`], this function does not set the default subscriber, allowing
724/// additional [`Layer`]s to be added.
725///
726/// This function is equivalent to the following:
727/// ```
728/// use console_subscriber::ConsoleLayer;
729///
730/// let layer = ConsoleLayer::builder().with_default_env().spawn();
731/// # use tracing_subscriber::prelude::*;
732/// # tracing_subscriber::registry().with(layer).init(); // to suppress must_use warnings
733/// ```
734/// [filter]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html
735/// [`Layer`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html
736/// [`Server`]: crate::Server
737///
738/// # Panics
739///
740/// * If the subscriber's background thread could not be spawned.
741///
742/// # Configuration
743///
744/// `console_subscriber::build` supports all of the environmental
745/// configuration described at [`console_subscriber::init`].
746///
747/// # Differences from `init`
748///
749/// Unlike [`console_subscriber::init`], this function does *not* add a
750/// [`tracing_subscriber::fmt`] layer to the configured `Layer`. This means
751/// that this function will not log spans and events based on the value of the
752/// `RUST_LOG` environment variable. Instead, a user-provided [`fmt::Layer`] can
753/// be added in order to customize the log format.
754///
755/// You must call [`.init()`] on the final subscriber in order to [set the
756/// subscriber as the default][default].
757///
758/// # Examples
759///
760/// ```rust
761/// use tracing_subscriber::prelude::*;
762/// tracing_subscriber::registry()
763///     .with(console_subscriber::spawn())
764///     .with(tracing_subscriber::fmt::layer())
765/// //  .with(...)
766///     .init();
767/// ```
768/// [`.init()`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/util/trait.SubscriberInitExt.html
769/// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
770/// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
771/// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
772/// [`fmt::Layer`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/struct.Layer.html
773/// [`console_subscriber::init`]: crate::init()
774#[must_use = "a `Layer` must be added to a `tracing::Subscriber`in order to be used"]
775pub fn spawn<S>() -> impl Layer<S>
776where
777    S: Subscriber + for<'a> LookupSpan<'a>,
778{
779    ConsoleLayer::builder().with_default_env().spawn::<S>()
780}
781
782fn duration_from_env(var_name: &str) -> Option<Duration> {
783    let var = std::env::var(var_name).ok()?;
784    match var.parse::<humantime::Duration>() {
785        Ok(dur) => Some(dur.into()),
786        Err(e) => panic!(
787            "failed to parse a duration from `{}={:?}`: {}",
788            var_name, var, e
789        ),
790    }
791}
792
793fn usize_from_env(var_name: &str) -> Option<usize> {
794    let var = std::env::var(var_name).ok()?;
795    match var.parse::<usize>() {
796        Ok(num) => Some(num),
797        Err(e) => panic!(
798            "failed to parse a usize from `{}={:?}`: {}",
799            var_name, var, e
800        ),
801    }
802}