async_inspect/integrations/tokio_console.rs
1//! Tokio Console integration guide
2//!
3//! This module provides guidance on using async-inspect alongside tokio-console.
4//! Since tokio-console requires compile-time instrumentation, both tools can
5//! work side-by-side to provide complementary insights.
6
7//! # Using async-inspect with tokio-console
8//!
9//! ## Setup
10//!
11//! 1. Add tokio-console to your dependencies:
12//! ```toml
13//! [dependencies]
14//! console-subscriber = "0.2"
15//! tokio = { version = "1", features = ["tracing"] }
16//! ```
17//!
18//! 2. Initialize both in your application:
19//! ```rust,ignore
20//! use async_inspect::prelude::*;
21//!
22//! #[tokio::main]
23//! async fn main() {
24//! // Initialize tokio-console
25//! console_subscriber::init();
26//!
27//! // async-inspect works alongside automatically
28//! // Your traced tasks will be visible in both tools
29//!
30//! my_async_function().await;
31//! }
32//! ```
33//!
34//! ## Complementary Features
35//!
36//! ### Tokio Console provides:
37//! - Real-time task monitoring
38//! - Live task tree visualization
39//! - Poll times and wait times
40//! - Resource tracking
41//!
42//! ### async-inspect provides:
43//! - Historical trace export (JSON/CSV)
44//! - Relationship graph analysis
45//! - Deadlock detection
46//! - Performance profiling
47//! - Custom inspection points
48//!
49//! ## Best Practices
50//!
51//! 1. **Development**: Use tokio-console for real-time debugging
52//! 2. **Production**: Use async-inspect with sampling for minimal overhead
53//! 3. **Post-mortem**: Export async-inspect traces for offline analysis
54//! 4. **CI/CD**: Use async-inspect exports to detect performance regressions
55//!
56//! ## Environment Variables
57//!
58//! Both tools respect standard Rust tracing environment variables:
59//!
60//! ```bash
61//! # Enable tokio-console
62//! export RUSTFLAGS="--cfg tokio_unstable"
63//!
64//! # Set trace level
65//! export RUST_LOG=debug
66//! ```
67//!
68//! ## Example Configuration
69//!
70//! ```rust,ignore
71//! use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
72//!
73//! // Create a layered subscriber with both tokio-console and async-inspect
74//! tracing_subscriber::registry()
75//! .with(console_subscriber::spawn()) // tokio-console
76//! .with(async_inspect::integrations::tracing_layer::AsyncInspectLayer::new())
77//! .init();
78//! ```
79
80use std::fmt;
81
82/// Configuration for using async-inspect with tokio-console
83#[derive(Debug, Clone)]
84pub struct ConsoleIntegrationConfig {
85 /// Enable tokio-console compatibility mode
86 pub console_compatible: bool,
87 /// Filter tasks to reduce noise in console
88 pub filter_short_tasks: bool,
89 /// Minimum task duration to show (ms)
90 pub min_duration_ms: u64,
91}
92
93impl Default for ConsoleIntegrationConfig {
94 fn default() -> Self {
95 Self {
96 console_compatible: true,
97 filter_short_tasks: true,
98 min_duration_ms: 10,
99 }
100 }
101}
102
103impl fmt::Display for ConsoleIntegrationConfig {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(
106 f,
107 "ConsoleIntegration {{ compatible: {}, filter: {}, min_ms: {} }}",
108 self.console_compatible, self.filter_short_tasks, self.min_duration_ms
109 )
110 }
111}
112
113/// Check if tokio-console is likely active
114#[must_use]
115pub fn is_console_active() -> bool {
116 std::env::var("RUSTFLAGS")
117 .map(|flags| flags.contains("tokio_unstable"))
118 .unwrap_or(false)
119}
120
121/// Print integration status and recommendations
122pub fn print_integration_info() {
123 println!("╔════════════════════════════════════════════════════════════╗");
124 println!("║ async-inspect + tokio-console Integration ║");
125 println!("╚════════════════════════════════════════════════════════════╝\n");
126
127 if is_console_active() {
128 println!("✅ tokio-console appears to be active");
129 println!(" Both tools will work together seamlessly!\n");
130 } else {
131 println!("ℹ️ tokio-console not detected");
132 println!(" To enable: RUSTFLAGS=\"--cfg tokio_unstable\" cargo run\n");
133 }
134
135 println!("📊 Tool Comparison:");
136 println!("┌─────────────────────┬──────────────┬──────────────┐");
137 println!("│ Feature │ tokio-console│ async-inspect│");
138 println!("├─────────────────────┼──────────────┼──────────────┤");
139 println!("│ Real-time monitoring│ ✅ │ ✅ │");
140 println!("│ Historical export │ ❌ │ ✅ │");
141 println!("│ Graph analysis │ ❌ │ ✅ │");
142 println!("│ Deadlock detection │ ❌ │ ✅ │");
143 println!("│ Production ready │ ❌ │ ✅ │");
144 println!("│ Zero overhead │ ❌ │ ✅ (opt) │");
145 println!("└─────────────────────┴──────────────┴──────────────┘\n");
146
147 println!("💡 Recommendations:");
148 println!(" • Development: Use tokio-console for live debugging");
149 println!(" • Production: Use async-inspect with sampling");
150 println!(" • CI/CD: Compare async-inspect exports");
151 println!(" • Post-mortem: Analyze exported JSON/CSV traces\n");
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn test_config() {
160 let config = ConsoleIntegrationConfig::default();
161 assert!(config.console_compatible);
162 }
163}