-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
priority:mediumMedium priority issueMedium priority issuestatus:reviewUnder reviewUnder reviewtype:enhancementNew feature or requestNew feature or request
Description
Problem / Background
When ERROR or WARN level logs occur during TUI mode execution, the log messages are printed directly to the screen, breaking the ratatui alternate screen layout.
Current State Analysis
- TUI Mode: Runs on ratatui's alternate screen in
src/ui/tui/mod.rs - Logging Implementation: Uses
tracing_subscriber::fmt()insrc/utils/logging.rsto output directly to stdout - Log Usage:
error!(),warn!()macros used interminal_guard.rsand many other files - Scope: 59 files use tracing throughout the codebase
Steps to Reproduce
- Execute command in TUI mode (
bssh -c cluster "command") - Trigger an error situation such as connection error or timeout
- Error logs are printed directly over the TUI screen, breaking the layout
Proposed Solution
Step 1: Create TUI-dedicated In-memory Log Buffer
// src/ui/tui/log_buffer.rs (new)
use std::collections::VecDeque;
use tracing::Level;
pub struct LogEntry {
pub level: Level,
pub target: String,
pub message: String,
pub timestamp: chrono::DateTime<chrono::Local>,
}
pub struct LogBuffer {
entries: VecDeque<LogEntry>,
max_entries: usize,
}
impl LogBuffer {
pub fn new(max_entries: usize) -> Self {
Self {
entries: VecDeque::with_capacity(max_entries),
max_entries,
}
}
pub fn push(&mut self, entry: LogEntry) {
if self.entries.len() >= self.max_entries {
self.entries.pop_front();
}
self.entries.push_back(entry);
}
pub fn iter(&self) -> impl Iterator<Item = &LogEntry> {
self.entries.iter()
}
}Step 2: Implement Custom tracing Layer
// src/ui/tui/log_layer.rs (new)
use std::sync::Arc;
use parking_lot::Mutex;
use tracing_subscriber::Layer;
pub struct TuiLogLayer {
buffer: Arc<Mutex<LogBuffer>>,
}
impl<S> Layer<S> for TuiLogLayer
where
S: tracing::Subscriber,
{
fn on_event(
&self,
event: &tracing::Event<'_>,
_ctx: tracing_subscriber::layer::Context<'_, S>,
) {
// Create LogEntry and add to buffer
}
}Step 3: Add Log Panel to TUI Layout
┌──────────────────────────────────────────────────────────┐
│ Cluster: production - command │
│ Total: 8 • ✓ 3 • ✗ 1 • 4 in progress │
├──────────────────────────────────────────────────────────┤
│ │
│ (Main content area) │
│ │
├──────────────────────────────────────────────────────────┤
│ [ERROR] Connection timeout: node3 (10.0.0.3:22) │ <- Log panel (toggleable)
│ [WARN] Slow response from node5 │
└──────────────────────────────────────────────────────────┘
│ [l] Log [1-9] Detail [s] Split [q] Quit [?] Help │
Step 4: Add Log-related Fields to TuiApp State
// src/ui/tui/app.rs modification
pub struct TuiApp {
// Existing fields...
// New log-related fields
pub log_buffer: Arc<Mutex<LogBuffer>>,
pub log_panel_visible: bool,
pub log_panel_height: u16, // Default: 3 lines
pub log_scroll_offset: usize,
}Acceptance Criteria
- Implement
LogBufferstruct (max 1000 entries, configurable) - Implement
TuiLogLayertracing layer - Auto-register log layer when entering TUI mode
- Remove log layer and restore stdout output when exiting TUI mode
- Implement log panel UI component (
src/ui/tui/views/log_panel.rs) - Implement
lkey to toggle log panel visibility - Color-code by log level:
- ERROR: Red (
Color::Red) - WARN: Yellow (
Color::Yellow) - INFO: White (
Color::White) - DEBUG: Gray (
Color::DarkGray)
- ERROR: Red (
- Support log panel scrolling (
j/kor arrow keys) - Adjustable log panel height (3-10 lines)
- Add log-related keybindings to help overlay
Technical Considerations
Dependencies
- Utilize
tracing_subscriber::Layertrait (no additional dependencies needed) - Consider using
parking_lot::Mutex(existingstd::sync::Mutexalso works)
Synchronization
LogBufferis shared between tracing layer and TUI rendering thread- Use
Arc<Mutex<LogBuffer>>pattern - Minimize lock acquisition time during rendering (copy only necessary data)
Memory Protection
- Limit maximum log entries (default: 1000)
- Auto-delete old logs in FIFO manner
- Configurable via environment variable (
BSSH_TUI_LOG_MAX_ENTRIES)
Compatibility
- Maintain existing stdout logging when not in TUI mode
- Preserve existing behavior with
--no-tuior pipe connections
Additional Context
- Related issue: feat: Implement real-time streaming output with interactive multi-node UI #68 (TUI streaming output implementation)
- Affected files:
src/ui/tui/,src/utils/logging.rs - Reference: Can utilize log viewer pattern from ratatui official examples
Future Improvements
- Log filtering functionality (by level, keyword search)
- Log copy/export functionality
- Log timestamp display option
- Log panel pin mode (disable auto-scroll)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
priority:mediumMedium priority issueMedium priority issuestatus:reviewUnder reviewUnder reviewtype:enhancementNew feature or requestNew feature or request