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