lazylog-framework
A powerful, extensible framework for building terminal-based log viewers with vim-like navigation and real-time monitoring capabilities.
Features
- Provider-based architecture - Pluggable log sources
- Vim-like navigation - j/k, gg/G, Ctrl+d/u, and more
- Real-time streaming - Monitor logs as they arrive
- Filtering - Dynamic log filtering with
/search - Detail levels - Control information density (0-4)
- Mouse support - Click and scroll
- Modern UI - Clean interface with tailwind-inspired colors
- Clipboard integration - Yank logs with
y - Memory-efficient - Ring buffer prevents unbounded growth
Installation
[]
= "0.3"
Quick Start
use ;
use Result;
use Arc;
// 1. implement LogProvider for your log source
;
// 2. implement LogParser to format your logs
;
// 3. run the application
Architecture
The framework uses a two-trait system that separates log acquisition from parsing:
┌──────────────┐ poll_logs() ┌─────────────┐
│ LogProvider │ ─────────────────> │ Vec<String> │ (raw logs)
└──────────────┘ └──────┬──────┘
│
│ parse()
│
┌──────────────┐ format_preview() ┌────▼───────┐
│ LogParser │ <──────────────────│ LogItem │
└──────────────┘ └────────────┘
│ │
└──────────────┬───────────────────┘
│
↓
┌──────────────────┐
│ Ring Buffer │
│ (16K capacity) │
└─────────┬────────┘
│
↓
┌──────────────────┐
│ lazylog-framework│
│ - Rendering │
│ - Navigation │
│ - Filtering │
│ - UI management │
└─────────┬────────┘
│
↓
┌──────────┐
│ Terminal │
└──────────┘
Core Concepts
LogProvider Trait
Provides raw log data from any source (files, network, APIs, etc.):
Key points:
poll_logs()must be non-blocking - return empty vec if no logs available- Returns raw strings, not parsed
LogItems - Called repeatedly at configured interval (default: 100ms)
LogParser Trait
Parses raw strings and formats them for display:
LogItem Structure
Structured representation of a log entry:
Use the builder pattern to add metadata:
let log = new
.with_metadata
.with_metadata
.with_metadata;
Configuration
Customize behavior with AppDesc:
use Duration;
use ;
use Arc;
let parser = new;
let mut desc = new;
desc.poll_interval = from_millis; // poll every 50ms
desc.ring_buffer_size = 32768; // 32K log capacity
desc.show_debug_logs = true; // show debug panel
start_with_desc?;
Keybindings
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
g g |
Go to top |
G |
Go to bottom |
Ctrl+d |
Page down |
Ctrl+u |
Page up |
/ |
Enter filter mode |
Esc |
Clear filter / Exit filter mode |
a |
Toggle autoscroll (tail mode) |
+ |
Increase detail level |
- |
Decrease detail level |
w |
Toggle text wrapping |
y |
Yank (copy) selected log |
d |
Toggle debug logs |
? |
Show help |
1 / 2 / 3 |
Focus block 1/2/3 |
q |
Quit |
Detail Levels
Control how much information is displayed (0-4):
Your parser defines what each level shows via format_preview(). Common convention:
| Level | Description |
|---|---|
| 0 | Content only (minimal) |
| 1 | Time + content |
| 2 | Time + level + content |
| 3 | Time + level + module + content |
| 4 | All fields (maximum detail) |
Users can adjust levels with +/- keys to progressively reveal more information.
Examples
See the examples/ directory for complete working implementations:
Simple Example
Generate dummy logs to demonstrate basic usage:
File Tailing Example
Tail a log file (like tail -f):
# or generate test logs:
while ; do ; ; done
Structured JSON Example
Parse JSON logs with metadata and detail levels:
Advanced Examples
File-based Provider with Tailing
use File;
use ;
JSON Parser with Metadata
;
UDP Syslog Receiver
use UdpSocket;
Use Cases
- Application logs - Tail local log files
- Container logs - Monitor Docker/Kubernetes logs
- Syslog viewer - UDP/TCP syslog receiver
- Database logs - Stream from PostgreSQL, MongoDB, etc.
- API logs - Fetch from logging services (Elasticsearch, Loki, etc.)
- SSH logs - Remote log tailing via SSH
- Multi-source aggregator - Combine multiple log sources
- Device logs - Monitor mobile devices (iOS, Android)
- Custom protocols - Any streaming log source
Performance
- Memory-efficient: Ring buffer prevents unbounded growth (default: 16K items)
- Lock-free: Uses ringbuf crate for zero-allocation producer/consumer
- Lazy rendering: Only visible logs are formatted and drawn
- Parallel filtering: Uses rayon for fast regex filtering on large log sets
- Non-blocking: Provider runs in background thread, UI stays responsive
Requirements
- Rust 1.70+
- Terminal with ANSI color support
- For best experience: 256 colors, mouse support
Testing
The framework includes doctests for all public APIs. Run them with:
Documentation
Full API documentation is available at docs.rs/lazylog-framework.
Generate local documentation:
License
MIT OR Apache-2.0
Contributing
Contributions welcome! Please:
- Check existing issues or create one
- Fork and create a feature branch
- Add tests for new functionality
- Ensure
cargo testandcargo clippypass - Submit a pull request
Credits
Built with:
- ratatui - Terminal UI framework
- crossterm - Terminal manipulation
- ringbuf - Lock-free ring buffer
- regex - Regular expressions
- rayon - Parallel filtering
Related Projects
- lazylog - Reference implementation with file/iOS/Android providers