@@ -2,8 +2,17 @@ use super::{Server, TasksLayer};
2
2
use std:: {
3
3
net:: { SocketAddr , ToSocketAddrs } ,
4
4
path:: PathBuf ,
5
+ thread,
5
6
time:: Duration ,
6
7
} ;
8
+ use tokio:: runtime;
9
+ use tracing:: Subscriber ;
10
+ use tracing_subscriber:: {
11
+ filter:: { FilterFn , LevelFilter , Targets } ,
12
+ layer:: { Layer , SubscriberExt } ,
13
+ prelude:: * ,
14
+ registry:: LookupSpan ,
15
+ } ;
7
16
8
17
/// Builder for configuring [`TasksLayer`]s.
9
18
#[ derive( Clone , Debug ) ]
@@ -149,6 +158,315 @@ impl Builder {
149
158
150
159
self
151
160
}
161
+
162
+ /// Initializes the console [tracing `Subscriber`][sub] and starts the console
163
+ /// subscriber [`Server`] on its own background thread.
164
+ ///
165
+ /// This function represents the easiest way to get started using
166
+ /// tokio-console.
167
+ ///
168
+ /// In addition to the [`TasksLayer`], which collects instrumentation data
169
+ /// consumed by the console, the default [`Subscriber`][sub] initialized by this
170
+ /// function also includes a [`tracing_subscriber::fmt`] layer, which logs
171
+ /// tracing spans and events to stdout. Which spans and events are logged will
172
+ /// be determined by the `RUST_LOG` environment variable.
173
+ ///
174
+ /// **Note**: this function sets the [default `tracing` subscriber][default]
175
+ /// for your application. If you need to add additional layers to a subscriber,
176
+ /// see [`spawn`].
177
+ ///
178
+ /// ## Panics
179
+ ///
180
+ /// * If the subscriber's background thread could not be spawned.
181
+ /// * If the [default `tracing` subscriber][default] has already been set.
182
+ ///
183
+ /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
184
+ /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
185
+ /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
186
+ /// [`Server`]: crate::Server
187
+ ///
188
+ /// ## Configuration
189
+ ///
190
+ /// Tokio console subscriber is configured with sensible defaults for most
191
+ /// use cases. If you need to tune these parameters, several environmental
192
+ /// configuration variables are available:
193
+ ///
194
+ /// | **Environment Variable** | **Purpose** | **Default Value** |
195
+ /// |-------------------------------------|---------------------------------------------------------------------------|-------------------|
196
+ /// | `TOKIO_CONSOLE_RETENTION` | The number of seconds to accumulate completed tracing data | 3600s (1h) |
197
+ /// | `TOKIO_CONSOLE_BIND` | A HOST:PORT description, such as `localhost:1234` | `127.0.0.1:6669` |
198
+ /// | `TOKIO_CONSOLE_PUBLISH_INTERVAL` | The number of milliseconds to wait between sending updates to the console | 1000ms (1s) |
199
+ /// | `TOKIO_CONSOLE_RECORD_PATH` | The file path to save a recording | None |
200
+ /// | `RUST_LOG` | Configures what events are logged events. See [`Targets`] for details. | "error" |
201
+ ///
202
+ /// ## Further customization
203
+ ///
204
+ /// To add additional layers or replace the format layer, replace
205
+ /// `console_subscriber::Builder::init` with:
206
+ ///
207
+ /// ```rust
208
+ /// use tracing_subscriber::prelude::*;
209
+ ///
210
+ /// let console_layer = console_subscriber::TasksLayer::builder().spawn();
211
+ ///
212
+ /// tracing_subscriber::registry()
213
+ /// .with(console_layer)
214
+ /// .with(tracing_subscriber::fmt::layer())
215
+ /// // .with(..potential additional layer..)
216
+ /// .init();
217
+ /// ```
218
+ ///
219
+ /// [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.Targets.html
220
+ pub fn init ( self ) {
221
+ let fmt_filter = std:: env:: var ( "RUST_LOG" )
222
+ . ok ( )
223
+ . and_then ( |rust_log| match rust_log. parse :: < Targets > ( ) {
224
+ Ok ( targets) => Some ( targets) ,
225
+ Err ( e) => {
226
+ eprintln ! ( "failed to parse `RUST_LOG={:?}`: {}" , rust_log, e) ;
227
+ None
228
+ }
229
+ } )
230
+ . unwrap_or_else ( || Targets :: default ( ) . with_default ( LevelFilter :: ERROR ) ) ;
231
+
232
+ let console_layer = self . spawn ( ) ;
233
+
234
+ tracing_subscriber:: registry ( )
235
+ . with ( console_layer)
236
+ . with ( tracing_subscriber:: fmt:: layer ( ) . with_filter ( fmt_filter) )
237
+ . init ( ) ;
238
+ }
239
+
240
+ /// Returns a new `tracing` [`Layer`] consisting of a [`TasksLayer`]
241
+ /// and a [filter] that enables the spans and events required by the console.
242
+ ///
243
+ /// This function spawns the console subscriber's [`Server`] in its own Tokio
244
+ /// runtime in a background thread.
245
+ ///
246
+ /// Unlike [`init`], this function does not set the default subscriber, allowing
247
+ /// additional [`Layer`]s to be added.
248
+ ///
249
+ /// [subscriber]: https://docs.rs/tracing/latest/tracing/subscriber/trait.Subscriber.html
250
+ /// [filter]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.Targets.html
251
+ /// [`Layer`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html
252
+ /// [`Server`]: crate::Server
253
+ ///
254
+ /// ## Panics
255
+ ///
256
+ /// * If the subscriber's background thread could not be spawned.
257
+ ///
258
+ /// ## Configuration
259
+ ///
260
+ /// `console_subscriber::build` supports all of the environmental
261
+ /// configuration described at [`console_subscriber::init`].
262
+ ///
263
+ /// ## Differences from `init`
264
+ ///
265
+ /// Unlike [`console_subscriber::init`], this function does *not* add a
266
+ /// [`tracing_subscriber::fmt`] layer to the configured `Subscriber`. This means
267
+ /// that this function will not log spans and events based on the value of the
268
+ /// `RUST_LOG` environment variable. Instead, a user-provided [`fmt::Layer`] can
269
+ /// be added in order to customize the log format.
270
+ ///
271
+ /// You must call [`.init()`] on the final subscriber in order to [set the
272
+ /// subscriber as the default][default].
273
+ ///
274
+ /// ## Examples
275
+ ///
276
+ /// ```rust
277
+ /// use tracing_subscriber::prelude::*;
278
+ ///
279
+ /// let console_layer = console_subscriber::TasksLayer::builder()
280
+ /// .with_default_env()
281
+ /// .spawn();
282
+ ///
283
+ /// tracing_subscriber::registry()
284
+ /// .with(console_layer)
285
+ /// .with(tracing_subscriber::fmt::layer())
286
+ /// // .with(...)
287
+ /// .init();
288
+ /// ```
289
+ /// [`.init()`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/util/trait.SubscriberInitExt.html
290
+ /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
291
+ /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
292
+ /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
293
+ /// [`fmt::Layer`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/struct.Layer.html
294
+ /// [`console_subscriber::init`]: crate::init()
295
+ #[ must_use = "a `Layer` must be added to a `tracing::Subscriber` in order to be used" ]
296
+ pub fn spawn < S > ( self ) -> impl Layer < S >
297
+ where
298
+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
299
+ {
300
+ fn console_filter ( meta : & tracing:: Metadata < ' _ > ) -> bool {
301
+ // events will have *targets* beginning with "runtime"
302
+ if meta. is_event ( ) {
303
+ return meta. target ( ) . starts_with ( "runtime" ) || meta. target ( ) . starts_with ( "tokio" ) ;
304
+ }
305
+
306
+ // spans will have *names* beginning with "runtime". for backwards
307
+ // compatibility with older Tokio versions, enable anything with the `tokio`
308
+ // target as well.
309
+ meta. name ( ) . starts_with ( "runtime." ) || meta. target ( ) . starts_with ( "tokio" )
310
+ }
311
+
312
+ let ( layer, server) = self . build ( ) ;
313
+ let filter =
314
+ FilterFn :: new ( console_filter as for <' r , ' s > fn ( & ' r tracing:: Metadata < ' s > ) -> bool ) ;
315
+ let layer = layer. with_filter ( filter) ;
316
+
317
+ thread:: Builder :: new ( )
318
+ . name ( "console_subscriber" . into ( ) )
319
+ . spawn ( move || {
320
+ let runtime = runtime:: Builder :: new_current_thread ( )
321
+ . enable_io ( )
322
+ . enable_time ( )
323
+ . build ( )
324
+ . expect ( "console subscriber runtime initialization failed" ) ;
325
+
326
+ runtime. block_on ( async move {
327
+ server
328
+ . serve ( )
329
+ . await
330
+ . expect ( "console subscriber server failed" )
331
+ } ) ;
332
+ } )
333
+ . expect ( "console subscriber could not spawn thread" ) ;
334
+
335
+ layer
336
+ }
337
+ }
338
+
339
+ /// Initializes the console [tracing `Subscriber`][sub] and starts the console
340
+ /// subscriber [`Server`] on its own background thread.
341
+ ///
342
+ /// This function represents the easiest way to get started using
343
+ /// tokio-console.
344
+ ///
345
+ /// In addition to the [`TasksLayer`], which collects instrumentation data
346
+ /// consumed by the console, the default [`Subscriber`][sub] initialized by this
347
+ /// function also includes a [`tracing_subscriber::fmt`] layer, which logs
348
+ /// tracing spans and events to stdout. Which spans and events are logged will
349
+ /// be determined by the `RUST_LOG` environment variable.
350
+ ///
351
+ /// **Note**: this function sets the [default `tracing` subscriber][default]
352
+ /// for your application. If you need to add additional layers to a subscriber,
353
+ /// see [`spawn`].
354
+ ///
355
+ /// ## Panics
356
+ ///
357
+ /// * If the subscriber's background thread could not be spawned.
358
+ /// * If the [default `tracing` subscriber][default] has already been set.
359
+ ///
360
+ /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
361
+ /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
362
+ /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
363
+ /// [`Server`]: crate::Server
364
+ ///
365
+ /// ## Configuration
366
+ ///
367
+ /// Tokio console subscriber is configured with sensible defaults for most
368
+ /// use cases. If you need to tune these parameters, several environmental
369
+ /// configuration variables are available:
370
+ ///
371
+ /// | **Environment Variable** | **Purpose** | **Default Value** |
372
+ /// |-------------------------------------|---------------------------------------------------------------------------|-------------------|
373
+ /// | `TOKIO_CONSOLE_RETENTION` | The number of seconds to accumulate completed tracing data | 3600s (1h) |
374
+ /// | `TOKIO_CONSOLE_BIND` | A HOST:PORT description, such as `localhost:1234` | `127.0.0.1:6669` |
375
+ /// | `TOKIO_CONSOLE_PUBLISH_INTERVAL` | The number of milliseconds to wait between sending updates to the console | 1000ms (1s) |
376
+ /// | `TOKIO_CONSOLE_RECORD_PATH` | The file path to save a recording | None |
377
+ /// | `RUST_LOG` | Configures what events are logged events. See [`Targets`] for details. | "error" |
378
+ ///
379
+ /// ## Further customization
380
+ ///
381
+ /// To add additional layers or replace the format layer, replace
382
+ /// `console_subscriber::init` with:
383
+ ///
384
+ /// ```rust
385
+ /// use tracing_subscriber::prelude::*;
386
+ ///
387
+ /// let console_layer = console_subscriber::spawn();
388
+ ///
389
+ /// tracing_subscriber::registry()
390
+ /// .with(console_layer)
391
+ /// .with(tracing_subscriber::fmt::layer())
392
+ /// // .with(..potential additional layer..)
393
+ /// .init();
394
+ /// ```
395
+ ///
396
+ /// Calling `console_subscriber::init` is equivalent to the following:
397
+ /// ```rust
398
+ /// use console_subscriber::TasksLayer;
399
+ ///
400
+ /// TasksLayer::builder().with_default_env().init();
401
+ /// ```
402
+ /// [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/filter/struct.Targets.html
403
+ pub fn init ( ) {
404
+ TasksLayer :: builder ( ) . with_default_env ( ) . init ( ) ;
405
+ }
406
+
407
+ /// Returns a new `tracing_subscriber` [`Layer`] configured with a [`TasksLayer`]
408
+ /// and a [filter] that enables the spans and events required by the console.
409
+ ///
410
+ /// This function spawns the console subscriber's [`Server`] in its own Tokio
411
+ /// runtime in a background thread.
412
+ ///
413
+ /// Unlike [`init`], this function does not set the default subscriber, allowing
414
+ /// additional [`Layer`]s to be added.
415
+ ///
416
+ /// This function is equivalent to the following:
417
+ /// ```
418
+ /// use console_subscriber::TasksLayer;
419
+ ///
420
+ /// let layer = TasksLayer::builder().with_default_env().spawn();
421
+ /// # use tracing_subscriber::prelude::*;
422
+ /// # tracing_subscriber::registry().with(layer).init(); // to suppress must_use warnings
423
+ /// ```
424
+ /// [filter]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.Targets.html
425
+ /// [`Layer`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html
426
+ /// [`Server`]: crate::Server
427
+ ///
428
+ /// ## Panics
429
+ ///
430
+ /// * If the subscriber's background thread could not be spawned.
431
+ ///
432
+ /// ## Configuration
433
+ ///
434
+ /// `console_subscriber::build` supports all of the environmental
435
+ /// configuration described at [`console_subscriber::init`].
436
+ ///
437
+ /// ## Differences from `init`
438
+ ///
439
+ /// Unlike [`console_subscriber::init`], this function does *not* add a
440
+ /// [`tracing_subscriber::fmt`] layer to the configured `Layer`. This means
441
+ /// that this function will not log spans and events based on the value of the
442
+ /// `RUST_LOG` environment variable. Instead, a user-provided [`fmt::Layer`] can
443
+ /// be added in order to customize the log format.
444
+ ///
445
+ /// You must call [`.init()`] on the final subscriber in order to [set the
446
+ /// subscriber as the default][default].
447
+ ///
448
+ /// ## Examples
449
+ ///
450
+ /// ```rust
451
+ /// use tracing_subscriber::prelude::*;
452
+ /// tracing_subscriber::registry()
453
+ /// .with(console_subscriber::spawn())
454
+ /// .with(tracing_subscriber::fmt::layer())
455
+ /// // .with(...)
456
+ /// .init();
457
+ /// ```
458
+ /// [`.init()`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/util/trait.SubscriberInitExt.html
459
+ /// [default]: https://docs.rs/tracing/latest/tracing/dispatcher/index.html#setting-the-default-subscriber
460
+ /// [sub]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
461
+ /// [`tracing_subscriber::fmt`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/index.html
462
+ /// [`fmt::Layer`]: https://docs.rs/tracing-subscriber/latest/tracing-subscriber/fmt/struct.Layer.html
463
+ /// [`console_subscriber::init`]: crate::init()
464
+ #[ must_use = "a `Layer` must be added to a `tracing::Subscriber`in order to be used" ]
465
+ pub fn spawn < S > ( ) -> impl Layer < S >
466
+ where
467
+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
468
+ {
469
+ TasksLayer :: builder ( ) . with_default_env ( ) . spawn :: < S > ( )
152
470
}
153
471
154
472
fn duration_from_env ( var_name : & str ) -> Option < Duration > {
0 commit comments