228 lines
7.9 KiB
Markdown
228 lines
7.9 KiB
Markdown
# Logging System Integration
|
|
|
|
## Overview
|
|
PyBusMonitor1553 integrates the `TkinterLogger` system from the `externals/python-tkinter-logger` submodule to provide comprehensive application logging with GUI display.
|
|
|
|
## Architecture
|
|
|
|
### Components
|
|
1. **TkinterLogger Module** (`externals/python-tkinter-logger/tkinter_logger.py`)
|
|
- Thread-safe logging via Queue
|
|
- Tkinter widget integration
|
|
- Intelligent batching (70%+ overhead reduction)
|
|
- Adaptive polling (fast when active, slow when idle)
|
|
- Auto-scroll and line limit management
|
|
|
|
2. **GUI Integration** ([pybusmonitor1553/gui/main_window.py](../pybusmonitor1553/gui/main_window.py))
|
|
- ScrolledText widget at bottom of window (8 lines)
|
|
- Configured for 500-line history
|
|
- Color-coded log levels
|
|
- Read-only display
|
|
|
|
3. **Application Modules** (logging producers)
|
|
- [core/network.py](../pybusmonitor1553/core/network.py) - UDP connection events
|
|
- [core/dispatcher.py](../pybusmonitor1553/core/dispatcher.py) - Message parsing errors
|
|
- [core/scheduler.py](../pybusmonitor1553/core/scheduler.py) - Transmission events
|
|
|
|
## GUI Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ Menu Bar │
|
|
├──────────────┬──────────────────────────────────┤
|
|
│ │ │
|
|
│ Message │ Notebook Tabs: │
|
|
│ List │ - Message Detail │
|
|
│ (TreeView) │ - Radar Status │
|
|
│ │ - Raw Data │
|
|
│ │ │
|
|
├──────────────┴──────────────────────────────────┤
|
|
│ Application Log (ScrolledText) │
|
|
│ 15:36:10 [INFO] UDP Listening on 127.0.0.1... │
|
|
│ 15:36:10 [INFO] Multi-rate traffic started │
|
|
│ │
|
|
├──────────────────────────────────────────────────┤
|
|
│ Status Bar: ● Connected | TX: 123 | RX: 456 │
|
|
└──────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Logging Configuration
|
|
|
|
### Initialization
|
|
```python
|
|
# In main_window.py __init__()
|
|
self.logger_system = TkinterLogger(self.root)
|
|
self.logger_system.setup(
|
|
enable_console=True, # Also output to console
|
|
enable_tkinter=True, # Enable GUI widget
|
|
enable_file=False, # No file logging (optional)
|
|
log_format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
|
date_format='%H:%M:%S',
|
|
root_level=logging.INFO # Set minimum log level
|
|
)
|
|
|
|
# Attach to widget
|
|
self.logger_system.add_tkinter_handler(
|
|
self.log_text,
|
|
max_lines=500 # Keep last 500 lines
|
|
)
|
|
```
|
|
|
|
### Usage in Modules
|
|
```python
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Use standard Python logging
|
|
logger.info("UDP Listening on 127.0.0.1:61553")
|
|
logger.error("Error parsing MsgA1: invalid format")
|
|
logger.debug("Sent MsgA4 (SA 4)") # Only if root_level=DEBUG
|
|
```
|
|
|
|
## Log Levels and Color Coding
|
|
|
|
| Level | Color | Usage |
|
|
|----------|------------|------------------------------------------|
|
|
| DEBUG | Gray | Detailed packet dumps (if enabled) |
|
|
| INFO | Black | Normal operations (connection, startup) |
|
|
| WARNING | Orange | Non-critical issues (fallbacks) |
|
|
| ERROR | Red | Parsing errors, send failures |
|
|
| CRITICAL | Dark Red | Fatal errors requiring attention |
|
|
|
|
## Performance Optimizations
|
|
|
|
### Batching
|
|
- Logs buffered in Queue by background threads
|
|
- GUI processes up to 50 logs every 200ms
|
|
- Single widget enable/disable operation per batch
|
|
- Prevents GUI event overflow
|
|
|
|
### Adaptive Polling
|
|
```python
|
|
# From tkinter_logger.py
|
|
_poll_interval_ms = 200 # Base: 5Hz when active
|
|
# Slows to 1Hz when idle for 2 seconds
|
|
# Resumes fast polling when new logs arrive
|
|
```
|
|
|
|
### Memory Management
|
|
- Auto-trim to 500 lines (configurable)
|
|
- Prevents unbounded memory growth
|
|
- Old logs automatically discarded
|
|
|
|
### Smart Auto-Scroll
|
|
- Only scrolls to bottom if user was already there
|
|
- Preserves user scroll position when reviewing history
|
|
- Checks scroll position once per batch
|
|
|
|
## Module-Specific Logging
|
|
|
|
### Network Module ([core/network.py](../pybusmonitor1553/core/network.py#L1-L10))
|
|
```python
|
|
logger.info(f"UDP Listening on {self.rx_ip}:{self.rx_port}")
|
|
logger.error(f"Error starting UDP: {e}")
|
|
logger.info("UDP Stopped")
|
|
logger.debug(f"RX from {addr}: {hex_dump(data)}") # If DEBUG_PACKETS=True
|
|
```
|
|
|
|
### Dispatcher ([core/dispatcher.py](../pybusmonitor1553/core/dispatcher.py#L1-L8))
|
|
```python
|
|
logger.error(f"Error parsing {msg_class.__name__}: {e}")
|
|
```
|
|
|
|
### Scheduler ([core/scheduler.py](../pybusmonitor1553/core/scheduler.py#L1-L9))
|
|
```python
|
|
logger.info(f"Multi-rate traffic generation started ({mode} format, {BASE_TICK_HZ}Hz base tick)")
|
|
logger.info(f"Message rates: A1/A3/A7/A8/B6=6.25Hz, A2/B7=25Hz, A4/A5=50Hz")
|
|
logger.info("Traffic generation stopped")
|
|
logger.debug(f"Sent {msg_obj.__class__.__name__} (SA {msg_obj.SUBADDRESS})") # If not QUIET_MODE
|
|
```
|
|
|
|
### GUI Module ([gui/main_window.py](../pybusmonitor1553/gui/main_window.py#L19-L24))
|
|
```python
|
|
logger.info("Logging system initialized")
|
|
logger.info("PyBusMonitor1553 GUI initialized")
|
|
logger.info("Shutting down GUI...")
|
|
```
|
|
|
|
## Debug Flags Integration
|
|
|
|
Existing debug flags now use logging system:
|
|
|
|
| Module | Flag | Effect |
|
|
|------------|------------------|--------------------------------------|
|
|
| network.py | `DEBUG_PACKETS` | Hex dump via `logger.debug()` |
|
|
| scheduler.py | `DEBUG_PACKETS` | Packet hex dump via `logger.debug()` |
|
|
| scheduler.py | `QUIET_MODE` | Suppress per-message logs |
|
|
|
|
## Shutdown Sequence
|
|
|
|
```python
|
|
# In main_window.py
|
|
def shutdown(self):
|
|
logging.getLogger(__name__).info("Shutting down GUI...")
|
|
if self.logger_system:
|
|
self.logger_system.shutdown()
|
|
|
|
# Registered on window close
|
|
root.protocol("WM_DELETE_WINDOW", on_closing)
|
|
```
|
|
|
|
Ensures all pending logs are flushed before exit.
|
|
|
|
## Future Enhancements
|
|
|
|
### File Logging (Optional)
|
|
```python
|
|
logger_system.setup(
|
|
enable_file=True,
|
|
file_path='logs/pybusmonitor.log',
|
|
file_max_bytes=5*1024*1024, # 5MB
|
|
file_backup_count=3 # Keep 3 rotated files
|
|
)
|
|
```
|
|
|
|
### Log Level Control
|
|
Add GUI menu to change log level at runtime:
|
|
```python
|
|
View → Log Level → DEBUG/INFO/WARNING/ERROR
|
|
```
|
|
|
|
### Log Export
|
|
Add button to save current log buffer to file:
|
|
```python
|
|
File → Export Log...
|
|
```
|
|
|
|
### Filtering
|
|
Add search/filter capabilities:
|
|
```python
|
|
# Filter by module name, level, or message content
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Logs Not Appearing in GUI
|
|
1. Check `TkinterLogger` import succeeded (no import error)
|
|
2. Verify `logger_system.setup()` was called
|
|
3. Ensure `add_tkinter_handler()` completed successfully
|
|
4. Check root logger level allows desired logs
|
|
|
|
### Console Logs Only
|
|
If GUI widget shows nothing but console shows logs:
|
|
- TkinterLogger may not be available (check imports)
|
|
- Widget may not be properly initialized
|
|
- Check for exceptions during `_setup_logging()`
|
|
|
|
### Performance Issues
|
|
If GUI becomes sluggish with logging:
|
|
- Reduce `root_level` to WARNING or ERROR
|
|
- Enable `QUIET_MODE` in scheduler
|
|
- Disable `DEBUG_PACKETS` in network/scheduler
|
|
- Reduce `max_lines` in widget handler
|
|
|
|
## References
|
|
- [TkinterLogger Documentation](../externals/python-tkinter-logger/TKINTER_LOGGER_README.md)
|
|
- [Python Logging Module](https://docs.python.org/3/library/logging.html)
|