From b9b2b7aced0aa423d504c1b00d96c10dbde7435e Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Thu, 18 Dec 2025 13:12:10 +0800 Subject: [PATCH] refactor: remove legacy Python code and optimize Rust implementation Removed all Python source files and build configuration. Refactored Rust code to remove unused modules (exporter) and fields. Updated README to man-page format. --- Cargo.toml | 1 - MANIFEST.in | 6 - README-rust.md | 320 ----------------------------------------- README.md | 207 +++++++++++++------------- RUST_MIGRATION.md | 58 -------- alert_system.py | 53 ------- config_manager.py | 50 ------- data_exporter.py | 51 ------- logger.py | 55 ------- process_monitor.py | 51 ------- pyproject.toml | 44 ------ requirements.txt | 3 - setup.py | 55 ------- src/alert.rs | 19 +-- src/exporter.rs | 53 ------- src/logger.rs | 7 +- src/main.rs | 1 - src/monitor.rs | 15 +- temperature_monitor.py | 35 ----- test_export.py | 26 ---- test_tracker.py | 45 ------ tracker.py | 139 ------------------ 22 files changed, 102 insertions(+), 1192 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 README-rust.md delete mode 100644 RUST_MIGRATION.md delete mode 100644 alert_system.py delete mode 100644 config_manager.py delete mode 100644 data_exporter.py delete mode 100644 logger.py delete mode 100644 process_monitor.py delete mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py delete mode 100644 src/exporter.rs delete mode 100644 temperature_monitor.py delete mode 100644 test_export.py delete mode 100644 test_tracker.py delete mode 100644 tracker.py diff --git a/Cargo.toml b/Cargo.toml index 13b0fe7..a251e6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,4 @@ serde_json = "1.0" chrono = "0.4" log = "0.4" env_logger = "0.11" -csv = "1.3" anyhow = "1.0" diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 07ae2c2..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -include README.md -include LICENSE -include CHANGELOG.md -include requirements.txt -include config.json -recursive-include tests *.py diff --git a/README-rust.md b/README-rust.md deleted file mode 100644 index fee244e..0000000 --- a/README-rust.md +++ /dev/null @@ -1,320 +0,0 @@ -# Tracker (Rust Edition) - -A high-performance, memory-safe system monitoring tool rewritten in Rust from the original Python implementation. - -## Why Rust? - -This rewrite provides several advantages over the Python version: - -- **Performance**: 10-50x faster execution with minimal CPU overhead -- **Memory Safety**: Zero-cost abstractions with no garbage collection pauses -- **Reliability**: Compile-time guarantees prevent common runtime errors -- **Cross-Platform**: Consistent behavior across Linux, macOS, and Windows -- **Single Binary**: No external dependencies or runtime requirements - -## Features - -- **Real-time System Monitoring** - - CPU usage with accurate multi-core tracking - - Memory utilization (total, used, available, percentage) - - Disk I/O statistics across all mounted filesystems - - Network traffic analysis (bytes sent/received, packet counts) - -- **Process Management** - - Top CPU-consuming processes - - Memory usage per process - - Configurable process display limit - -- **Alert System** - - Configurable thresholds for CPU, memory, and disk - - Visual warnings in terminal output - - Automatic logging of all alerts - -- **Logging** - - Daily rotating log files - - Structured logging with timestamps - - Multiple log levels (INFO, WARNING, ERROR) - -- **Data Export** - - JSON format for programmatic access - - CSV format for spreadsheet analysis - - Automatic timestamped filenames - -- **Configuration** - - JSON-based config file - - Runtime customization via CLI flags - - Sensible defaults for quick start - -## Installation - -### Prerequisites - -- Rust 1.70 or higher (install from https://rustup.rs) -- Cargo (included with Rust) - -### Building from Source - -```bash -# Clone the repository -git clone https://github.com/m1ngsama/tracker.git -cd tracker - -# Build release version (optimized) -cargo build --release - -# The binary will be at: target/release/tracker-rs -``` - -### Installing System-Wide - -```bash -cargo install --path . -``` - -## Usage - -### Basic Usage - -Run a single monitoring snapshot: - -```bash -cargo run -# or if installed: -tracker-rs -``` - -### Continuous Monitoring - -Run in continuous mode with 5-second intervals: - -```bash -cargo run -- --continuous --interval 5 -``` - -### Command-Line Options - -``` -tracker-rs [OPTIONS] - -Options: - -c, --continuous Run in continuous monitoring mode - -i, --interval Update interval in seconds [default: 5] - --config Path to config file [default: config.json] - -h, --help Print help - -V, --version Print version -``` - -### Examples - -```bash -# Monitor once and exit -tracker-rs - -# Continuous monitoring every 10 seconds -tracker-rs -c -i 10 - -# Use custom config file -tracker-rs --config /path/to/config.json - -# Continuous mode with logging enabled -RUST_LOG=info tracker-rs -c -``` - -## Configuration - -Create or edit `config.json`: - -```json -{ - "update_interval": 5, - "display": { - "show_cpu": true, - "show_memory": true, - "show_disk": true, - "show_network": true, - "show_processes": true, - "show_temperatures": true - }, - "process_limit": 5, - "alert_thresholds": { - "cpu_percent": 80.0, - "memory_percent": 85.0, - "disk_percent": 90.0 - } -} -``` - -### Configuration Options - -- `update_interval`: Default refresh rate (used if -i not specified) -- `display`: Toggle individual monitoring features on/off -- `process_limit`: Number of top processes to display -- `alert_thresholds`: Percentage thresholds for alerts - -## Project Structure - -``` -tracker/ -├── src/ -│ ├── main.rs # Application entry point and CLI -│ ├── config.rs # Configuration management -│ ├── monitor.rs # Core system monitoring logic -│ ├── process.rs # Process tracking -│ ├── temperature.rs # Temperature sensors -│ ├── alert.rs # Alert system -│ ├── logger.rs # Logging subsystem -│ └── exporter.rs # Data export (JSON/CSV) -├── Cargo.toml # Rust dependencies -├── config.json # Default configuration -└── README-rust.md # This file -``` - -## Output - -### Console Output - -The tracker displays formatted system statistics: - -``` -================================================== -System Tracker - 2025-12-11 15:30:45 -================================================== - -CPU Usage: 35.42% -Memory: 58.21% (14.00GB / 24.00GB) -Disk: 50.40% (464.07GB / 920.86GB) -Network: Sent 4872.76MB | Recv 6633.56MB - -Top Processes by CPU Usage: -PID Name CPU% Memory% ------------------------------------------------------------- -1234 chrome 45.23 3.21 -5678 rust-analyzer 12.45 1.85 -9012 terminal 5.67 0.42 -... -``` - -### Log Files - -Daily logs are stored in `logs/tracker_YYYYMMDD.log`: - -``` -2025-12-11 15:30:45 - SystemTracker - INFO - CPU: 35.42% -2025-12-11 15:30:45 - SystemTracker - INFO - Memory: 58.21% -2025-12-11 15:30:45 - SystemTracker - WARNING - ALERT: CPU: CPU usage is 85.50% (threshold: 80.00%) -``` - -### Alerts - -When thresholds are exceeded, visual alerts appear: - -``` -⚠️ ALERT: CPU usage is 85.50% (threshold: 80.00%) -⚠️ ALERT: Memory usage is 90.25% (threshold: 85.00%) -``` - -## Development - -### Running Tests - -```bash -cargo test -``` - -### Code Quality - -```bash -# Check for errors -cargo check - -# Lint with Clippy -cargo clippy - -# Format code -cargo fmt -``` - -### Building for Production - -```bash -# Optimized release build -cargo build --release - -# Strip debug symbols for smaller binary -strip target/release/tracker-rs -``` - -### Debugging - -Enable logging with the `RUST_LOG` environment variable: - -```bash -RUST_LOG=debug cargo run -RUST_LOG=tracker_rs=trace cargo run -``` - -## Dependencies - -Key dependencies and their purposes: - -- `sysinfo` - Cross-platform system and process information -- `clap` - Command-line argument parsing -- `serde` / `serde_json` - Configuration serialization -- `chrono` - Date and time utilities -- `log` / `env_logger` - Logging framework -- `csv` - CSV file generation -- `anyhow` - Error handling - -## Performance Comparison - -Rust vs Python (original) on macOS M1: - -| Metric | Python | Rust | Improvement | -|--------|--------|------|-------------| -| Startup Time | 250ms | 10ms | 25x faster | -| Memory Usage | 45MB | 3MB | 15x smaller | -| CPU Overhead | 2-5% | 0.1-0.5% | 10x lower | -| Binary Size | N/A | 4MB | Single binary | - -## Platform Support - -- **macOS**: Full support (tested on M1/M2 and Intel) -- **Linux**: Full support (tested on Ubuntu, Debian, Arch) -- **Windows**: Partial support (temperature sensors limited) - -## Contributing - -Contributions are welcome! Areas for improvement: - -- Enhanced temperature sensor support -- GPU monitoring -- Battery status tracking -- Historical data visualization -- Web dashboard interface - -## Migration from Python Version - -The Rust version maintains compatibility with the Python version's: -- Configuration file format -- Log file structure -- CLI interface - -Simply replace `python tracker.py` with `tracker-rs` in your scripts. - -## License - -MIT License - See [LICENSE](LICENSE) file - -## Author - -m1ngsama - -## Acknowledgments - -- Original Python version inspired by [psutil](https://github.com/giampaolo/psutil) -- Rust implementation built on [sysinfo](https://github.com/GuillaumeGomez/sysinfo) -- Community feedback and contributions - ---- - -**Note**: This is a complete rewrite in Rust. While maintaining feature parity with the Python version, it introduces performance improvements and memory safety guarantees inherent to Rust. diff --git a/README.md b/README.md index 1bdb67d..8bc3466 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,128 @@ -# Tracker +tracker-rs(1) System Tracker tracker-rs(1) -A comprehensive system monitoring tool for tracking various machine health metrics and performance indicators. +NAME + tracker-rs - high-performance system monitoring tool -[![CI](https://github.com/m1ngsama/tracker/actions/workflows/ci.yml/badge.svg)](https://github.com/m1ngsama/tracker/actions/workflows/ci.yml) -[![Release](https://github.com/m1ngsama/tracker/actions/workflows/release.yml/badge.svg)](https://github.com/m1ngsama/tracker/actions/workflows/release.yml) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +SYNOPSIS + tracker-rs [OPTIONS] -## Features +DESCRIPTION + tracker-rs is a high-performance, memory-safe system monitoring tool written in Rust. + It provides real-time statistics for CPU, memory, disk I/O, and network traffic, along + with process management and temperature monitoring. -- **CPU Monitoring**: Real-time CPU usage percentage tracking -- **Memory Utilization**: Track memory usage with detailed statistics -- **Disk I/O Statistics**: Monitor disk usage and I/O operations -- **Network Traffic Analysis**: Track network bytes sent/received -- **Process Monitoring**: View top processes by CPU usage -- **Temperature Sensors**: Monitor system temperatures (if available) -- **Alert System**: Configurable thresholds for CPU, memory, and disk alerts -- **Logging**: Automatic logging of all metrics to daily log files -- **Data Export**: Export monitoring data to JSON or CSV formats -- **Configuration**: Customizable settings via JSON config file + Designed as a drop-in replacement for the legacy Python implementation, it offers + significant performance improvements (10-50x faster execution, reduced memory usage) + while maintaining configuration compatibility. -## Installation +OPTIONS + -c, --continuous + Run in continuous monitoring mode. The tool will repeatedly display statistics + and log data based on the update interval. -### From PyPI (coming soon) + -i, --interval SECONDS + Set the update interval in seconds. Default is 5 seconds. + This option is primarily used with --continuous mode. -```bash -pip install system-tracker -``` + --config FILE + Path to the configuration file. Default is "config.json". + If the file does not exist, internal defaults are used. -### From Source + -h, --help + Print help message and exit. -```bash -git clone https://github.com/m1ngsama/tracker.git -cd tracker -pip install -r requirements.txt -``` + -V, --version + Print version information and exit. -## Usage +CONFIGURATION + The tool is configured via a JSON file (default: config.json). + The configuration file supports the following keys: -### Basic usage: -```bash -python tracker.py -``` + update_interval (integer) + Default refresh rate in seconds (overridden by -i). -### Continuous monitoring mode: -```bash -python tracker.py --continuous --interval 5 -``` + display (object) + Toggle individual monitoring features on/off: + - show_cpu (boolean) + - show_memory (boolean) + - show_disk (boolean) + - show_network (boolean) + - show_processes (boolean) + - show_temperatures (boolean) -### Command line options: -- `-c, --continuous`: Run in continuous monitoring mode -- `-i, --interval`: Set update interval in seconds (default: 5) + process_limit (integer) + Number of top CPU-consuming processes to display. -## Configuration + alert_thresholds (object) + Percentage thresholds for triggering alerts: + - cpu_percent (float) + - memory_percent (float) + - disk_percent (float) -The `config.json` file allows you to customize the tracker behavior: + Example config.json: + { + "update_interval": 5, + "display": { + "show_cpu": true, + "show_memory": true, + "show_disk": true, + "show_network": true, + "show_processes": true, + "show_temperatures": true + }, + "process_limit": 5, + "alert_thresholds": { + "cpu_percent": 80.0, + "memory_percent": 85.0, + "disk_percent": 90.0 + } + } -```json -{ - "update_interval": 5, - "display": { - "show_cpu": true, - "show_memory": true, - "show_disk": true, - "show_network": true, - "show_processes": true, - "show_temperatures": true - }, - "process_limit": 5, - "alert_thresholds": { - "cpu_percent": 80, - "memory_percent": 85, - "disk_percent": 90 - } -} -``` +OUTPUT + tracker-rs outputs formatted system statistics to the console. + In continuous mode, it updates at the specified interval. -## Output + CPU Usage: 35.42% + Memory: 58.21% (14.00GB / 24.00GB) + Disk: 50.40% (464.07GB / 920.86GB) + Network: Sent 4872.76MB | Recv 6633.56MB -The tracker provides: -- **Console Output**: Real-time metrics displayed in the terminal -- **Log Files**: Daily logs stored in `logs/` directory -- **Alerts**: Visual and logged warnings when thresholds are exceeded -- **Export Data**: Optional data export to `exports/` directory + Top Processes by CPU Usage: + PID Name CPU% Memory% + ------------------------------------------------------------ + 1234 chrome 45.23 3.21 -## Requirements +FILES + config.json + Default configuration file location. -- Python 3.8+ -- psutil -- GPUtil (for GPU monitoring) -- requests + logs/tracker_YYYYMMDD.log + Daily rotating log files containing system stats and alerts. -## Development +EXIT STATUS + 0 Success. + 1 Failure (e.g., invalid configuration). -### Running Tests +EXAMPLES + Run a single monitoring snapshot: + $ tracker-rs -```bash -python test_tracker.py -``` + Run continuously every 2 seconds: + $ tracker-rs -c -i 2 -### Project Structure + Use a custom configuration file: + $ tracker-rs --config /etc/tracker/config.json -``` -tracker/ -├── tracker.py # Main application -├── process_monitor.py # Process monitoring module -├── temperature_monitor.py # Temperature sensors module -├── config_manager.py # Configuration management -├── alert_system.py # Alert and threshold management -├── logger.py # Logging functionality -├── data_exporter.py # Data export utilities -├── config.json # Configuration file -└── requirements.txt # Python dependencies -``` +SEE ALSO + top(1), htop(1), ps(1) -## CI/CD +BUGS + Report bugs to https://github.com/m1ngsama/tracker/issues -This project uses GitHub Actions for: -- **Continuous Integration**: Automated testing on multiple OS and Python versions -- **Automated Releases**: Automatic package building and release creation on version tags -- **Code Quality**: Linting and syntax checking +AUTHOR + m1ngsama -## Contributing +LICENSE + MIT License -Contributions are welcome! Please feel free to submit a Pull Request. - -## License - -MIT License - see [LICENSE](LICENSE) file for details - -## Author - -m1ngsama - -## Acknowledgments - -- Built with [psutil](https://github.com/giampaolo/psutil) for cross-platform system monitoring +v1.0.0 2025-12-18 tracker-rs(1) \ No newline at end of file diff --git a/RUST_MIGRATION.md b/RUST_MIGRATION.md deleted file mode 100644 index bff868e..0000000 --- a/RUST_MIGRATION.md +++ /dev/null @@ -1,58 +0,0 @@ -# Migration Guide: Python to Rust - -This document explains the architectural changes and benefits of the Rust rewrite. - -## Architecture Changes - -### Module Mapping - -| Python Module | Rust Module | Changes | -|---------------|-------------|---------| -| `tracker.py` | `src/main.rs` + `src/monitor.rs` | Split into CLI and monitoring logic | -| `config_manager.py` | `src/config.rs` | Added type safety with serde | -| `process_monitor.py` | `src/process.rs` | Improved error handling | -| `temperature_monitor.py` | `src/temperature.rs` | Platform-agnostic design | -| `alert_system.py` | `src/alert.rs` | Enhanced with type-safe thresholds | -| `logger.py` | `src/logger.rs` | Zero-allocation logging | -| `data_exporter.py` | `src/exporter.rs` | Generic export with serde | - -### Key Improvements - -1. **Type Safety**: Compile-time guarantees prevent runtime errors -2. **Zero-Copy Operations**: Reduced memory allocations -3. **Error Handling**: Result types replace exception handling -4. **Ownership**: Rust's ownership system prevents memory leaks -5. **Concurrency**: Safe concurrent operations (future enhancement) - -### API Compatibility - -The Rust version maintains CLI compatibility: - -```bash -# Python -python tracker.py --continuous --interval 5 - -# Rust -tracker-rs --continuous --interval 5 -``` - -Configuration format remains identical for easy migration. - -## Performance Benefits - -- **Startup**: 25x faster cold start -- **Memory**: 15x lower memory footprint -- **CPU**: 10x lower CPU overhead during monitoring -- **Binary**: Single 4MB executable vs 45MB Python + deps - -## Breaking Changes - -None! The Rust version is a drop-in replacement. - -## Future Enhancements - -With Rust foundation, we can add: -- Async monitoring for better resource usage -- WASM compilation for browser-based monitoring -- FFI bindings for embedding in other languages -- Plugin system with dynamic loading diff --git a/alert_system.py b/alert_system.py deleted file mode 100644 index 64afbe8..0000000 --- a/alert_system.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Alert system for system monitoring -""" - -from logger import TrackerLogger - - -class AlertSystem: - def __init__(self, config): - self.config = config - self.logger = TrackerLogger() - self.alert_history = [] - - def check_cpu_alert(self, cpu_percent): - """Check if CPU usage exceeds threshold""" - threshold = self.config.get('alert_thresholds.cpu_percent', 80) - if cpu_percent > threshold: - message = f"CPU usage is {cpu_percent}% (threshold: {threshold}%)" - self.trigger_alert('CPU', message) - return True - return False - - def check_memory_alert(self, memory_percent): - """Check if memory usage exceeds threshold""" - threshold = self.config.get('alert_thresholds.memory_percent', 85) - if memory_percent > threshold: - message = f"Memory usage is {memory_percent}% (threshold: {threshold}%)" - self.trigger_alert('Memory', message) - return True - return False - - def check_disk_alert(self, disk_percent): - """Check if disk usage exceeds threshold""" - threshold = self.config.get('alert_thresholds.disk_percent', 90) - if disk_percent > threshold: - message = f"Disk usage is {disk_percent}% (threshold: {threshold}%)" - self.trigger_alert('Disk', message) - return True - return False - - def trigger_alert(self, alert_type, message): - """Trigger an alert""" - alert = { - 'type': alert_type, - 'message': message - } - self.alert_history.append(alert) - self.logger.log_alert(f"{alert_type}: {message}") - print(f"\n⚠️ ALERT: {message}") - - def get_alert_history(self): - """Get alert history""" - return self.alert_history diff --git a/config_manager.py b/config_manager.py deleted file mode 100644 index 89118e4..0000000 --- a/config_manager.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -Configuration management for tracker -""" - -import json -import os - - -class Config: - def __init__(self, config_file='config.json'): - self.config_file = config_file - self.config = self.load_config() - - def load_config(self): - """Load configuration from JSON file""" - if os.path.exists(self.config_file): - with open(self.config_file, 'r') as f: - return json.load(f) - return self.get_default_config() - - def get_default_config(self): - """Return default configuration""" - return { - 'update_interval': 5, - 'display': { - 'show_cpu': True, - 'show_memory': True, - 'show_disk': True, - 'show_network': True, - 'show_processes': True, - 'show_temperatures': True - }, - 'process_limit': 5, - 'alert_thresholds': { - 'cpu_percent': 80, - 'memory_percent': 85, - 'disk_percent': 90 - } - } - - def get(self, key, default=None): - """Get configuration value""" - keys = key.split('.') - value = self.config - for k in keys: - if isinstance(value, dict): - value = value.get(k, default) - else: - return default - return value diff --git a/data_exporter.py b/data_exporter.py deleted file mode 100644 index 676f46d..0000000 --- a/data_exporter.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Data export functionality -""" - -import json -import csv -from datetime import datetime - - -class DataExporter: - def __init__(self, output_dir='exports'): - self.output_dir = output_dir - self._ensure_directory() - - def _ensure_directory(self): - """Ensure the output directory exists""" - import os - if not os.path.exists(self.output_dir): - os.makedirs(self.output_dir) - - def export_to_json(self, data, filename=None): - """Export data to JSON format""" - if filename is None: - filename = f"tracker_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" - - filepath = f"{self.output_dir}/{filename}" - - try: - with open(filepath, 'w') as f: - json.dump(data, f, indent=2) - return filepath - except IOError as e: - raise IOError(f"Failed to export data to JSON: {e}") - - def export_to_csv(self, data, filename=None): - """Export data to CSV format""" - if filename is None: - filename = f"tracker_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" - - filepath = f"{self.output_dir}/{filename}" - - try: - if isinstance(data, list) and len(data) > 0: - keys = data[0].keys() - with open(filepath, 'w', newline='') as f: - writer = csv.DictWriter(f, fieldnames=keys) - writer.writeheader() - writer.writerows(data) - return filepath - except IOError as e: - raise IOError(f"Failed to export data to CSV: {e}") diff --git a/logger.py b/logger.py deleted file mode 100644 index 6c88037..0000000 --- a/logger.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -Logging functionality for tracker -""" - -import logging -import os -from datetime import datetime - - -class TrackerLogger: - def __init__(self, log_dir='logs'): - self.log_dir = log_dir - self.setup_logger() - - def setup_logger(self): - """Setup logging configuration""" - if not os.path.exists(self.log_dir): - os.makedirs(self.log_dir) - - log_file = os.path.join( - self.log_dir, - f"tracker_{datetime.now().strftime('%Y%m%d')}.log" - ) - - # Clear any existing handlers to prevent duplicate logging - logger = logging.getLogger('SystemTracker') - logger.handlers.clear() - - # Create handlers - file_handler = logging.FileHandler(log_file) - stream_handler = logging.StreamHandler() - - # Create formatter and add it to handlers - formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') - file_handler.setFormatter(formatter) - stream_handler.setFormatter(formatter) - - # Add handlers to logger - logger.addHandler(file_handler) - logger.addHandler(stream_handler) - logger.setLevel(logging.INFO) - - self.logger = logger - - def log_stats(self, stats_type, stats_data): - """Log system statistics""" - self.logger.info(f"{stats_type}: {stats_data}") - - def log_alert(self, message): - """Log alert messages""" - self.logger.warning(f"ALERT: {message}") - - def log_error(self, error_message): - """Log error messages""" - self.logger.error(f"ERROR: {error_message}") diff --git a/process_monitor.py b/process_monitor.py deleted file mode 100644 index 63c4ee1..0000000 --- a/process_monitor.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Process monitoring utilities -""" - -import psutil - - -class ProcessMonitor: - def get_top_processes(self, limit=5): - """Get top processes by CPU usage""" - processes = [] - # First collect all processes - for proc in psutil.process_iter(['pid', 'name']): - try: - # Get CPU percent with interval for more accurate reading - cpu_percent = proc.cpu_percent(interval=0.1) - memory_percent = proc.memory_percent() - processes.append({ - 'pid': proc.info['pid'], - 'name': proc.info['name'], - 'cpu_percent': cpu_percent, - 'memory_percent': memory_percent - }) - except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): - pass - - processes.sort(key=lambda x: x['cpu_percent'] or 0, reverse=True) - return processes[:limit] - - def get_process_count(self): - """Get total number of running processes""" - try: - return len(psutil.pids()) - except Exception: - return 0 - - def display_processes(self): - """Display top processes""" - try: - print(f"\nTop Processes by CPU Usage:") - print(f"{'PID':<10}{'Name':<30}{'CPU%':<10}{'Memory%':<10}") - print("-" * 60) - - for proc in self.get_top_processes(): - cpu = proc['cpu_percent'] if proc['cpu_percent'] is not None else 0 - mem = proc['memory_percent'] if proc['memory_percent'] is not None else 0 - print(f"{proc['pid']:<10}{proc['name']:<30}{cpu:<10.2f}{mem:<10.2f}") - - print(f"\nTotal Processes: {self.get_process_count()}") - except Exception as e: - print(f"Error displaying processes: {e}") diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 764ce07..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,44 +0,0 @@ -[build-system] -requires = ["setuptools>=45", "wheel"] -build-backend = "setuptools.build_meta" - -[project] -name = "system-tracker" -version = "1.0.0" -description = "A comprehensive system monitoring tool for tracking machine health metrics" -readme = "README.md" -requires-python = ">=3.8" -license = {text = "MIT"} -authors = [ - {name = "m1ngsama"} -] -keywords = ["monitoring", "system", "performance", "metrics", "health-check"] -classifiers = [ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "Topic :: System :: Monitoring", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", -] -dependencies = [ - "psutil>=5.9.0", - "GPUtil>=1.4.0", - "requests>=2.28.0", -] - -[project.urls] -Homepage = "https://github.com/m1ngsama/tracker" -Repository = "https://github.com/m1ngsama/tracker" -Issues = "https://github.com/m1ngsama/tracker/issues" - -[project.scripts] -tracker = "tracker:main" - -[tool.setuptools] -py-modules = ["tracker", "process_monitor", "temperature_monitor", "config_manager", "alert_system", "logger", "data_exporter"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index eef0fdf..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -psutil>=5.9.0 -GPUtil>=1.4.0 -requests>=2.28.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index 8b753cd..0000000 --- a/setup.py +++ /dev/null @@ -1,55 +0,0 @@ -from setuptools import setup - -with open("README.md", "r", encoding="utf-8") as fh: - long_description = fh.read() - -with open("requirements.txt", "r", encoding="utf-8") as fh: - requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")] - -setup( - name="system-tracker", - version="1.0.0", - author="m1ngsama", - author_email="", - description="A comprehensive system monitoring tool for tracking machine health metrics", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/m1ngsama/tracker", - py_modules=[ - "tracker", - "process_monitor", - "temperature_monitor", - "config_manager", - "alert_system", - "logger", - "data_exporter", - ], - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "Topic :: System :: Monitoring", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Operating System :: OS Independent", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS", - "Operating System :: Microsoft :: Windows", - ], - python_requires=">=3.8", - install_requires=requirements, - entry_points={ - "console_scripts": [ - "tracker=tracker:main", - ], - }, - include_package_data=True, - data_files=[ - ("", ["config.json"]), - ], -) diff --git a/src/alert.rs b/src/alert.rs index f62f6ba..fba1240 100644 --- a/src/alert.rs +++ b/src/alert.rs @@ -4,13 +4,6 @@ use crate::logger::TrackerLogger; pub struct AlertSystem { config: Config, logger: TrackerLogger, - alert_history: Vec, -} - -#[derive(Debug, Clone)] -pub struct Alert { - pub alert_type: String, - pub message: String, } impl AlertSystem { @@ -18,7 +11,6 @@ impl AlertSystem { AlertSystem { config, logger: TrackerLogger::default(), - alert_history: Vec::new(), } } @@ -53,16 +45,7 @@ impl AlertSystem { } fn trigger_alert(&mut self, alert_type: &str, message: &str) { - let alert = Alert { - alert_type: alert_type.to_string(), - message: message.to_string(), - }; - self.alert_history.push(alert.clone()); self.logger.log_alert(&format!("{}: {}", alert_type, message)); println!("\n⚠️ ALERT: {}", message); } - - pub fn get_alert_history(&self) -> &[Alert] { - &self.alert_history - } -} +} \ No newline at end of file diff --git a/src/exporter.rs b/src/exporter.rs deleted file mode 100644 index bc67e41..0000000 --- a/src/exporter.rs +++ /dev/null @@ -1,53 +0,0 @@ -use serde::Serialize; -use std::fs; -use std::path::PathBuf; -use anyhow::Result; -use chrono::Local; - -pub struct DataExporter { - output_dir: PathBuf, -} - -impl DataExporter { - pub fn new(output_dir: &str) -> Self { - let output_dir = PathBuf::from(output_dir); - if !output_dir.exists() { - fs::create_dir_all(&output_dir).ok(); - } - DataExporter { output_dir } - } - - pub fn export_to_json(&self, data: &T, filename: Option) -> Result { - let filename = filename.unwrap_or_else(|| { - format!("tracker_data_{}.json", Local::now().format("%Y%m%d_%H%M%S")) - }); - - let filepath = self.output_dir.join(filename); - let json = serde_json::to_string_pretty(data)?; - fs::write(&filepath, json)?; - - Ok(filepath) - } - - pub fn export_to_csv(&self, data: &[T], filename: Option) -> Result { - let filename = filename.unwrap_or_else(|| { - format!("tracker_data_{}.csv", Local::now().format("%Y%m%d_%H%M%S")) - }); - - let filepath = self.output_dir.join(filename); - let mut wtr = csv::Writer::from_path(&filepath)?; - - for record in data { - wtr.serialize(record)?; - } - - wtr.flush()?; - Ok(filepath) - } -} - -impl Default for DataExporter { - fn default() -> Self { - Self::new("exports") - } -} diff --git a/src/logger.rs b/src/logger.rs index 5bdf7d4..801b665 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -43,15 +43,10 @@ impl TrackerLogger { let alert_message = format!("ALERT: {}", message); self.write_log("WARNING", &alert_message); } - - pub fn log_error(&self, error_message: &str) { - let error_msg = format!("ERROR: {}", error_message); - self.write_log("ERROR", &error_msg); - } } impl Default for TrackerLogger { fn default() -> Self { Self::new("logs") } -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index adce467..4507f3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ mod process; mod temperature; mod alert; mod logger; -mod exporter; use config::Config; use monitor::SystemMonitor; diff --git a/src/monitor.rs b/src/monitor.rs index 647da6c..6ebd2c3 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -42,7 +42,6 @@ impl SystemMonitor { self.sys.refresh_memory(); let total = self.sys.total_memory(); let used = self.sys.used_memory(); - let available = self.sys.available_memory(); let percent = if total > 0 { (used as f32 / total as f32) * 100.0 } else { @@ -52,7 +51,6 @@ impl SystemMonitor { MemoryInfo { total, used, - available, percent, } } @@ -78,7 +76,6 @@ impl SystemMonitor { DiskInfo { total, used, - free: available, percent, } } @@ -88,21 +85,15 @@ impl SystemMonitor { let mut bytes_sent = 0; let mut bytes_recv = 0; - let mut packets_sent = 0; - let mut packets_recv = 0; for (_, network) in &self.networks { bytes_sent += network.total_transmitted(); bytes_recv += network.total_received(); - packets_sent += network.total_packets_transmitted(); - packets_recv += network.total_packets_received(); } NetworkStats { bytes_sent, bytes_recv, - packets_sent, - packets_recv, } } @@ -163,7 +154,6 @@ impl SystemMonitor { pub struct MemoryInfo { pub total: u64, pub used: u64, - pub available: u64, pub percent: f32, } @@ -171,7 +161,6 @@ pub struct MemoryInfo { pub struct DiskInfo { pub total: u64, pub used: u64, - pub free: u64, pub percent: f32, } @@ -179,6 +168,4 @@ pub struct DiskInfo { pub struct NetworkStats { pub bytes_sent: u64, pub bytes_recv: u64, - pub packets_sent: u64, - pub packets_recv: u64, -} +} \ No newline at end of file diff --git a/temperature_monitor.py b/temperature_monitor.py deleted file mode 100644 index f775b51..0000000 --- a/temperature_monitor.py +++ /dev/null @@ -1,35 +0,0 @@ -""" -Temperature sensor monitoring -""" - -import psutil - - -class TemperatureMonitor: - def get_temperatures(self): - """Get system temperatures if available""" - try: - temps = psutil.sensors_temperatures() - return temps - except AttributeError: - return None - - def display_temperatures(self): - """Display system temperatures""" - temps = self.get_temperatures() - - if not temps: - print("\nTemperature sensors not available on this system") - return - - print("\nSystem Temperatures:") - print(f"{'Sensor':<30}{'Current':<15}{'High':<15}{'Critical':<15}") - print("-" * 75) - - for name, entries in temps.items(): - for entry in entries: - label = entry.label or name - current = f"{entry.current}°C" if entry.current else "N/A" - high = f"{entry.high}°C" if entry.high else "N/A" - critical = f"{entry.critical}°C" if entry.critical else "N/A" - print(f"{label:<30}{current:<15}{high:<15}{critical:<15}") diff --git a/test_export.py b/test_export.py deleted file mode 100644 index 1359331..0000000 --- a/test_export.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -"""Test data export functionality""" - -from data_exporter import DataExporter - -# Test data -test_data = [ - {'timestamp': '2025-11-25 15:00:00', 'cpu': 45.2, 'memory': 60.1}, - {'timestamp': '2025-11-25 15:05:00', 'cpu': 52.3, 'memory': 62.5}, - {'timestamp': '2025-11-25 15:10:00', 'cpu': 48.9, 'memory': 61.8} -] - -exporter = DataExporter() - -# Test JSON export -json_file = exporter.export_to_json(test_data) -print(f"✓ JSON export successful: {json_file}") - -# Test CSV export -csv_file = exporter.export_to_csv(test_data) -print(f"✓ CSV export successful: {csv_file}") - -print("\nExport directory contents:") -import os -for file in os.listdir('exports'): - print(f" - {file}") diff --git a/test_tracker.py b/test_tracker.py deleted file mode 100644 index 33a8c05..0000000 --- a/test_tracker.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -Unit tests for tracker functionality -""" - -import unittest -from unittest.mock import Mock, patch -from tracker import SystemTracker - - -class TestSystemTracker(unittest.TestCase): - def setUp(self): - self.tracker = SystemTracker() - - @patch('psutil.cpu_percent') - def test_get_cpu_usage(self, mock_cpu): - mock_cpu.return_value = 50.0 - result = self.tracker.get_cpu_usage() - self.assertEqual(result, 50.0) - - @patch('psutil.virtual_memory') - def test_get_memory_info(self, mock_mem): - mock_mem.return_value = Mock( - total=8589934592, - available=4294967296, - percent=50.0, - used=4294967296 - ) - result = self.tracker.get_memory_info() - self.assertEqual(result['percent'], 50.0) - self.assertEqual(result['total'], 8589934592) - - @patch('psutil.disk_usage') - def test_get_disk_usage(self, mock_disk): - mock_disk.return_value = Mock( - total=1000000000000, - used=500000000000, - free=500000000000, - percent=50.0 - ) - result = self.tracker.get_disk_usage() - self.assertEqual(result['percent'], 50.0) - - -if __name__ == '__main__': - unittest.main() diff --git a/tracker.py b/tracker.py deleted file mode 100644 index c01bcc5..0000000 --- a/tracker.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python3 -""" -System Tracker - Monitor machine health and performance -""" - -import psutil -import time -import argparse -from datetime import datetime -from process_monitor import ProcessMonitor -from temperature_monitor import TemperatureMonitor -from config_manager import Config -from alert_system import AlertSystem -from logger import TrackerLogger - - -class SystemTracker: - def __init__(self, config_file='config.json'): - self.start_time = time.time() - self.config = Config(config_file) - self.process_monitor = ProcessMonitor() - self.temperature_monitor = TemperatureMonitor() - self.alert_system = AlertSystem(self.config) - self.logger = TrackerLogger() - - def get_cpu_usage(self): - """Get current CPU usage percentage""" - try: - return psutil.cpu_percent(interval=1, percpu=False) - except Exception as e: - self.logger.log_error(f"Failed to get CPU usage: {e}") - return 0.0 - - def get_memory_info(self): - """Get memory usage statistics""" - try: - mem = psutil.virtual_memory() - return { - 'total': mem.total, - 'available': mem.available, - 'percent': mem.percent, - 'used': mem.used - } - except Exception as e: - self.logger.log_error(f"Failed to get memory info: {e}") - return {'total': 0, 'available': 0, 'percent': 0, 'used': 0} - - def get_disk_usage(self): - """Get disk usage statistics""" - try: - disk = psutil.disk_usage('/') - return { - 'total': disk.total, - 'used': disk.used, - 'free': disk.free, - 'percent': disk.percent - } - except Exception as e: - self.logger.log_error(f"Failed to get disk usage: {e}") - return {'total': 0, 'used': 0, 'free': 0, 'percent': 0} - - def get_network_stats(self): - """Get network I/O statistics""" - try: - net = psutil.net_io_counters() - return { - 'bytes_sent': net.bytes_sent, - 'bytes_recv': net.bytes_recv, - 'packets_sent': net.packets_sent, - 'packets_recv': net.packets_recv - } - except Exception as e: - self.logger.log_error(f"Failed to get network stats: {e}") - return {'bytes_sent': 0, 'bytes_recv': 0, 'packets_sent': 0, 'packets_recv': 0} - - def display_stats(self): - """Display all system statistics""" - print(f"\n{'='*50}") - print(f"System Tracker - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print(f"{'='*50}\n") - - # CPU monitoring - if self.config.get('display.show_cpu', True): - cpu_usage = self.get_cpu_usage() - print(f"CPU Usage: {cpu_usage}%") - self.logger.log_stats('CPU', f"{cpu_usage}%") - self.alert_system.check_cpu_alert(cpu_usage) - - # Memory monitoring - if self.config.get('display.show_memory', True): - mem = self.get_memory_info() - print(f"Memory: {mem['percent']}% ({mem['used'] / (1024**3):.2f}GB / {mem['total'] / (1024**3):.2f}GB)") - self.logger.log_stats('Memory', f"{mem['percent']}%") - self.alert_system.check_memory_alert(mem['percent']) - - # Disk monitoring - if self.config.get('display.show_disk', True): - disk = self.get_disk_usage() - print(f"Disk: {disk['percent']}% ({disk['used'] / (1024**3):.2f}GB / {disk['total'] / (1024**3):.2f}GB)") - self.logger.log_stats('Disk', f"{disk['percent']}%") - self.alert_system.check_disk_alert(disk['percent']) - - # Network monitoring - if self.config.get('display.show_network', True): - net = self.get_network_stats() - print(f"Network: Sent {net['bytes_sent'] / (1024**2):.2f}MB | Recv {net['bytes_recv'] / (1024**2):.2f}MB") - self.logger.log_stats('Network', f"Sent: {net['bytes_sent']} Recv: {net['bytes_recv']}") - - # Process monitoring - if self.config.get('display.show_processes', True): - self.process_monitor.display_processes() - - # Temperature monitoring - if self.config.get('display.show_temperatures', True): - self.temperature_monitor.display_temperatures() - - -def main(): - """Main entry point for the tracker application""" - parser = argparse.ArgumentParser(description='System Tracker - Monitor machine health') - parser.add_argument('-c', '--continuous', action='store_true', help='Run continuously') - parser.add_argument('-i', '--interval', type=int, default=5, help='Update interval in seconds') - args = parser.parse_args() - - tracker = SystemTracker() - - if args.continuous: - try: - while True: - tracker.display_stats() - time.sleep(args.interval) - except KeyboardInterrupt: - print("\n\nTracker stopped by user") - else: - tracker.display_stats() - - -if __name__ == "__main__": - main()