340 lines
11 KiB
Python
340 lines
11 KiB
Python
#!/usr/bin/env python3.11
|
|
"""
|
|
Monitoring & Analytics - ULTRA KONSOLIDIERUNG
|
|
=============================================
|
|
|
|
Migration Information:
|
|
- Ursprünglich: analytics.py, performance_tracker.py, report_generator.py
|
|
- Konsolidiert am: 2025-06-09
|
|
- Funktionalitäten: System-Monitoring, Performance-Tracking, Report-Generierung
|
|
- Breaking Changes: Keine - Alle Original-APIs bleiben verfügbar
|
|
|
|
ULTRA KONSOLIDIERUNG für Projektarbeit MYP
|
|
Author: MYP Team - Till Tomczak
|
|
Ziel: DRASTISCHE Datei-Reduktion!
|
|
"""
|
|
|
|
import time
|
|
import json
|
|
import psutil
|
|
import threading
|
|
from datetime import datetime, timedelta
|
|
from typing import Dict, List, Any, Optional
|
|
from reportlab.pdfgen import canvas
|
|
from reportlab.lib.pagesizes import letter, A4
|
|
import matplotlib.pyplot as plt
|
|
import pandas as pd
|
|
|
|
from utils.logging_config import get_logger
|
|
|
|
# Logger
|
|
monitor_logger = get_logger("monitoring_analytics")
|
|
|
|
# ===== PERFORMANCE TRACKER =====
|
|
|
|
class PerformanceTracker:
|
|
"""System-Performance Monitoring"""
|
|
|
|
def __init__(self):
|
|
self.metrics = {}
|
|
self.start_time = time.time()
|
|
self.tracking = True
|
|
|
|
def track_cpu_usage(self) -> float:
|
|
"""CPU-Auslastung messen"""
|
|
return psutil.cpu_percent(interval=1)
|
|
|
|
def track_memory_usage(self) -> Dict[str, Any]:
|
|
"""Speicher-Auslastung messen"""
|
|
memory = psutil.virtual_memory()
|
|
return {
|
|
'total': memory.total,
|
|
'available': memory.available,
|
|
'percent': memory.percent,
|
|
'used': memory.used,
|
|
'free': memory.free
|
|
}
|
|
|
|
def track_disk_usage(self) -> Dict[str, Any]:
|
|
"""Festplatten-Auslastung messen"""
|
|
disk = psutil.disk_usage('/')
|
|
return {
|
|
'total': disk.total,
|
|
'used': disk.used,
|
|
'free': disk.free,
|
|
'percent': (disk.used / disk.total) * 100
|
|
}
|
|
|
|
def get_system_metrics(self) -> Dict[str, Any]:
|
|
"""Vollständige System-Metriken"""
|
|
return {
|
|
'timestamp': datetime.now().isoformat(),
|
|
'uptime': time.time() - self.start_time,
|
|
'cpu': self.track_cpu_usage(),
|
|
'memory': self.track_memory_usage(),
|
|
'disk': self.track_disk_usage()
|
|
}
|
|
|
|
# ===== ANALYTICS ENGINE =====
|
|
|
|
class AnalyticsEngine:
|
|
"""System-Analytics und Metriken"""
|
|
|
|
def __init__(self):
|
|
self.data_store = {}
|
|
|
|
def collect_job_analytics(self) -> Dict[str, Any]:
|
|
"""Sammelt Job-Analytics"""
|
|
try:
|
|
from models import get_db_session, Job
|
|
|
|
db_session = get_db_session()
|
|
jobs = db_session.query(Job).all()
|
|
|
|
analytics = {
|
|
'total_jobs': len(jobs),
|
|
'status_distribution': {},
|
|
'print_time_stats': [],
|
|
'success_rate': 0,
|
|
'daily_jobs': {}
|
|
}
|
|
|
|
# Status-Verteilung
|
|
for job in jobs:
|
|
status = job.status or 'unknown'
|
|
analytics['status_distribution'][status] = \
|
|
analytics['status_distribution'].get(status, 0) + 1
|
|
|
|
# Erfolgsrate
|
|
completed = analytics['status_distribution'].get('completed', 0)
|
|
if len(jobs) > 0:
|
|
analytics['success_rate'] = (completed / len(jobs)) * 100
|
|
|
|
# Druckzeit-Statistiken
|
|
print_times = [j.print_time for j in jobs if j.print_time]
|
|
if print_times:
|
|
analytics['print_time_stats'] = {
|
|
'avg': sum(print_times) / len(print_times),
|
|
'min': min(print_times),
|
|
'max': max(print_times),
|
|
'total': sum(print_times)
|
|
}
|
|
|
|
db_session.close()
|
|
return analytics
|
|
|
|
except Exception as e:
|
|
monitor_logger.error(f"Job-Analytics Fehler: {e}")
|
|
return {'error': str(e)}
|
|
|
|
def collect_printer_analytics(self) -> Dict[str, Any]:
|
|
"""Sammelt Drucker-Analytics"""
|
|
try:
|
|
from models import get_db_session, Printer
|
|
|
|
db_session = get_db_session()
|
|
printers = db_session.query(Printer).all()
|
|
|
|
analytics = {
|
|
'total_printers': len(printers),
|
|
'status_distribution': {},
|
|
'usage_stats': {},
|
|
'location_stats': {}
|
|
}
|
|
|
|
# Status-Verteilung
|
|
for printer in printers:
|
|
status = printer.status or 'unknown'
|
|
analytics['status_distribution'][status] = \
|
|
analytics['status_distribution'].get(status, 0) + 1
|
|
|
|
# Location-Statistiken
|
|
location = printer.location or 'unknown'
|
|
analytics['location_stats'][location] = \
|
|
analytics['location_stats'].get(location, 0) + 1
|
|
|
|
db_session.close()
|
|
return analytics
|
|
|
|
except Exception as e:
|
|
monitor_logger.error(f"Drucker-Analytics Fehler: {e}")
|
|
return {'error': str(e)}
|
|
|
|
# ===== REPORT GENERATOR =====
|
|
|
|
class ReportGenerator:
|
|
"""PDF/Excel-Report-Generator"""
|
|
|
|
def __init__(self):
|
|
self.reports_path = "backend/uploads/reports/"
|
|
|
|
def generate_system_report(self) -> str:
|
|
"""Generiert System-Status-Report"""
|
|
try:
|
|
filename = f"system_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
|
|
filepath = f"{self.reports_path}{filename}"
|
|
|
|
c = canvas.Canvas(filepath, pagesize=A4)
|
|
width, height = A4
|
|
|
|
# Header
|
|
c.setFont("Helvetica-Bold", 16)
|
|
c.drawString(50, height - 50, "MYP System Report")
|
|
c.drawString(50, height - 70, f"Generiert: {datetime.now().strftime('%d.%m.%Y %H:%M')}")
|
|
|
|
# Performance-Daten
|
|
performance = PerformanceTracker()
|
|
metrics = performance.get_system_metrics()
|
|
|
|
y_pos = height - 120
|
|
c.setFont("Helvetica-Bold", 12)
|
|
c.drawString(50, y_pos, "System-Performance:")
|
|
|
|
y_pos -= 30
|
|
c.setFont("Helvetica", 10)
|
|
c.drawString(70, y_pos, f"CPU-Auslastung: {metrics['cpu']:.1f}%")
|
|
y_pos -= 20
|
|
c.drawString(70, y_pos, f"Arbeitsspeicher: {metrics['memory']['percent']:.1f}%")
|
|
y_pos -= 20
|
|
c.drawString(70, y_pos, f"Festplatte: {metrics['disk']['percent']:.1f}%")
|
|
|
|
# Analytics-Daten
|
|
analytics = AnalyticsEngine()
|
|
job_analytics = analytics.collect_job_analytics()
|
|
|
|
y_pos -= 50
|
|
c.setFont("Helvetica-Bold", 12)
|
|
c.drawString(50, y_pos, "Job-Statistiken:")
|
|
|
|
y_pos -= 30
|
|
c.setFont("Helvetica", 10)
|
|
c.drawString(70, y_pos, f"Gesamt-Jobs: {job_analytics.get('total_jobs', 0)}")
|
|
y_pos -= 20
|
|
c.drawString(70, y_pos, f"Erfolgsrate: {job_analytics.get('success_rate', 0):.1f}%")
|
|
|
|
c.save()
|
|
monitor_logger.info(f"System-Report generiert: {filename}")
|
|
return filename
|
|
|
|
except Exception as e:
|
|
monitor_logger.error(f"Report-Generierung Fehler: {e}")
|
|
return None
|
|
|
|
def generate_usage_report(self, start_date: datetime, end_date: datetime) -> str:
|
|
"""Generiert Nutzungs-Report für Zeitraum"""
|
|
try:
|
|
filename = f"usage_report_{start_date.strftime('%Y%m%d')}_to_{end_date.strftime('%Y%m%d')}.pdf"
|
|
filepath = f"{self.reports_path}{filename}"
|
|
|
|
c = canvas.Canvas(filepath, pagesize=A4)
|
|
width, height = A4
|
|
|
|
# Header
|
|
c.setFont("Helvetica-Bold", 16)
|
|
c.drawString(50, height - 50, "MYP Nutzungsreport")
|
|
c.drawString(50, height - 70, f"Zeitraum: {start_date.strftime('%d.%m.%Y')} - {end_date.strftime('%d.%m.%Y')}")
|
|
|
|
# Hier würden weitere Statistiken eingefügt
|
|
|
|
c.save()
|
|
monitor_logger.info(f"Nutzungs-Report generiert: {filename}")
|
|
return filename
|
|
|
|
except Exception as e:
|
|
monitor_logger.error(f"Nutzungs-Report Fehler: {e}")
|
|
return None
|
|
|
|
# ===== MONITORING DASHBOARD =====
|
|
|
|
class MonitoringDashboard:
|
|
"""Real-time Monitoring Dashboard"""
|
|
|
|
def __init__(self):
|
|
self.performance_tracker = PerformanceTracker()
|
|
self.analytics_engine = AnalyticsEngine()
|
|
|
|
def get_dashboard_data(self) -> Dict[str, Any]:
|
|
"""Holt alle Dashboard-Daten"""
|
|
return {
|
|
'timestamp': datetime.now().isoformat(),
|
|
'system_metrics': self.performance_tracker.get_system_metrics(),
|
|
'job_analytics': self.analytics_engine.collect_job_analytics(),
|
|
'printer_analytics': self.analytics_engine.collect_printer_analytics()
|
|
}
|
|
|
|
def get_health_status(self) -> Dict[str, Any]:
|
|
"""System-Gesundheitsstatus"""
|
|
metrics = self.performance_tracker.get_system_metrics()
|
|
|
|
status = 'healthy'
|
|
alerts = []
|
|
|
|
# CPU-Check
|
|
if metrics['cpu'] > 80:
|
|
status = 'warning'
|
|
alerts.append('Hohe CPU-Auslastung')
|
|
|
|
# Memory-Check
|
|
if metrics['memory']['percent'] > 85:
|
|
status = 'critical' if status != 'critical' else status
|
|
alerts.append('Hoher Arbeitsspeicherverbrauch')
|
|
|
|
# Disk-Check
|
|
if metrics['disk']['percent'] > 90:
|
|
status = 'critical'
|
|
alerts.append('Festplatte fast voll')
|
|
|
|
return {
|
|
'status': status,
|
|
'alerts': alerts,
|
|
'metrics': metrics
|
|
}
|
|
|
|
# ===== GLOBALE INSTANZEN =====
|
|
|
|
performance_tracker = PerformanceTracker()
|
|
analytics_engine = AnalyticsEngine()
|
|
report_generator = ReportGenerator()
|
|
monitoring_dashboard = MonitoringDashboard()
|
|
|
|
# ===== CONVENIENCE FUNCTIONS =====
|
|
|
|
def get_system_performance() -> Dict[str, Any]:
|
|
"""Holt System-Performance-Daten"""
|
|
return performance_tracker.get_system_metrics()
|
|
|
|
def get_job_statistics() -> Dict[str, Any]:
|
|
"""Holt Job-Statistiken"""
|
|
return analytics_engine.collect_job_analytics()
|
|
|
|
def get_printer_statistics() -> Dict[str, Any]:
|
|
"""Holt Drucker-Statistiken"""
|
|
return analytics_engine.collect_printer_analytics()
|
|
|
|
def generate_system_report() -> str:
|
|
"""Generiert System-Report"""
|
|
return report_generator.generate_system_report()
|
|
|
|
def get_health_check() -> Dict[str, Any]:
|
|
"""System-Gesundheitscheck"""
|
|
return monitoring_dashboard.get_health_status()
|
|
|
|
# ===== LEGACY COMPATIBILITY =====
|
|
|
|
# Original analytics.py compatibility
|
|
def collect_analytics_data():
|
|
"""Legacy-Wrapper für Analytics"""
|
|
return analytics_engine.collect_job_analytics()
|
|
|
|
# Original performance_tracker.py compatibility
|
|
def track_performance():
|
|
"""Legacy-Wrapper für Performance-Tracking"""
|
|
return performance_tracker.get_system_metrics()
|
|
|
|
# Original report_generator.py compatibility
|
|
def create_pdf_report():
|
|
"""Legacy-Wrapper für PDF-Report"""
|
|
return report_generator.generate_system_report()
|
|
|
|
monitor_logger.info("✅ Monitoring & Analytics Module initialisiert")
|
|
monitor_logger.info("📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)") |