Enhance Turnkey CLI: Implement A Real-Time Logs Panel

by TheNnagam 54 views

Hey guys! Today, we're diving deep into a crucial enhancement for the Turnkey CLI: implementing a real-time logs panel. This feature is designed to significantly improve the development and debugging experience by providing developers with immediate insights into the emulator's activity. Let's break down why this is important, what it entails, and how it's going to make your lives easier.

Feature Description

The primary goal here is to create a scrollable logs panel that displays real-time event logs, access attempts, protocol messages, and system status updates. This component will be a game-changer for monitoring emulator activity and debugging access control integrations. Imagine having all the vital information right at your fingertips!

Problem Statement

During the development and testing phases, developers often face several challenges that this logs panel aims to address. Real-time event streams are essential for understanding what's happening as it happens. This includes seeing access requests, grants, and denials in real-time. Monitoring protocol message exchanges, such as TCP send and receive operations, is also crucial for ensuring smooth communication. Debugging validation logic becomes much easier when you can see exactly why access was denied. Tracking device state changes, like online/offline status and configuration updates, helps maintain a clear understanding of the system's current state. Finally, reviewing historical events during a session is vital for identifying patterns and troubleshooting issues.

Currently, developers have to rely on terminal output or log files, which can be less convenient and more time-consuming. A dedicated logs panel streamlines this process by centralizing all relevant information in one place, making debugging and monitoring significantly more efficient. Without such a panel, developers spend unnecessary time sifting through disparate sources of information, hindering their productivity and slowing down the development cycle. This improvement not only saves time but also reduces the frustration associated with diagnosing complex issues.

Moreover, the logs panel fosters a more proactive approach to development. By having real-time visibility into system operations, developers can quickly identify and address potential problems before they escalate. This leads to more stable and reliable software, ultimately enhancing the user experience. In essence, the logs panel is a critical tool for maintaining the health and performance of the Turnkey CLI, ensuring that developers have the insights they need to create robust and efficient applications.

Proposed Solution

Our proposed solution is to create a Logs Panel component using ratatui that addresses all the needs outlined above. Here's a detailed look at what this component will include:

  1. Scrollable Event Log Display:

    • Newest events will appear at the bottom, mimicking a chat-style interface for easy readability.
    • Auto-scroll functionality ensures that the display automatically updates when new events arrive, keeping you in the loop without manual intervention.
    • Manual scrolling with Up/Down arrows allows you to navigate through historical logs to examine past events in detail.
    • A scroll indicator will visually represent your current position within the log, providing context and orientation as you scroll.
  2. Color-Coded Log Levels:

    • INFO: White text for routine events, providing a clean and unobtrusive display for regular activity.
    • SUCCESS: Green text to highlight successful operations, making it easy to spot positive outcomes.
    • WARNING: Yellow text to draw attention to potential issues or non-critical errors that require attention.
    • ERROR: Red text to immediately flag critical errors that need urgent investigation and resolution.
    • DEBUG: Gray text for detailed protocol messages, offering a deeper level of insight for advanced debugging.
  3. Timestamp Formatting:

    • Show timestamp for each log entry to provide a clear timeline of events.
    • Format: [HH:MM:SS] or [HH:MM:SS.mmm] for debug mode, offering flexibility in time precision based on the level of detail required.
    • Relative timestamps (e.g., "2s ago") as an option, allowing for quick and intuitive understanding of event recency.
  4. Log Filtering:

    • Filter by log level to show only errors or warnings, allowing you to focus on the most critical issues.
    • Filter by event type to isolate specific categories of events, such as access-related or protocol-related logs.
    • A search function will be added as a future enhancement, enabling you to quickly find specific log entries based on keywords or patterns.
  5. Performance Optimization:

    • A ring buffer for log storage will limit the number of stored entries (e.g., max 1000 entries), preventing excessive memory usage.
    • Efficient rendering will ensure that only visible rows are rendered, minimizing the performance impact on the application.
    • Log rotation will automatically remove the oldest entries when the buffer is full, maintaining a manageable log size.

This comprehensive solution aims to provide developers with a powerful and efficient tool for monitoring and debugging the Turnkey CLI, enhancing productivity and ensuring a smoother development process.

Alternatives Considered

Before settling on the proposed solution, we considered a few alternatives:

  • Separate log file: While this is a common approach, it's less convenient for real-time monitoring. You'd have to constantly switch between the application and the log file, which can be cumbersome.
  • Full-screen log view: This would take up too much screen space and disrupt the workflow. We wanted a solution that's integrated and doesn't dominate the interface.
  • No logs: This would make debugging extremely difficult. We need a way to see what's happening under the hood.

Use Case

To illustrate the benefits of the Logs Panel, here are a few scenarios:

Scenario 1: Monitor Access Attempts

[14:30:00] INFO  Device online, waiting for access
[14:30:05] INFO  Card read: 00000000000011912322
[14:30:05] INFO  Sending access request to server
[14:30:06] SUCCESS Access granted: JoΓ£o Silva
[14:30:07] INFO  Rotation completed
[14:30:08] INFO  Returned to idle state

Scenario 2: Debug Access Denial

[14:31:00] INFO  Card read: 99999999999999999999
[14:31:00] INFO  Sending access request
[14:31:01] WARNING Access denied: Unknown user
[14:31:01] DEBUG Server response: 01+REON+00+30]0]Acesso negado]
[14:31:02] INFO  Displayed denial message for 3s

Scenario 3: Track Protocol Errors

[14:32:00] INFO  TCP connection established: 192.168.0.100:3000
[14:32:05] ERROR Connection lost: timeout
[14:32:06] INFO  Attempting reconnect...
[14:32:08] INFO  Reconnected successfully

Implementation Notes

Here are some technical details for the implementation:

Affected Crates:

  • turnkey-cli

Files to Create:

  • turnkey-cli/src/tui/components/logs.rs

Files to Modify:

  • turnkey-cli/src/tui/mod.rs (add logs module)

Key Types:

pub enum LogLevel {
    Debug,
    Info,
    Success,
    Warning,
    Error,
}

pub struct LogEntry {
    pub timestamp: DateTime<Local>,
    pub level: LogLevel,
    pub message: String,
}

pub struct LogsPanel {
    entries: VecDeque<LogEntry>,
    max_entries: usize,
    scroll_offset: usize,
    auto_scroll: bool,
    filter_level: Option<LogLevel>,
}

impl LogsPanel {
    pub fn new(max_entries: usize) -> Self;
    pub fn add_log(&mut self, level: LogLevel, message: impl Into<String>);
    pub fn scroll_up(&mut self);
    pub fn scroll_down(&mut self);
    pub fn toggle_auto_scroll(&mut self);
    pub fn set_filter(&mut self, level: Option<LogLevel>);
}

impl Widget for LogsPanel {
    fn render(self, area: Rect, buf: &mut Buffer);
}

Rendering Approach:

fn render(self, area: Rect, buf: &mut Buffer) {
    let block = Block::default()
        .title("πŸ“‹ LOGS")
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Cyan));

    let inner = block.inner(area);
    block.render(area, buf);

    let visible_entries = self.entries
        .iter()
        .skip(self.scroll_offset)
        .take(inner.height as usize);

    for (i, entry) in visible_entries.enumerate() {
        let style = match entry.level {
            LogLevel::Info => Style::default().fg(Color::White),
            LogLevel::Success => Style::default().fg(Color::Green),
            LogLevel::Warning => Style::default().fg(Color::Yellow),
            LogLevel::Error => Style::default().fg(Color::Red),
            LogLevel::Debug => Style::default().fg(Color::Gray),
        };

        let timestamp = entry.timestamp.format("[%H:%M:%S]");
        let line = format!("{} {}", timestamp, entry.message);

        // Render log line
    }
}

Testing Requirements:

  • Unit tests for log entry addition
  • Unit tests for ring buffer rotation
  • Unit tests for scroll operations
  • Unit tests for log filtering
  • Integration test with app event loop

Priority: Medium (depends on Issue #27) Effort: Medium (1 day)

Acceptance Criteria:

  • [ ] Logs panel renders scrollable list
  • [ ] New log entries added at bottom
  • [ ] Auto-scroll to newest entry works
  • [ ] Manual scroll with Up/Down arrows
  • [ ] Scroll indicator shows position
  • [ ] Timestamps displayed in [HH:MM:SS] format
  • [ ] Color-coded log levels (Info, Success, Warning, Error, Debug)
  • [ ] Ring buffer limits to max 1000 entries
  • [ ] Log filtering by level works
  • [ ] All unit tests passing

Additional Context

Visual Example:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           πŸ“‹ LOGS               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ [14:30:00] Device boot complete β”‚
β”‚ [14:30:01] TCP connected        β”‚
β”‚ [14:30:05] Card read OK         β”‚
β”‚ [14:30:06] Access granted βœ“     β”‚
β”‚ [14:30:07] Rotation done        β”‚
β”‚ [14:30:08] Idle                 β”‚
β”‚ [14:31:00] Access denied βœ—      β”‚
β”‚ [14:31:05] Timeout              β”‚
β”‚                                 β”‚
β”‚ [β–²] More above (10/50)          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Keyboard Controls:

  • Up Arrow: Scroll up one line
  • Down Arrow: Scroll down one line
  • Page Up: Scroll up one page
  • Page Down: Scroll down one page
  • Home: Jump to oldest entry
  • End: Jump to newest entry
  • 'a': Toggle auto-scroll

Log Level Icons:

  • β„Ή INFO (white)
  • βœ“ SUCCESS (green)
  • ⚠ WARNING (yellow)
  • βœ— ERROR (red)
  • βš™ DEBUG (gray)

Performance Considerations:

  • Only render visible lines (viewport optimization)
  • Use VecDeque for efficient front/back operations
  • Limit stored entries to prevent memory growth
  • Batch log additions to reduce render calls

Related Documentation:

  • /docs/tui-specification.md - Section "Logs Panel Component"
  • /docs/emulator-modes.md - Event logging during access flows

By implementing this logs panel, we're setting the stage for a more efficient, transparent, and enjoyable development experience. Keep coding, and stay tuned for more updates!