A feature rich TUI JSON log file viewer
Project description
Juffi - JSON Log Viewer
A feature-rich Terminal User Interface (TUI) for viewing and analyzing JSON log files with ease.
Why Juffi?
JSON logs are powerful but painful to read in their raw format. Compare these two views of the same log data:
Without Juffi
{"timestamp":"2024-01-15T10:23:45.123Z","level":"INFO","message":"User login successful","user_id":"user_12345","ip":"192.168.1.100","session_id":"abc-def-ghi","service":"auth-service"}
{"timestamp":"2024-01-15T10:23:46.456Z","level":"WARN","message":"High memory usage detected","memory_percent":85.3,"process":"api-server","service":"monitoring"}
{"timestamp":"2024-01-15T10:23:47.789Z","level":"ERROR","message":"Database connection timeout","db_host":"db-primary.example.com","retry_count":3,"error":"connection timeout after 30s","service":"database"}
{"timestamp":"2024-01-15T10:23:48.012Z","level":"INFO","message":"API request received","method":"POST","path":"/api/v1/users","response_time_ms":45,"status_code":200,"service":"api-gateway"}
{"timestamp":"2024-01-15T10:23:49.234Z","level":"DEBUG","message":"Cache hit","cache_key":"user:12345:profile","ttl_seconds":3600,"service":"cache-service"}
{"timestamp":"2024-01-15T10:23:50.567Z","level":"INFO","message":"Payment processed","amount":99.99,"currency":"USD","transaction_id":"txn_abc123","user_id":"user_12345","service":"payment-service"}
{"timestamp":"2024-01-15T10:23:51.890Z","level":"WARN","message":"Rate limit approaching","current_requests":950,"limit":1000,"window_seconds":60,"ip":"192.168.1.100","service":"rate-limiter"}
{"timestamp":"2024-01-15T10:23:52.123Z","level":"ERROR","message":"Failed to send email","recipient":"user@example.com","error":"SMTP connection refused","retry_attempt":2,"service":"email-service"}
{"timestamp":"2024-01-15T10:23:53.456Z","level":"INFO","message":"File uploaded successfully","filename":"document.pdf","size_bytes":1048576,"user_id":"user_67890","service":"storage-service"}
{"timestamp":"2024-01-15T10:23:54.789Z","level":"DEBUG","message":"SQL query executed","query":"SELECT * FROM users WHERE id = ?","duration_ms":12,"rows_affected":1,"service":"database"}
{"timestamp":"2024-01-15T10:23:55.012Z","level":"INFO","message":"User logout","user_id":"user_12345","session_duration_seconds":1800,"service":"auth-service"}
{"timestamp":"2024-01-15T10:23:56.345Z","level":"WARN","message":"Slow query detected","query":"SELECT * FROM orders JOIN users","duration_ms":5000,"threshold_ms":1000,"service":"database"}
{"timestamp":"2024-01-15T10:23:57.678Z","level":"ERROR","message":"Authentication failed","user_id":"user_99999","reason":"invalid_credentials","ip":"10.0.0.50","service":"auth-service"}
{"timestamp":"2024-01-15T10:23:58.901Z","level":"INFO","message":"Background job completed","job_id":"job_456","job_type":"data_export","duration_seconds":120,"service":"worker"}
{"timestamp":"2024-01-15T10:23:59.234Z","level":"DEBUG","message":"WebSocket connection established","client_id":"ws_client_789","protocol":"wss","service":"websocket-server"}
{"timestamp":"2024-01-15T10:24:00.567Z","level":"INFO","message":"Metrics published","metric_count":150,"destination":"prometheus","service":"metrics-collector"}
{"timestamp":"2024-01-15T10:24:01.890Z","level":"WARN","message":"Disk space low","available_gb":5.2,"total_gb":100,"threshold_percent":10,"mount_point":"/data","service":"monitoring"}
{"timestamp":"2024-01-15T10:24:02.123Z","level":"ERROR","message":"External API timeout","api":"payment-gateway","endpoint":"/charge","timeout_seconds":30,"service":"integration"}
{"timestamp":"2024-01-15T10:24:03.456Z","level":"INFO","message":"Cache cleared","cache_type":"redis","keys_deleted":1500,"service":"cache-service"}
{"timestamp":"2024-01-15T10:24:04.789Z","level":"DEBUG","message":"Request validation passed","endpoint":"/api/v1/orders","validation_time_ms":5,"service":"api-gateway"}
{"timestamp":"2024-01-15T10:24:05.012Z","level":"INFO","message":"Scheduled task started","task_name":"daily_backup","schedule":"0 2 * * *","service":"scheduler"}
{"timestamp":"2024-01-15T10:24:06.345Z","level":"WARN","message":"Connection pool exhausted","pool_size":50,"active_connections":50,"waiting_requests":10,"service":"database"}
{"timestamp":"2024-01-15T10:24:07.678Z","level":"ERROR","message":"Message queue full","queue_name":"notifications","current_size":10000,"max_size":10000,"service":"message-queue"}
{"timestamp":"2024-01-15T10:24:08.901Z","level":"INFO","message":"Health check passed","endpoint":"/health","response_time_ms":2,"status":"healthy","service":"api-gateway"}
{"timestamp":"2024-01-15T10:24:09.234Z","level":"DEBUG","message":"Token refreshed","user_id":"user_12345","token_type":"JWT","expires_in_seconds":3600,"service":"auth-service"}
With Juffi
Features
🔍 Smart Log Viewing
- Automatic column detection - Juffi analyzes your JSON logs and creates columns for all fields
- Tabular display - View logs in a clean, organized table format
- Details view - Dive deep into individual log entries with full JSON expansion
📊 Powerful Filtering & Search
- Column filtering - Filter by any column to focus on relevant entries
- Global search - Search across all fields simultaneously
- Clear filters - Easily reset filters to start fresh
🎯 Column Management
- Sortable columns - Sort by any column (ascending or descending)
- Reorderable columns - Arrange columns in the order that makes sense to you
- Adjustable widths - Resize columns to fit your data
- Column management screen - Hide/show columns as needed
📡 Real-time Monitoring
- Follow mode - Like
tail -f, automatically show new log entries as they're written - Live reload - Refresh the view to pick up new entries
- Responsive updates - Smooth scrolling and navigation even with large files
Installation
From PyPI (Recommended)
pip install juffi
From Source
git clone https://github.com/YotamAlon/juffi.git
cd juffi
pip install -e .
Quick Start
Basic Usage
juffi app.log
Requirements
- Python 3.11 or higher
- Terminal with curses support (most Unix-like systems)
- No external dependencies required
Use Cases
Juffi is perfect for:
- Debugging - Quickly find errors and warnings in application logs
- Monitoring - Watch logs in real-time with follow mode
- Analysis - Sort and filter logs to identify patterns
- Development - Review structured logging output during development
- Operations - Investigate production issues with powerful search and filtering
Technical Details
Architecture
Juffi follows a clean MVVM (Model-View-ViewModel) architecture:
- Models (
juffi/models/) - Data structures and business logic - ViewModels (
juffi/viewmodels/) - Presentation logic and state management - Views (
juffi/views/) - UI rendering using Python's curses library - Input Controller (
juffi/input_controller.py) - Handles file reading and input streaming
Project Structure
juffi/
├── juffi/
│ ├── __main__.py # Entry point
│ ├── input_controller.py # File input handling
│ ├── models/ # Data models
│ ├── viewmodels/ # Presentation logic
│ ├── views/ # UI components
│ └── helpers/ # Utility functions
├── tests/ # Test suite
├── pyproject.toml # Project configuration
└── README.md
Building from Source
Prerequisites
# Install development dependencies
pip install -e ".[dev]"
Build
# Build wheel and source distribution
make build
# Or building a wheel
make wheel
Testing
# Run tests
make test
# Run tests with coverage
make coverage
# Run linter
make lint
Development Setup
-
Clone the repository
git clone https://github.com/YotamAlon/juffi.git cd juffi
-
Create virtual environment
python -m venv .venv source .venv/bin/activate
-
Install in development mode
pip install -e ".[dev]"
-
Install pre-commit hooks
pre-commit install
Code Quality
The project uses:
- Black - Code formatting
- isort - Import sorting
- mypy - Type checking
- pylint - Linting
- pytest - Testing
All checks run automatically via pre-commit hooks.
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Author
Yotam Alon - yotam.alon@gmail.com
Links
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file juffi-0.3.0.tar.gz.
File metadata
- Download URL: juffi-0.3.0.tar.gz
- Upload date:
- Size: 44.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b2076a1379ccb14bcd10d9a03239ae72c561c12ea231b7ddc0948a24586fe85
|
|
| MD5 |
92b6c7eba85c2face51abbb25b973013
|
|
| BLAKE2b-256 |
44509d70346433e65a4be2953279be189f0ed755d3030609870bae1939801758
|
File details
Details for the file juffi-0.3.0-py3-none-any.whl.
File metadata
- Download URL: juffi-0.3.0-py3-none-any.whl
- Upload date:
- Size: 47.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9c6dc666ed089f1845edec7373b9e470f5ec9a0fe7969968be4258a2380109a
|
|
| MD5 |
c06d2ce1f283078560efb236a4ae9749
|
|
| BLAKE2b-256 |
bbb24e4d058881a50734aafc6dbb9f09fef95ebdadf3fb3d295b67dc61fff8b1
|