Debug Panel Documentation
The Speakr debug panel is a development-only interface that provides debugging tools and testing capabilities. It's designed to help developers test features, monitor system behaviour, and troubleshoot issues during development.
Overview
The debug panel is only available in debug builds (cargo tauri dev
) and is completely excluded from release builds for security and performance reasons. It provides a comprehensive debugging interface with real-time logging, feature testing, and system monitoring capabilities.
Accessing the Debug Panel
Availability
- Debug builds only: The panel is conditionally compiled using
#[cfg(debug_assertions)]
- Toggle button: A red "🛠️ Debug" button appears in the header (debug builds only)
- Visual indicator: The panel shows a "DEBUG BUILD" badge to remind developers of the build type
Navigation
- Start the application in debug mode:
cargo tauri dev
- Look for the "🛠️ Debug" button in the top-right corner of the header
- Click to toggle between the settings panel and debug panel
- The button text changes to "🛠️ Hide Debug" when the panel is active
Features
1. Audio Testing
Legacy Test Button
- Purpose: Basic audio system testing
- Behaviour: Click to run a simple audio recording test
- Feedback: Shows progress in the debug output area
Push-to-Talk Recording
- Purpose: Test real-time audio recording with push-to-talk interaction
- Behaviour:
- Hold the button to start recording
- Release to stop recording
- Supports both mouse and touch events
- Visual feedback:
- Button changes colour and shows pulsing animation when recording
- Text updates to show current state
- Recording state is displayed in system info
2. Logging Console
Real-time Log Display
- Scrolling console: Shows recent log messages from the backend
- Auto-scroll: Automatically scrolls to show newest messages (toggleable)
- Timestamp: Each message includes precise timestamp
- Source tracking: Shows which component generated each log message
Log Level Filtering
- Dropdown filter: Filter by specific log levels (TRACE, DEBUG, INFO, WARN, ERROR)
- Visual indicators: Each level has distinct emoji icons and colours
- Level-specific styling: Error and warning messages have highlighted backgrounds
Console Controls
- Refresh: Manually refresh log messages from backend
- Clear: Clear all log messages from display and backend storage
- Auto-scroll toggle: Enable/disable automatic scrolling to newest messages
3. System Information
Real-time display of:
- Build type: Always shows "Debug" in debug panel
- Environment: Shows "Development"
- Recording state: Live status of audio recording (Active/Inactive)
Technical Implementation
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Frontend │ │ Backend │ │ Log Storage │
│ (Leptos) │ │ (Tauri) │ │ (Memory) │
├─────────────────┤ ├──────────────────┤ ├─────────────────┤
│ DebugPanel │◄──►│ debug_* commands │◄──►│ DEBUG_LOG_ │
│ LoggingConsole │ │ add_debug_log() │ │ MESSAGES │
│ Push-to-talk UI │ │ Log collection │ │ (VecDeque) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
Conditional Compilation
The debug panel uses Rust's conditional compilation to ensure it's only included in debug builds:
#![allow(unused)] fn main() { #[cfg(debug_assertions)] mod debug; #[cfg(debug_assertions)] use crate::debug::DebugPanel; }
Backend Commands
All debug commands are prefixed with debug_
and conditionally compiled:
debug_test_audio_recording()
- Legacy audio testdebug_start_recording()
- Start push-to-talk recordingdebug_stop_recording()
- Stop push-to-talk recordingdebug_get_log_messages()
- Retrieve stored log messagesdebug_clear_log_messages()
- Clear log message storage
Log Message Storage
Debug logs are stored in memory using a thread-safe circular buffer:
#![allow(unused)] fn main() { static DEBUG_LOG_MESSAGES: LazyLock<Arc<Mutex<VecDeque<DebugLogMessage>>>> = LazyLock::new(|| Arc::new(Mutex::new(VecDeque::with_capacity(1000)))); }
Key characteristics:
- Capacity: Limited to 1000 messages (prevents memory bloat)
- Thread-safe: Uses
Arc<Mutex<>>
for concurrent access - Circular buffer: Automatically removes old messages when capacity is reached
- Structured data: Each message includes timestamp, level, target, and content
Event Handling
Push-to-talk functionality uses multiple event handlers for robust interaction:
#![allow(unused)] fn main() { on:mousedown=move |_| start_recording() on:mouseup=move |_| stop_recording() on:mouseleave=move |_| stop_recording() // Handles mouse leaving button area on:touchstart=move |_| start_recording() on:touchend=move |_| stop_recording() }
Development Patterns
Adding New Debug Features
-
Backend Command:
#![allow(unused)] fn main() { #[cfg(debug_assertions)] #[tauri::command] async fn debug_your_feature() -> Result<String, AppError> { add_debug_log(DebugLogLevel::Info, "your-component", "Feature tested"); // Your implementation Ok("Success message".to_string()) } }
-
Frontend Integration:
#![allow(unused)] fn main() { impl DebugManager { pub async fn test_your_feature() -> Result<String, String> { tauri_invoke_no_args("debug_your_feature") .await .map_err(|e| format!("Failed to test feature: {e}")) } } }
-
UI Component:
#![allow(unused)] fn main() { <button class="debug-btn-primary" on:click=move |_| test_your_feature() > "Test Your Feature" </button> }
-
Register Command:
#![allow(unused)] fn main() { // Add to debug build handler list debug_your_feature, }
Logging Best Practices
-
Use appropriate log levels:
Trace
: Detailed execution flowDebug
: Development informationInfo
: General informationWarn
: Potential issuesError
: Actual errors
-
Include context:
#![allow(unused)] fn main() { add_debug_log( DebugLogLevel::Info, "component-name", &format!("Action completed with result: {}", result) ); }
-
Target naming:
- Use consistent component names
- Follow pattern:
speakr-{component}
(e.g.,speakr-core
,speakr-tauri
)
Testing Debug Features
Debug features should be tested like any other code:
#![allow(unused)] fn main() { #[test] fn test_debug_manager_methods_exist() { // Compile-time test for method signatures let _fn: fn() -> _ = DebugManager::test_your_feature; assert!(true, "Debug method exists and compiles"); } }
Security Considerations
Build-time Exclusion
- Debug panel code is completely removed from release builds
- No performance impact on production builds
- No security surface area in release builds
Development-only Data
- Log messages are stored only in memory
- No persistent storage of debug information
- Automatic cleanup when application closes
Safe Defaults
- Mock implementations prevent accidental system access
- All debug commands return safe, predictable responses
- Clear visual indicators remind developers of debug mode
Troubleshooting
Debug Panel Not Visible
- Check build type: Ensure you're running
cargo tauri dev
, not a release build - Look for button: The toggle button appears in the header, not as a separate window
- Browser cache: If using
trunk serve
, clear browser cache and reload
Log Messages Not Appearing
- Click refresh: Use the "🔄 Refresh" button to manually fetch logs
- Check backend: Ensure debug commands are registered in the invoke handler
- Memory limit: Log storage is limited to 1000 messages; older messages are automatically removed
Push-to-Talk Not Working
- Hold, don't click: The button requires holding down, not just clicking
- Check events: Ensure mouse/touch events are properly handled
- Visual feedback: Look for button colour change and pulsing animation during recording
Future Enhancements
Potential additions to the debug panel:
- Performance Monitoring: CPU, memory usage graphs
- Network Activity: Mock API call testing
- State Inspection: Real-time application state viewer
- Configuration Testing: Dynamic settings modification
- Export Functionality: Save debug logs to file
- Remote Debugging: WebSocket connection for external debugging tools
Related Files
- Frontend:
speakr-ui/src/debug.rs
- Main debug panel implementation - Backend:
speakr-tauri/src/lib.rs
- Debug commands and log storage - Styles:
speakr-ui/styles.css
- Debug panel CSS styles - Types: Log message types and enums
- Tests: Unit tests for debug functionality
Contributing
When adding debug features:
- Follow the established patterns for conditional compilation
- Add appropriate logging with meaningful messages
- Include tests for new functionality
- Update this documentation with new features
- Ensure features work in both desktop and mobile layouts
The debug panel is a powerful development tool that should enhance the development experience while maintaining security and performance in production builds.