Add configuration, utilities, and update server with enhanced monitoring features
- Add config.py for environment configuration management - Add utils.py with utility functions - Add .env.example for environment variable reference - Add routes_example.py as route reference - Add login.html template for authentication - Update server.py with enhancements - Update all dashboard and log templates - Move documentation to 'explanations and old code' directory - Update database schema
This commit is contained in:
391
explanations and old code/IMPLEMENTATION_GUIDE.md
Normal file
391
explanations and old code/IMPLEMENTATION_GUIDE.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# Server Monitorizare - Quick Reference Guide
|
||||
|
||||
## 📁 Files Created/Updated
|
||||
|
||||
### 1. **IMPROVEMENT_ANALYSIS.md** (Main Analysis)
|
||||
Comprehensive analysis of the codebase with:
|
||||
- 10 major issue categories
|
||||
- Security vulnerabilities
|
||||
- Performance problems
|
||||
- Code structure recommendations
|
||||
- Prioritized implementation roadmap
|
||||
- Quick wins list
|
||||
|
||||
### 2. **config.py** (Configuration Management)
|
||||
Features:
|
||||
- Environment-based configuration (dev/prod/test)
|
||||
- Centralized settings management
|
||||
- Support for environment variables via `.env`
|
||||
- Sensible defaults
|
||||
|
||||
Usage:
|
||||
```python
|
||||
from config import get_config
|
||||
config = get_config()
|
||||
database = config.DATABASE_PATH
|
||||
```
|
||||
|
||||
### 3. **utils.py** (Utility Functions)
|
||||
Features:
|
||||
- Error handling decorators
|
||||
- Authentication decorators
|
||||
- Request logging
|
||||
- Standardized response formats
|
||||
- Input validation helpers
|
||||
- Logging setup
|
||||
|
||||
Usage:
|
||||
```python
|
||||
@require_auth
|
||||
@log_request
|
||||
def protected_endpoint():
|
||||
return success_response({"data": "value"})
|
||||
```
|
||||
|
||||
### 4. **.env.example** (Configuration Template)
|
||||
- Updated with comprehensive environment variables
|
||||
- Copy to `.env` and customize for your environment
|
||||
|
||||
### 5. **routes_example.py** (Refactored Route Module)
|
||||
Shows how to restructure the code using:
|
||||
- Blueprint modules
|
||||
- Proper error handling
|
||||
- Pagination support
|
||||
- Database backup integration
|
||||
- Comprehensive logging
|
||||
- Standardized responses
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Top 5 Critical Issues (Fix First)
|
||||
|
||||
### 1. No Authentication (Security Risk)
|
||||
```python
|
||||
# Current: Anyone can submit logs
|
||||
@app.route('/logs', methods=['POST'])
|
||||
def log_event():
|
||||
# No protection!
|
||||
|
||||
# Recommended: Use API key validation
|
||||
@app.route('/logs', methods=['POST'])
|
||||
@require_auth # Checks X-API-Key header
|
||||
def log_event():
|
||||
# Protected
|
||||
```
|
||||
|
||||
### 2. No Logging System
|
||||
```python
|
||||
# Current: Using print() - lost in production
|
||||
print(f"Database error: {e}")
|
||||
|
||||
# Recommended: Proper logging
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"Database error: {e}", exc_info=True)
|
||||
```
|
||||
|
||||
### 3. Inconsistent Error Handling
|
||||
```python
|
||||
# Current: Different error formats
|
||||
return {"error": "Message"}, 400
|
||||
return jsonify({"error": message}), 500
|
||||
|
||||
# Recommended: Standardized format
|
||||
from utils import error_response
|
||||
return error_response("Message", 400)
|
||||
```
|
||||
|
||||
### 4. Monolithic Code Structure
|
||||
```
|
||||
# Current: All code in server.py (462 lines)
|
||||
server.py
|
||||
|
||||
# Recommended: Modular structure
|
||||
routes/
|
||||
├── logs.py
|
||||
├── devices.py
|
||||
└── commands.py
|
||||
services/
|
||||
└── device_service.py
|
||||
utils.py
|
||||
config.py
|
||||
```
|
||||
|
||||
### 5. No Input Validation
|
||||
```python
|
||||
# Current: Only checks if field exists
|
||||
if not hostname:
|
||||
return error, 400
|
||||
|
||||
# Recommended: Validates format and length
|
||||
def validate_hostname(hostname):
|
||||
if not re.match(r'^[a-zA-Z0-9_-]+$', hostname):
|
||||
raise APIError("Invalid format", 400)
|
||||
if len(hostname) > 255:
|
||||
raise APIError("Too long", 400)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Quick Wins (Easy Fixes - Do Today!)
|
||||
|
||||
### 1. Add `.env` Support (5 minutes)
|
||||
```bash
|
||||
pip install python-dotenv
|
||||
# Create .env file from .env.example
|
||||
# Update server.py to load from .env
|
||||
```
|
||||
|
||||
### 2. Replace `print()` with Logging (10 minutes)
|
||||
```python
|
||||
# Add at top of server.py
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Replace all print() calls:
|
||||
# print("error") → logger.error("error")
|
||||
```
|
||||
|
||||
### 3. Add Health Check Endpoint (5 minutes)
|
||||
```python
|
||||
@app.route('/health', methods=['GET'])
|
||||
def health():
|
||||
try:
|
||||
with sqlite3.connect(DATABASE) as conn:
|
||||
conn.execute('SELECT 1')
|
||||
return jsonify({"status": "healthy"}), 200
|
||||
except:
|
||||
return jsonify({"status": "unhealthy"}), 503
|
||||
```
|
||||
|
||||
### 4. Add Error Handler (10 minutes)
|
||||
```python
|
||||
from utils import error_response
|
||||
|
||||
@app.errorhandler(400)
|
||||
def bad_request(error):
|
||||
return error_response("Bad request", 400)
|
||||
|
||||
@app.errorhandler(500)
|
||||
def internal_error(error):
|
||||
return error_response("Internal server error", 500)
|
||||
```
|
||||
|
||||
### 5. Add Rate Limiting (5 minutes)
|
||||
```bash
|
||||
pip install flask-limiter
|
||||
```
|
||||
|
||||
```python
|
||||
from flask_limiter import Limiter
|
||||
limiter = Limiter(app, key_func=get_remote_address)
|
||||
|
||||
@app.route('/logs', methods=['POST'])
|
||||
@limiter.limit("10 per minute")
|
||||
def log_event():
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Current Architecture
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Web Clients │
|
||||
└────────┬────────┘
|
||||
│ HTTP
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Flask App (server.py) │
|
||||
│ - 462 lines (monolithic) │
|
||||
│ - No authentication │
|
||||
│ - No logging │
|
||||
│ - Direct SQL queries │
|
||||
└────────┬────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ SQLite Database │
|
||||
│ data/database.db │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎯 Recommended New Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ Web Clients │
|
||||
│ Device API Clients │
|
||||
└────────┬─────────────────────┘
|
||||
│ HTTP (authenticated)
|
||||
▼
|
||||
┌──────────────────────────────┐
|
||||
│ Flask App │
|
||||
├──────────────────────────────┤
|
||||
│ Routes (Blueprints) │
|
||||
│ ├── logs.py │
|
||||
│ ├── devices.py │
|
||||
│ └── commands.py │
|
||||
├──────────────────────────────┤
|
||||
│ Services Layer │
|
||||
│ ├── device_service.py │
|
||||
│ └── command_service.py │
|
||||
├──────────────────────────────┤
|
||||
│ Utils │
|
||||
│ ├── config.py │
|
||||
│ ├── utils.py │
|
||||
│ └── validators.py │
|
||||
└────────┬─────────────────────┘
|
||||
│
|
||||
├─────────────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────┐ ┌──────────────┐
|
||||
│ Database │ │ Cache │
|
||||
│ (SQLite) │ │ (Redis/Mem) │
|
||||
└─────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Implementation Steps
|
||||
|
||||
### Phase 1: Foundation (Week 1)
|
||||
- [ ] Add `config.py` - Centralize configuration
|
||||
- [ ] Add `utils.py` - Common utilities
|
||||
- [ ] Replace `print()` with logging
|
||||
- [ ] Add API authentication decorator
|
||||
- [ ] Update `.env.example`
|
||||
|
||||
### Phase 2: Structure (Week 2)
|
||||
- [ ] Create `routes/` directory
|
||||
- [ ] Create `services/` directory
|
||||
- [ ] Move routes to separate files
|
||||
- [ ] Create blueprint structure
|
||||
- [ ] Add error handling middleware
|
||||
|
||||
### Phase 3: Features (Week 3)
|
||||
- [ ] Add rate limiting
|
||||
- [ ] Add pagination
|
||||
- [ ] Add caching
|
||||
- [ ] Add backup system
|
||||
- [ ] Add health checks
|
||||
|
||||
### Phase 4: Quality (Week 4)
|
||||
- [ ] Add unit tests with pytest
|
||||
- [ ] Add input validation
|
||||
- [ ] Add API documentation
|
||||
- [ ] Docker containerization
|
||||
- [ ] Performance optimization
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Dependencies to Install
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
**requirements.txt:**
|
||||
```
|
||||
flask==3.0.0
|
||||
python-dotenv==1.0.0
|
||||
flask-limiter==3.5.0
|
||||
flask-cors==4.0.0
|
||||
marshmallow==3.20.1
|
||||
requests==2.31.0
|
||||
gunicorn==21.2.0
|
||||
pytest==7.4.3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Example: Before & After
|
||||
|
||||
### BEFORE (Current)
|
||||
```python
|
||||
@app.route('/logs', methods=['POST'])
|
||||
def log_event():
|
||||
try:
|
||||
data = request.json
|
||||
if not data:
|
||||
return {"error": "Invalid payload"}, 400
|
||||
|
||||
hostname = data.get('hostname')
|
||||
if not hostname:
|
||||
return {"error": "Missing fields"}, 400
|
||||
|
||||
with sqlite3.connect(DATABASE) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('''INSERT INTO logs ...''')
|
||||
conn.commit()
|
||||
|
||||
print("Log saved successfully")
|
||||
return {"message": "Success"}, 201
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
return {"error": "Error"}, 500
|
||||
```
|
||||
|
||||
### AFTER (Recommended)
|
||||
```python
|
||||
@logs_bp.route('', methods=['POST'])
|
||||
@require_auth
|
||||
@log_request
|
||||
@validate_required_fields(['hostname', 'device_ip'])
|
||||
def log_event():
|
||||
data = request.get_json()
|
||||
|
||||
# Validate fields
|
||||
hostname = sanitize_hostname(data['hostname'])
|
||||
if not validate_ip_address(data['device_ip']):
|
||||
raise APIError("Invalid IP address", 400)
|
||||
|
||||
# Save to database
|
||||
try:
|
||||
conn = get_db_connection(config.DATABASE_PATH)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('''INSERT INTO logs ...''', (...))
|
||||
conn.commit()
|
||||
|
||||
logger.info(f"Log saved from {hostname}")
|
||||
return success_response({"log_id": cursor.lastrowid}, 201)
|
||||
finally:
|
||||
conn.close()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 For More Information
|
||||
|
||||
See **IMPROVEMENT_ANALYSIS.md** for:
|
||||
- Detailed analysis of all 10 issues
|
||||
- Code examples for each improvement
|
||||
- Security recommendations
|
||||
- Performance optimization tips
|
||||
- Testing strategies
|
||||
- Deployment considerations
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Q: Do I need to rewrite the entire application?**
|
||||
A: No! Start with Phase 1 (foundation) and gradually refactor. You can run the old and new code side-by-side during transition.
|
||||
|
||||
**Q: What's the minimum I should fix?**
|
||||
A: Authentication + Logging + Error handling. These three fix most critical issues.
|
||||
|
||||
**Q: How long will it take?**
|
||||
A: Phase 1 (1-2 days), Phase 2 (3-4 days), Phase 3 (3-4 days), Phase 4 (5-7 days).
|
||||
|
||||
**Q: Should I use a database ORM?**
|
||||
A: Yes, SQLAlchemy is recommended for better connection pooling and query building.
|
||||
|
||||
**Q: What about backward compatibility?**
|
||||
A: API endpoints remain the same; internal refactoring doesn't break clients.
|
||||
|
||||
---
|
||||
|
||||
Created: December 17, 2025
|
||||
Reference in New Issue
Block a user