Files
Projektarbeit-MYP/backend/utils/monitoring_analytics.py

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)")