## 1. Project Overview & Quickstart (tokio-rs/console) ## File: README.md # tokio-console [][main-docs] [![MIT licensed][mit-badge]][mit-url] [![Build Status][actions-badge]][actions-url] [![Discord chat][discord-badge]][discord-url] [Chat][discord-url] | [API Documentation (`main` branch)][main-docs] [main-docs]: https://tokio-console.netlify.app [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: LICENSE [actions-badge]: https://github.com/tokio-rs/console/workflows/CI/badge.svg [actions-url]:https://github.com/tokio-rs/console/actions?query=workflow%3ACI [discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white [discord-url]: https://discord.gg/EeF3cQw ## what's all this, then? this repository contains an implementation of TurboWish/tokio-console, a diagnostics and debugging tool for asynchronous Rust programs. the diagnostic toolkit consists of multiple components: * a **wire protocol for streaming diagnostic data** from instrumented applications to diagnostic tools. the wire format is defined using [gRPC] and [protocol buffers], for efficient transport on the wire and interoperability between different implementations of data producers and consumers. the [`console-api`] crate contains generated code for this wire format for projects using the [`tonic`] gRPC implementation. additionally, projects using other gRPC code generators (including those in other languages!) can depend on [the protobuf definitions] themselves. * **instrumentation for collecting diagnostic data** from a process and exposing it over the wire format. the [`console-subscriber`] crate in this repository contains **an implementation of the instrumentation-side API as a [`tracing-subscriber`] [`Layer`]**, for projects using [Tokio] and [`tracing`]. * tools for **displaying and exploring diagnostic data**, implemented as gRPC clients using the console wire protocol. the [`tokio-console`] crate implements an **an interactive command-line tool** that consumes this data, but **other implementations**, such as graphical or web-based tools, are also possible. [gRPC]: https://grpc.io/ [protocol buffers]: https://developers.google.com/protocol-buffers [the protobuf definitions]: https://github.com/tokio-rs/console/tree/main/console-api/proto [`tonic`]: https://lib.rs/crates/tonic [Tokio]: https://tokio.rs ## extremely cool and amazing screenshots wow! whoa! it's like `top(1)` for tasks! viewing details for a single task: ## on the shoulders of giants the console is **part of a much larger effort** to improve debugging tooling for async Rust. **a [2019 Google Summer of Code project][gsoc] by Matthias Prechtl** ([**@matprec**]) implemented an initial prototype, with a focus on interactive log viewing. more recently, both **the [Tokio team][tokio-blog] and the [async foundations working group][shiny-future]** have made diagnostics and debugging tools a priority for async Rust in 2021 and beyond. in particular, a [series][tw-1] of [blog][tw-2] [posts][tw-3] by [**@pnkfelix**] lay out much of the vision that this project seeks to eventually implement. furthermore, we're indebted to our antecedents in other programming languages and environments for inspiration. this includes tools and systems such as [`pprof`], Unix [`top(1)`] and [`htop(1)`], XCode's [Instruments], and many others. [gsoc]: https://github.com/tokio-rs/console-gsoc [tokio-blog]: https://tokio.rs/blog/2020-12-tokio-1-0#tracing [shiny-future]: https://rust-lang.github.io/wg-async/vision/submitted_stories/shiny_future/barbara_makes_a_wish.html [tw-1]: http://blog.pnkfx.org/blog/2021/04/26/road-to-turbowish-part-1-goals/ [tw-2]: http://blog.pnkfx.org/blog/2021/04/27/road-to-turbowish-part-2-stories/ [tw-3]: http://blog.pnkfx.org/blog/2021/05/03/road-to-turbowish-part-3-design/ [`pprof`]: https://github.com/google/pprof [`top(1)`]: https://man7.org/linux/man-pages/man1/top.1.html [`htop(1)`]: https://htop.dev/ [Instruments]: https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/MeasuringPerformance.html [**@matprec**]: https://github.com/matprec [**@pnkfelix**]: https://github.com/pnkfelix ## using it ### instrumenting your program to **instrument an application using Tokio**, add a dependency on the [`console-subscriber`] crate, and **add this one-liner** to the top of your `main` function: ```rust console_subscriber::init(); ``` notes: * in order to collect task data from Tokio, **the `tokio_unstable` cfg must be enabled**. for example, you could build your project with ```shell RUSTFLAGS="--cfg tokio_unstable" cargo build ``` or add the following to your `.cargo/config.toml` file: ```toml [build] rustflags = ["--cfg", "tokio_unstable"] ``` For more information on the appropriate location of your `.cargo/config.toml` file, especially when using workspaces, see the [console-subscriber readme](console-subscriber/README.md#enabling-tokio-instrumentation). * the `tokio` and `runtime` [`tracing` targets] must be enabled at the [`TRACE` level]. * if you're using the [`console_subscriber::init()`][init] or [`console_subscriber::Builder`][builder] APIs, these targets are enabled automatically. * if you are manually configuring the `tracing` subscriber using the [`EnvFilter`] or [`Targets`] filters from [`tracing-subscriber`], add `"tokio=trace,runtime=trace"` to your filter configuration. * also, ensure you have not enabled any of the [compile time filter features][compile_time_filters] in your `Cargo.toml`. ### running the console to **run the console command-line tool**, install `tokio-console` from [crates.io](https://crates.io/crates/tokio-console) ```shell cargo install --locked tokio-console ``` and run locally ```shell tokio-console ``` > **alternative method:** run the tool from a local checkout of this repository > > ```shell > $ cargo run > ``` by default, this will attempt to connect to an instrumented application running on localhost on port 6669. if the application is running somewhere else, or is serving the console endpoint on a different port, a target address can be passed as an argument to the console (either as an `:` or `:`). for example: ```shell cargo run -- http://my.great.console.app.local:5555 ``` The console command-line tool supports a number of additional flags to configure its behavior. The `help` command will print a list of supported command-line flags and arguments: ``` /* Detailed source-code truncated for AI context efficiency. */ ``` #### running the console on windows The console uses the UTF-8 character set to display graphs and other visual features in the terminal. In order to display this rich terminal UI on Windows, it's necessary to use a UTF-8-enabled terminal emulator, such as the new [Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/install). If you're using a terminal that supports UTF-8, make sure to explicitly call tokio-console with the UTF-8 language flag set: ```shell tokio-console --lang en_US.UTF-8 ``` ## for development the `console-subscriber/examples` directory contains **some potentially useful tools**: * `app.rs`: a very simple example program that spawns a bunch of tasks in a loop forever * `dump.rs`: a simple CLI program that dumps the data stream from a `Tasks` server Examples can be executed with: ```shell cargo run --example $name ``` [`tracing`]: https://lib.rs/crates/tracing [`tracing-subscriber`]: https://lib.rs/crates/tracing-subscriber [`console-api`]: ./console-api [`console-subscriber`]: ./console-subscriber [`tokio-console`]: ./tokio-console [`Layer`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html [`tracing` targets]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html [`TRACE` level]: https://docs.rs/tracing/latest/tracing/struct.Level.html#associatedconstant.TRACE [builder]: https://docs.rs/console-subscriber/latest/console_subscriber/struct.Builder.html [init]: https://docs.rs/console-subscriber/latest/console_subscriber/fn.init.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html [compile_time_filters]: https://docs.rs/tracing/latest/tracing/level_filters/index.html#compile-time-filters --- ## File: console-api/README.md # tokio-console API 🛰 [Tonic] bindings for the [`tokio-console`] [protobuf] wire format. [![crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] [![Documentation (`main` branch)][docs-main-badge]][docs-main-url] [![MIT licensed][mit-badge]][mit-url] [![Build Status][actions-badge]][actions-url] [![Discord chat][discord-badge]][discord-url] [Website](https://tokio.rs) | [Chat][discord-url] | [API Documentation][docs-url] [crates-badge]: https://img.shields.io/crates/v/console-api.svg [crates-url]: https://crates.io/crates/console-api [docs-badge]: https://docs.rs/console-api/badge.svg [docs-url]: https://docs.rs/console-api [docs-main-badge]: https://img.shields.io/netlify/0e5ffd50-e1fa-416e-b147-a04dab28cfb1?label=docs%20%28main%20branch%29 [docs-main-url]: https://tokio-console.netlify.app/console_api/ [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: ../LICENSE [actions-badge]: https://github.com/tokio-rs/console/workflows/CI/badge.svg [actions-url]:https://github.com/tokio-rs/console/actions?query=workflow%3ACI [discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white ## Overview This crate contains generated [protobuf] bindings for the [`tokio-console`] wire format. The wire format is used to export diagnostic data from instrumented applications to consumers that aggregate and display that data. [`tokio-console`] is a debugging and profiling tool for asynchronous Rust applications, which collects and displays in-depth diagnostic data on the asynchronous tasks, resources, and operations in an application. The console system consists of two primary components: * _instrumentation_, embedded in the application, which collects data from the async runtime and exposes it over the console's wire format * _consumers_, such as the [`tokio-console`] command-line application, which connect to the instrumented application, receive telemetry data, and display it to the user The wire format [protobuf] bindings in this crate are used by both the instrumentation in the [`console-subscriber`] crate, which emits telemetry in this format, and by the clients that consume that telemetry. In general, most [`tokio-console`] users will *not* depend on this crate directly. Applications are typically instrumented using the [`console-subscriber`] crate, which collects data and exports it using this wire format; this data can be consumed using the [`tokio-console`] command-line application. However, the wire format API definition in this crate may be useful for anyone implementing other software that also consumes the [`tokio-console`] diagnostic data. [`tokio-console`]: https://github.com/tokio-rs/console [`console-subscriber`]: https://crates.io/crates/console-subscriber [protobuf]: https://developers.google.com/protocol-buffers ### Stability ⚠️ The protobuf wire format is not currently considered totally stable. While we will try to avoid unnecessary protobuf-incompatible changes, protobuf compatibility is only guaranteed within SemVer-compatible releases of this crate. For example, the protobuf as of `console-api` v0.2.5 may not be backwards-compatible with `console-api` v0.1.12. ### Crate Feature Flags This crate provides the following feature flags: * `transport`: Generate code that is compatible with [Tonic]'s [`transport` module] (disabled by default) [Tonic]: https://crates.io/crates/tonic [`transport` module]: https://docs.rs/tonic/latest/tonic/transport/index.html ## Getting Help First, see if the answer to your question can be found in the [API documentation]. If the answer is not there, there is an active community in the [Tokio Discord server][discord-url]. We would be happy to try to answer your question. You can also ask your question on [the discussions page][discussions]. [API documentation]: https://docs.rs/console-api [discussions]: https://github.com/tokio-rs/console/discussions [discord-url]: https://discord.gg/tokio ## Contributing 🎈 Thanks for your help improving the project! We are so happy to have you! We have a [contributing guide][guide] to help you get involved in the Tokio console project. [guide]: https://github.com/tokio-rs/console/blob/main/CONTRIBUTING.md ## Supported Rust Versions The Tokio console is built against the latest stable release. The minimum supported version is 1.64. The current Tokio console version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## License This project is licensed under the [MIT license]. [MIT license]: https://github.com/tokio-rs/console/blob/main/LICENSE ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you, shall be licensed as MIT, without any additional terms or conditions. --- ## File: console-subscriber/examples/grpc_web/README.md # gRPC-web Example This app provides an example of using the gRPC-web library to facilitate communication between a web browser and a gRPC server. ## Prerequisites Ensure you have the following installed on your system: - [Node.js](https://nodejs.org/en/download/) (version 20.10.0 or higher) - [npm](https://www.npmjs.com/get-npm) (version 10.2.3 or higher) ## Getting Started Follow these steps to get the application up and running: 1. **Install Dependencies:** Navigate to the `console-subscriber/examples/grpc_web/app` directory and install all necessary dependencies: ```sh npm install ``` 2. **Start the gRPC-web Server:** In the console-subscriber directory, start the server: ```sh cargo run --example grpc_web --features grpc-web ``` 3. **Start the Web Application:** In the `console-subscriber/examples/grpc_web/app` directory, start the web application: ```sh npm run dev ``` 4. **View the Application:** Open a web browser and navigate to `http://localhost:5173`. You can view the output in the developer console. ## Understanding the Code This example leverages the [connect-es] library to enable communication with the gRPC server from a web browser. The client code can be found in the `console-subscriber/examples/grpc_web/app/src/app.tsx` file. The [buf] tool is used to generate the gRPC code. You can generate the code using the following command: ```sh npm run gen ``` For more information about the connect-es library, refer to the [connect-es documentation]. [connect-es]: https://github.com/connectrpc/connect-es [buf]: https://buf.build/ [connect-es documentation]: https://connectrpc.com/docs/web/getting-started --- ## File: console-subscriber/README.md # tokio-console subscriber 📡️ A [`tracing-subscriber`] [`Layer`] for collecting [`tokio-console`] telemetry. [![crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] [![Documentation (`main` branch)][docs-main-badge]][docs-main-url] [![MIT licensed][mit-badge]][mit-url] [![Build Status][actions-badge]][actions-url] [![Discord chat][discord-badge]][discord-url] [Website](https://tokio.rs) | [Chat][discord-url] | [API Documentation][docs-url] [crates-badge]: https://img.shields.io/crates/v/console-subscriber.svg [crates-url]: https://crates.io/crates/console-subscriber [docs-badge]: https://docs.rs/console-subscriber/badge.svg [docs-url]: https://docs.rs/console-subscriber [docs-main-badge]: https://img.shields.io/netlify/0e5ffd50-e1fa-416e-b147-a04dab28cfb1?label=docs%20%28main%20branch%29 [docs-main-url]: https://tokio-console.netlify.app/console_subscriber/ [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: ../LICENSE [actions-badge]: https://github.com/tokio-rs/console/workflows/CI/badge.svg [actions-url]:https://github.com/tokio-rs/console/actions?query=workflow%3ACI [discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white ## Overview [`tokio-console`] is a debugging and profiling tool for asynchronous Rust applications, which collects and displays in-depth diagnostic data on the asynchronous tasks, resources, and operations in an application. The console system consists of two primary components: * _instrumentation_, embedded in the application, which collects data from the async runtime and exposes it over the console's [wire format] * _consumers_, such as the [`tokio-console`] command-line application, which connect to the instrumented application, receive telemetry data, and display it to the user This crate implements the instrumentation-side interface using data emitted by the async runtime using the [`tracing`]. It provides a type implementing the [`Layer`] trait from [`tracing-subscriber`], for collecting and aggregating the runtime's [`tracing`] data, and a gRPC server that exports telemetry to clients. [wire format]: https://crates.io/crates/console-api ## Getting Started To instrument your asynchronous application, you must be using an async runtime that supports the [`tracing`] instrumentation required by the console. Currently, the only runtime that implements this instrumentation is [Tokio] version 1.7.0 and newer. ### Enabling Tokio Instrumentation ⚠️ Currently, the [`tracing`] support in the [`tokio` runtime][Tokio] is considered *experimental*. In order to use `console-subscriber` with Tokio, the following is required: * Tokio's optional `tracing` dependency must be enabled. For example: ```toml [dependencies] # ... tokio = { version = "1.15", features = ["full", "tracing"] } ``` * The `tokio_unstable` cfg flag, which enables experimental APIs in Tokio, must be enabled. It can be enabled by setting the `RUSTFLAGS` environment variable at build-time: ```shell $ RUSTFLAGS="--cfg tokio_unstable" cargo build ``` or, by adding the following to the `.cargo/config.toml` file in a Cargo workspace: ```toml [build] rustflags = ["--cfg", "tokio_unstable"] ``` If you're using a workspace, you should put the `.cargo/config.toml` file in the root of your workspace. Otherwise, put the `.cargo/config.toml` file in the root directory of your crate. Putting `.cargo/config.toml` files below the workspace or crate root directory may lead to tools like Rust-Analyzer or VSCode not using your `.cargo/config.toml` since they invoke cargo from the workspace or crate root and cargo only looks for the `.cargo` directory in the current & parent directories. Cargo ignores configurations in child directories. More information about where cargo looks for configuration files can be found [here](https://doc.rust-lang.org/cargo/reference/config.html). Missing this configuration file during compilation will cause tokio-console to not work, and alternating between building with and without this configuration file included will cause full rebuilds of your project. * The `tokio` and `runtime` [`tracing` targets] must be enabled at the [`TRACE` level]. + If you're using the [`console_subscriber::init()`][init] or [`console_subscriber::Builder`][builder] APIs, these targets are enabled automatically. + If you are manually configuring the `tracing` subscriber using the [`EnvFilter`] or [`Targets`] filters from [`tracing-subscriber`], add `"tokio=trace,runtime=trace"` to your filter configuration. + Also, ensure you have not enabled any of the [compile time filter features][compile_time_filters] in your `Cargo.toml`. #### Required Tokio Versions Because instrumentation for different aspects of the runtime is being added to Tokio over time, the latest Tokio release is generally *recommended* to access all of the console's functionality. However, it should generally be compatible with earlier Tokio versions, although some information may not be available. A minimum version of [Tokio v1.0.0] or later is required to use the console's task instrumentation. Other instrumentation is added in later Tokio releases: * [Tokio v1.7.0] or later is required to record task waker instrumentation (such as waker counts, clones, drops, et cetera). * [Tokio v1.12.0] or later is required to record tasks created by the [`Runtime::block_on`] and [`Handle::block_on`] methods. * [Tokio v1.13.0] or later is required to track [`tokio::time`] resources, such as `sleep` and `Interval`. * [Tokio v1.15.0] or later is required to track [`tokio::sync`] resources, such as `Mutex`es, `RwLock`s, `Semaphore`s, `oneshot` channels, `mpsc` channels, et cetera. * [Tokio v1.21.0] or later is required to use newest `task::Builder::spawn*` APIs. * [Tokio v1.41.0] (as yet unreleased) or later is required for task future sizes and the related tokio-console lints `auto-boxed-future` and `large-future`. [Tokio v1.0.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.0.0 [Tokio v1.7.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.7.0 [Tokio v1.12.0]:https://github.com/tokio-rs/tokio/releases/tag/tokio-1.12.0 [`Runtime::block_on`]: https://docs.rs/tokio/1/tokio/runtime/struct.Runtime.html#method.block_on [`Handle::block_on`]: https://docs.rs/tokio/1/tokio/runtime/struct.Handle.html#method.block_on [Tokio v1.13.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.13.0 [`tokio::time`]: https://docs.rs/tokio/1/tokio/time/index.html [Tokio v1.15.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.13.0 [`tokio::sync`]: https://docs.rs/tokio/1/tokio/sync/index.html [`tracing` targets]: https://docs.rs/tracing/latest/tracing/struct.Metadata.html [`TRACE` level]: https://docs.rs/tracing/latest/tracing/struct.Level.html#associatedconstant.TRACE [`EnvFilter`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html [`Targets`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html [builder]: https://docs.rs/console-subscriber/latest/console_subscriber/struct.Builder.html [init]: https://docs.rs/console-subscriber/latest/console_subscriber/fn.init.html [compile_time_filters]: https://docs.rs/tracing/latest/tracing/level_filters/index.html#compile-time-filters [Tokio v1.21.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.21.0 [Tokio v1.41.0]: https://github.com/tokio-rs/tokio/releases/tag/tokio-1.41.0 ### Adding the Console Subscriber If the runtime emits compatible `tracing` events, enabling the console is as simple as adding the following line to your `main` function: ```rust console_subscriber::init(); ``` This sets the [default `tracing` subscriber][default] to serve console telemetry (as well as logging to stdout based on the `RUST_LOG` environment variable). The console subscriber's behavior can be configured via a set of [environment variables][env]. For programmatic configuration, a [builder interface][builder] is also provided: ```rust use std::time::Duration; console_subscriber::ConsoleLayer::builder() // set how long the console will retain data from completed tasks .retention(Duration::from_secs(60)) // set the address the server is bound to .server_addr(([127, 0, 0, 1], 5555)) // ... other configurations ... .init(); ``` The layer provided by this crate can also be combined with other [`Layer`]s from other crates: ```rust use tracing_subscriber::prelude::*; // spawn the console server in the background, // returning a `Layer`: let console_layer = console_subscriber::spawn(); // build a `Subscriber` by combining layers with a // `tracing_subscriber::Registry`: tracing_subscriber::registry() // add the console layer to the subscriber .with(console_layer) // add other layers... .with(tracing_subscriber::fmt::layer()) // .with(...) .init(); ``` [`tracing`]: https://crates.io/crates/tracing [`tracing-subscriber`]: https://crates.io/crates/tracing-subscriber [`Layer`]:https://docs.rs/tracing-subscriber/0.3/tracing_subscriber/layer/index.html [default]: https://docs.rs/tracing/latest/tracing/#in-executables [env]: https://docs.rs/console-subscriber/latest/console_subscriber/struct.Builder.html#method.with_default_env [builder]: https://docs.rs/console-subscriber/latest/console_subscriber/struct.Builder.html [`tokio-console`]: https://github.com/tokio-rs/console [Tokio]: https://tokio.rs ### Using other runtimes If you are using a custom runtime that supports tokio-console, you may not need to enable the `tokio_unstable` cfg flag. In this case, you need to enable cfg `console_without_tokio_unstable` for console-subscriber to disable its check for `tokio_unstable`. ### Crate Feature Flags This crate provides the following feature flags and optional dependencies: * [`parking_lot`]: Use the [`parking_lot`] crate's locks, rather than `std::sync`. Using [`parking_lot`] may result in improved performance, especially in highly concurrent applications. Disabled by default. [`parking_lot`]: https://crates.io/crates/parking_lot ## Getting Help First, see if the answer to your question can be found in the [API documentation]. If the answer is not there, there is an active community in the [Tokio Discord server][discord-url]. We would be happy to try to answer your question. You can also ask your question on [the discussions page][discussions]. [API documentation]: https://docs.rs/console-subscriber [discussions]: https://github.com/tokio-rs/console/discussions [discord-url]: https://discord.gg/tokio ## Contributing 🎈 Thanks for your help improving the project! We are so happy to have you! We have a [contributing guide][guide] to help you get involved in the Tokio console project. [guide]: https://github.com/tokio-rs/console/blob/main/CONTRIBUTING.md ## Supported Rust Versions The Tokio console is built against the latest stable release. The minimum supported version is 1.88. The current Tokio console version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## License This project is licensed under the [MIT license]. [MIT license]: https://github.com/tokio-rs/console/blob/main/LICENSE ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you, shall be licensed as MIT, without any additional terms or conditions. --- ## File: tokio-console/README.md # tokio-console CLI 🎛️ The [Tokio console][`tokio-console`]: a debugger for asynchronous Rust programs. [![crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] [![Documentation (`main` branch)][docs-main-badge]][docs-main-url] [![MIT licensed][mit-badge]][mit-url] [![Build Status][actions-badge]][actions-url] [![Discord chat][discord-badge]][discord-url] [Website](https://tokio.rs) | [Chat][discord-url] | [API Documentation][docs-url] [crates-badge]: https://img.shields.io/crates/v/tokio-console.svg [crates-url]: https://crates.io/crates/tokio-console [docs-badge]: https://docs.rs/tokio-console/badge.svg [docs-url]: https://docs.rs/tokio-console [docs-main-badge]: https://img.shields.io/netlify/0e5ffd50-e1fa-416e-b147-a04dab28cfb1?label=docs%20%28main%20branch%29 [docs-main-url]: https://tokio-console.netlify.app/tokio_console/ [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: ../LICENSE [actions-badge]: https://github.com/tokio-rs/console/workflows/CI/badge.svg [actions-url]:https://github.com/tokio-rs/console/actions?query=workflow%3ACI [discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white ## Overview [`tokio-console`] is a debugging and profiling tool for asynchronous Rust applications, which collects and displays in-depth diagnostic data on the asynchronous tasks, resources, and operations in an application. The console system consists of two primary components: * 📡️ _instrumentation_, embedded in the application, which collects data from the async runtime and exposes it over the console's wire format * 🛰️ _consumers_, which connect to the instrumented application, receive telemetry data, and display it to the user This crate is the primary consumer of `tokio-console` telemetry, a command-line application that provides an interactive debugging interface. [wire format]: https://crates.io/crates/console-api [subscriber]: https://crates.io/crates/console-subscriber ## Getting Started To use the console to monitor and debug a program, it must be instrumented to emit the data the console consumes. Then, the `tokio-console` CLI application can be used to connect to the application and monitor its operation. ### Instrumenting the Application Before the console can connect to an application, it must first be instrumented to record `tokio-console` telemetry. The easiest way to do this is [using the `console-subscriber` crate][subscriber]. `console-subscriber` requires that the application's async runtime (or runtimes) emit [`tracing`] data in a format that the console can record. For programs that use the [Tokio] runtime, this means that: - Tokio's [unstable features][unstable] must be enabled. See [the `console-subscriber` documentation][unstable] for details. - A [compatible Tokio version][versions] must be used. Tokio v1.0 or greater is required to use the console, and some features are only available in later versions. See [the `console-subscriber` documentation][versions] for details. [`tracing`]: https://crates.io/crates/tracing [unstable]: https://docs.rs/console-subscriber/0.1/console_subscriber/#enabling-tokio-instrumentation [versions]: https://docs.rs/console-subscriber/0.1/console_subscriber/#required-tokio-versions ### Using the Console Once the application is instrumented, install the console CLI using ```shell cargo install --locked tokio-console ``` Running `tokio-console` without any arguments will connect to an application on localhost listening on the default port, port 6669: ```shell tokio-console ``` If the application is not running locally, or was configured to listen on a different port, the console will also accept a target address as a command-like argument: ```shell tokio-console http://192.168.0.42:9090 ``` A DNS name can also be provided as the target address: ```shell tokio-console http://my.instrumented.application.local:6669 ``` See [here][cli-ref] for a complete list of all command-line arguments. Tokio Console has a number of different views: * [Tasks List](#tasks-list) * [Task Details](#task-details) * [Resources List](#resources-list) * [Resource Details](#resource-details) #### running the console on windows The console uses the UTF-8 character set to display graphs and other visual features in the terminal. In order to display this rich terminal UI on Windows, it's necessary to use a UTF-8-enabled terminal emulator, such as the new [Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/install). If you're using a terminal that supports UTF-8, make sure to explicitly call tokio-console with the UTF-8 language flag set: ```shell tokio-console --lang en_US.UTF-8 ``` ### Tasks List When the console CLI is launched, it displays a list of all [asynchronous tasks] in the program: Tasks are displayed in a table. * `Warn` - The number of warnings active for the task. * `ID` - The ID of the task. This is the same as the value returned by the unstable [`tokio::task::Id`](https://docs.rs/tokio/latest/tokio/task/struct.Id.html) API (see documentation for details). * `State` - The state of the task. * `RUNNING`/▶ - Task is currently being polled. * `IDLE`/⏸ - Task is waiting on some resource. * `SCHED`/⏫ - Task is scheduled (it has been woken but not yet polled). * `DONE`/⏹ - Task has completed. * `Name` - The name of the task, which can be set when spawning a task using the unstable [`tokio::task::Builder::name()`](https://docs.rs/tokio/latest/tokio/task/struct.Builder.html#method.name) API. * `Total` - Duration the task has been alive (sum of Busy, Sched, and Idle). * `Busy` - Total duration for which the task has been actively executing. * `Sched` - Total duration for which the task has been scheduled to be polled by the runtime. * `Idle` - Total duration for which the task has been idle (waiting to be woken). * `Polls` - Number of times the task has been polled. * `Target` - The target of the span used to record the task. * `tokio::task` - Async task. * `tokio::task::blocking` - A blocking task (created with [tokio::task::spawn_blocking](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html)). * `Location` - The source code location where the task was spawned from. * `Fields` - Additional fields on the task span. * `kind` - may be `task` (for async tasks) or `blocking` (for blocking tasks). * `fn` - function signature for blocking tasks. Async tasks don't record this field, as it is generally very large when using `async`/`await`. Using the and arrow keys, an individual task can be highlighted. Pressingenter while a task is highlighted displays details about that task. ### Task Details This view shows details about a specific task: The task details view includes percentiles and a visual histogram of the polling (busy) times and scheduled times. Pressing the escape key returns to the task list. ### Resources List The r key switches from the list of tasks to a list of [resources], such as synchronization primitives, I/O resources, et cetera: Resources are displayed in a table similar to the task list. * `ID` - The ID of the resource. This is a display ID as there is no internal resource ID to reference. * `Parent` - The ID of the parent resource if it exists. * `Kind` - The resource kind, this is a high level grouping of resources. * `Sync` - Synchronization resources from [`tokio::sync`](https://docs.rs/tokio/latest/tokio/sync/index.html) such as [`Mutex`](https://docs.rs/tokio/latest/tokio/sync/struct.Mutex.html). * `Timer` - Timer resources from [`tokio::time`](https://docs.rs/tokio/latest/tokio/time/index.html) such as [`Sleep`](https://docs.rs/tokio/latest/tokio/time/struct.Sleep.html). * `Total` - Total duration that this resource has been alive. * `Target` - The module path of the resource type. * `Type` - The specific type of the resource, possible values depend on the resources instrumented in Tokio, which may vary between versions. * `Vis` - The visibility of the resource. * `INT`/🔒 - Internal, this resource is only used by other resources. * `PUB`/✅ - Public, available in the public Tokio API. * `Location` - The source code location where the resource was created. * `Attributes` - Additional resource-dependent attributes, for example a resource of type `Sleep` record the `duration` of the sleep. Pressing the t key switches the view back to the task list. Like the task list view, the resource list view can be navigated using the and arrow keys. Pressing enter while a resource is highlighted displays details about that resource. ### Resource Details The resource details view lists the tasks currently waiting on that resource. This may be a single task, as in the [`tokio::time::Sleep`] above, or a large number of tasks, such as this private `tokio::sync::batch_semaphore::Semaphore`: The resource details view includes a table of async ops belonging to the resource. * `ID` - The ID of the async op. This is a display ID similar to those recorded for resources. * `Parent` - The ID of the parent async op, if it exists. * `Task` - The ID and name of the task which performed this async op. * `Source` - The method where the async op is being called from. * `Total` - Total duration for which the async op has been alive (sum of Busy and Idle, as an async op has no scheduled state). * `Busy` - Total duration for which the async op has been busy (its future is actively being polled). * `Idle` - Total duration for which the async op has been idle (the future exists but is not being polled). * `Polls` - Number of times the async op has been polled. * `Attributes` - Additional attributes from the async op. These will vary based on the type of the async op. Like the task details view, pressing the escape key while viewing a resource's details returns to the resource list. A configuration file (`console.toml`) can be used to configure the console's behavior. See [the documentation][cfg-ref] for details. [`tokio-console`]: https://github.com/tokio-rs/console [Tokio]: https://tokio.rs [asynchronous tasks]: https://tokio.rs/tokio/tutorial/spawning#tasks [resources]: https://tokio.rs/tokio/tutorial/async#async-fn-as-a-future [`tokio::sync::oneshot`]: https://docs.rs/tokio/latest/tokio/sync/oneshot/index.html [`tokio::sync::Semaphore`]: https://docs.rs/tokio/latest/tokio/sync/struct.Semaphore.html [cli-ref]: https://docs.rs/tokio-console/latest/tokio_console/config_reference/index.html#command-line-arguments [cfg-ref]: https://docs.rs/tokio-console/latest/tokio_console/config_reference/index.html#configuration-file ## Getting Help First, see if the answer to your question can be found in the [API documentation]. If the answer is not there, there is an active community in the [Tokio Discord server][discord-url]. We would be happy to try to answer your question. You can also ask your question on [the discussions page][discussions]. [API documentation]: https://docs.rs/tokio-console [discussions]: https://github.com/tokio-rs/console/discussions [discord-url]: https://discord.gg/tokio ## Contributing 🎈 Thanks for your help improving the project! We are so happy to have you! We have a [contributing guide][guide] to help you get involved in the Tokio console project. [guide]: https://github.com/tokio-rs/console/blob/main/CONTRIBUTING.md ## Supported Rust Versions The Tokio console is built against the latest stable release. The minimum supported version is 1.88. The current Tokio console version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## License This project is licensed under the [MIT license]. [MIT license]: https://github.com/tokio-rs/console/blob/main/LICENSE ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you, shall be licensed as MIT, without any additional terms or conditions. ## 2. Official Technical Reference & Guides (tokio-rs/website) ## File: README.md # Tokio Website The website for the Tokio project. Lives at https://tokio.rs. Besides containing the content for the website, it also includes crates containing the example code used in the tutorial. These crates can be compiled and run. * [hello-tokio](tutorial-code/hello-tokio/src/main.rs) * [spawning](tutorial-code/spawning/src/main.rs) * [shared-state](tutorial-code/shared-state/src/main.rs) * [channels](tutorial-code/channels/src/main.rs) * [io](tutorial-code/io) * [echo-server-copy](tutorial-code/io/src/echo-server-copy.rs) * [echo-server](tutorial-code/io/src/echo-server.rs) * [mini-tokio](tutorial-code/mini-tokio/src/main.rs) ## Contributing Thinking about contributing? Great! This should help you get the website running locally. ### Getting Started The website is built using [Next.js] paired with the [Bulma] CSS framework. You'll need NPM to install the required packages with: ```bash npm install ``` Next, start the development server: ```bash npm run dev ``` Then, open [http://localhost:3000](http://localhost:3000). [Next.js]: https://nextjs.org/ [Bulma]: https://bulma.io/ ### Resources To learn more about Next.js, take a look at the following resources: - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - [Bulma documentation](https://bulma.io/documentation/) - learn about Bulma. ## License This project is licensed under the [MIT license](LICENSE). ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Tokio by you, shall be licensed as MIT, without any additional terms or conditions. You can run our tests by running the commands: ``` # in doc-test (unstable APIs are needed by some tests) RUSTFLAGS="--cfg tokio_unstable" cargo +nightly test # in tutorial-code cargo test --all ``` The doc tests verify that all code blocks are valid Rust, and the tutorial-code folder contains the full code examples from the tutorial. --- ## File: content/tokio/topics/bridging.md --- title: "Bridging with sync code" --- In most examples of using Tokio, we mark the main function with `#[tokio::main]` and make the entire project asynchronous. In some cases, you may need to run a small portion of synchronous code. For more information on that, see [`spawn_blocking`]. In other cases, it may be easier to structure the application as largely synchronous, with smaller or logically distinct asynchronous portions. For instance, a GUI application might want to run the GUI code on the main thread and run a Tokio runtime next to it on another thread. This page explains how you can isolate async/await to a small part of your project. # What `#[tokio::main]` expands to The `#[tokio::main]` macro is a macro that replaces your main function with a non-async main function that starts a runtime and then calls your code. For instance, this: ```rust #[tokio::main] async fn main() { println!("Hello world"); } ``` is turned into this: ```rust fn main() { tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap() .block_on(async { println!("Hello world"); }) } ``` by the macro. To use async/await in our own projects, we can do something similar where we leverage the [`block_on`] method to enter the asynchronous context where appropriate. # A synchronous interface to mini-redis In this section, we will go through how to build a synchronous interface to mini-redis by storing a `Runtime` object and using its `block_on` method. In the following sections, we will discuss some alternate approaches and when you should use each approach. The interface that we will be wrapping is the asynchronous [`Client`] type. It has several methods, and we will implement a blocking version of the following methods: * [`Client::get`] * [`Client::set`] * [`Client::set_expires`] * [`Client::publish`] * [`Client::subscribe`] To do this, we introduce a new file called `src/clients/blocking_client.rs` and initialize it with a wrapper struct around the async `Client` type: ```rs use tokio::net::ToSocketAddrs; use tokio::runtime::Runtime; pub use crate::clients::client::Message; /// Established connection with a Redis server. pub struct BlockingClient { /// The asynchronous `Client`. inner: crate::clients::Client, /// A `current_thread` runtime for executing operations on the /// asynchronous client in a blocking manner. rt: Runtime, } impl BlockingClient { pub fn connect(addr: T) -> crate::Result { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build()?; // Call the asynchronous connect method using the runtime. let inner = rt.block_on(crate::clients::Client::connect(addr))?; Ok(BlockingClient { inner, rt }) } } ``` Here, we have included the constructor function as our first example of how to execute asynchronous methods in a non-async context. We do this using the [`block_on`] method on the Tokio [`Runtime`] type, which executes an asynchronous method and returns its result. One important detail is the use of the [`current_thread`] runtime. Usually when using Tokio, you would be using the default [`multi_thread`] runtime, which will spawn a bunch of background threads so it can efficiently run many things at the same time. For our use-case, we are only going to be doing one thing at the time, so we won't gain anything by running multiple threads. This makes the [`current_thread`] runtime a perfect fit as it doesn't spawn any threads. The [`enable_all`] call enables the IO and timer drivers on the Tokio runtime. If they are not enabled, the runtime is unable to perform IO or timers. > **warning** > Because the `current_thread` runtime does not spawn threads, it only operates > when `block_on` is called. Once `block_on` returns, all spawned tasks on that > runtime will freeze until you call `block_on` again. Use the `multi_threaded` > runtime if spawned tasks must keep running when not calling `block_on`. Once we have this struct, most of the methods are easy to implement: ```rs use bytes::Bytes; use std::time::Duration; impl BlockingClient { pub fn get(&mut self, key: &str) -> crate::Result