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}