feat: init projet supervision — monitoring systeme Windows
Interface web Flask securisee pour surveiller CPU, RAM, disques et processus (JVM, Nginx, Amadea Web 8 x64). Alertes email SMTP configurables, seuils reglables, compilation PyInstaller en .exe, installation service Windows via NSSM. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
126
config_manager.py
Normal file
126
config_manager.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Gestion de la configuration persistante (JSON)."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import secrets
|
||||
from pathlib import Path
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
DATA_DIR = Path(__file__).parent / "data"
|
||||
CONFIG_FILE = DATA_DIR / "config.json"
|
||||
ALERTS_FILE = DATA_DIR / "alerts.json"
|
||||
MAX_ALERTS = 500
|
||||
|
||||
|
||||
def get_default_config():
|
||||
return {
|
||||
"secret_key": secrets.token_hex(32),
|
||||
"port": 5000,
|
||||
"check_interval_minutes": 1,
|
||||
"alert_cooldown_minutes": 30,
|
||||
"thresholds": {
|
||||
"cpu_percent": 90,
|
||||
"ram_percent": 85,
|
||||
"disk_percent": 90,
|
||||
},
|
||||
"processes": [
|
||||
{
|
||||
"name": "JVM",
|
||||
"pattern": "java",
|
||||
"memory_threshold_mb": 0,
|
||||
"enabled": True,
|
||||
"alert_on_down": True,
|
||||
},
|
||||
{
|
||||
"name": "Nginx",
|
||||
"pattern": "nginx",
|
||||
"memory_threshold_mb": 0,
|
||||
"enabled": False,
|
||||
"alert_on_down": False,
|
||||
},
|
||||
{
|
||||
"name": "Amadea Web 8 x64",
|
||||
"pattern": "amadea",
|
||||
"memory_threshold_mb": 0,
|
||||
"enabled": True,
|
||||
"alert_on_down": True,
|
||||
},
|
||||
],
|
||||
"smtp": {
|
||||
"server": "",
|
||||
"port": 587,
|
||||
"use_tls": True,
|
||||
"username": "",
|
||||
"password": "",
|
||||
"from_email": "",
|
||||
"to_emails": [],
|
||||
},
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password_hash": generate_password_hash("admin"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
def __init__(self):
|
||||
DATA_DIR.mkdir(exist_ok=True)
|
||||
self._config = self._load()
|
||||
|
||||
def _load(self):
|
||||
if CONFIG_FILE.exists():
|
||||
with open(CONFIG_FILE, "r", encoding="utf-8") as f:
|
||||
saved = json.load(f)
|
||||
# Fusionner avec les valeurs par defaut (nouvelles cles)
|
||||
default = get_default_config()
|
||||
for key, val in default.items():
|
||||
if key not in saved:
|
||||
saved[key] = val
|
||||
return saved
|
||||
else:
|
||||
config = get_default_config()
|
||||
self._save(config)
|
||||
return config
|
||||
|
||||
def _save(self, config=None):
|
||||
if config is None:
|
||||
config = self._config
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump(config, f, indent=2, ensure_ascii=False)
|
||||
|
||||
def reload(self):
|
||||
self._config = self._load()
|
||||
|
||||
def get(self, key, default=None):
|
||||
return self._config.get(key, default)
|
||||
|
||||
def set(self, key, value):
|
||||
self._config[key] = value
|
||||
self._save()
|
||||
|
||||
def update(self, data: dict):
|
||||
self._config.update(data)
|
||||
self._save()
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
return self._config
|
||||
|
||||
# --- Alertes persistees ---
|
||||
|
||||
def load_alerts(self):
|
||||
if ALERTS_FILE.exists():
|
||||
with open(ALERTS_FILE, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
return []
|
||||
|
||||
def save_alert(self, alert: dict):
|
||||
alerts = self.load_alerts()
|
||||
alerts.insert(0, alert)
|
||||
alerts = alerts[:MAX_ALERTS]
|
||||
with open(ALERTS_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump(alerts, f, indent=2, ensure_ascii=False)
|
||||
|
||||
def clear_alerts(self):
|
||||
with open(ALERTS_FILE, "w", encoding="utf-8") as f:
|
||||
json.dump([], f)
|
||||
Reference in New Issue
Block a user