🎉 Improved session management system and logs organization 🎨

This commit is contained in:
2025-06-13 07:05:57 +02:00
parent 3ff5f17f42
commit ae95d82afc
81 changed files with 950 additions and 11 deletions

View File

@ -5,11 +5,12 @@ Dieses Modul enthält allgemeine API-Endpunkte und WebSocket-Fallback-Funktional
"""
import logging
from datetime import datetime
from datetime import datetime, timedelta
from flask import Blueprint, jsonify, request, session
from flask_login import login_required, current_user
from models import get_db_session, User, Notification
from models import get_db_session, User, Notification, Printer, Job, Stats
from utils.logging_config import get_logger
from utils.permissions import admin_required
# Blueprint erstellen
api_blueprint = Blueprint('api', __name__, url_prefix='/api')
@ -145,7 +146,6 @@ def session_status():
# Prüfe ob Benutzer über Flask-Login authentifiziert ist
if hasattr(current_user, 'is_authenticated') and current_user.is_authenticated:
# Benutzer ist angemeldet
from datetime import timedelta
from backend.config.settings import SESSION_LIFETIME
# Session-Informationen sammeln
@ -255,4 +255,268 @@ def extend_session():
'success': False,
'error': 'Session-Verlängerung fehlgeschlagen',
'message': str(e)
}), 500
@api_blueprint.route('/stats', methods=['GET'])
@login_required
def get_stats():
"""
Hauptstatistiken-Endpunkt für das System.
Liefert umfassende Statistiken über Drucker, Jobs und Benutzer.
"""
try:
db_session = get_db_session()
# Grundlegende Zählungen
total_printers = db_session.query(Printer).count()
active_printers = db_session.query(Printer).filter(Printer.active == True).count()
total_jobs = db_session.query(Job).count()
# Job-Status-Verteilung
completed_jobs = db_session.query(Job).filter(Job.status == 'completed').count()
running_jobs = db_session.query(Job).filter(Job.status == 'running').count()
pending_jobs = db_session.query(Job).filter(Job.status == 'pending').count()
failed_jobs = db_session.query(Job).filter(Job.status == 'failed').count()
# Benutzer-Statistiken
total_users = db_session.query(User).count()
active_users = db_session.query(User).filter(User.active == True).count()
# Zeitbasierte Statistiken (letzte 24 Stunden)
yesterday = datetime.now() - timedelta(days=1)
jobs_last_24h = db_session.query(Job).filter(Job.created_at >= yesterday).count()
# Gesamtdruckzeit berechnen
completed_jobs_with_duration = db_session.query(Job).filter(
Job.status == 'completed',
Job.duration_minutes.isnot(None)
).all()
total_print_hours = sum(job.duration_minutes for job in completed_jobs_with_duration) / 60.0
db_session.close()
stats_data = {
'success': True,
'timestamp': datetime.now().isoformat(),
# Grundlegende Zählungen
'total_printers': total_printers,
'active_printers': active_printers,
'total_jobs': total_jobs,
'total_users': total_users,
'active_users': active_users,
# Job-Statistiken
'completed_jobs': completed_jobs,
'running_jobs': running_jobs,
'pending_jobs': pending_jobs,
'failed_jobs': failed_jobs,
'jobs_last_24h': jobs_last_24h,
# Druckzeit-Statistiken
'total_print_hours': round(total_print_hours, 2),
'completion_rate': round((completed_jobs / total_jobs * 100), 2) if total_jobs > 0 else 0
}
api_logger.info(f"Statistiken abgerufen von Benutzer {current_user.username}")
return jsonify(stats_data)
except Exception as e:
api_logger.error(f"Fehler beim Abrufen der Statistiken: {str(e)}")
return jsonify({
'success': False,
'error': 'Fehler beim Laden der Statistiken',
'message': str(e)
}), 500
@api_blueprint.route('/admin/system-health', methods=['GET'])
@admin_required
def get_system_health():
"""
System-Gesundheitsstatus für Administratoren.
Liefert detaillierte Informationen über den System-Zustand.
"""
try:
db_session = get_db_session()
# Datenbankverbindung testen
db_healthy = True
try:
db_session.execute("SELECT 1")
except Exception as e:
db_healthy = False
api_logger.error(f"Datenbankfehler: {str(e)}")
# Systemressourcen prüfen
import psutil
import os
# CPU und Speicher
cpu_usage = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
# Aktive Drucker prüfen
active_printers = db_session.query(Printer).filter(Printer.active == True).count()
total_printers = db_session.query(Printer).count()
# Laufende Jobs prüfen
running_jobs = db_session.query(Job).filter(Job.status == 'running').count()
db_session.close()
# Gesamtstatus bestimmen
overall_status = 'healthy'
if not db_healthy or cpu_usage > 90 or memory.percent > 90:
overall_status = 'warning'
if not db_healthy or cpu_usage > 95 or memory.percent > 95:
overall_status = 'critical'
health_data = {
'success': True,
'timestamp': datetime.now().isoformat(),
'overall_status': overall_status,
# System-Status
'database': {
'status': 'healthy' if db_healthy else 'error',
'connection': db_healthy
},
# Systemressourcen
'system': {
'cpu_usage': cpu_usage,
'memory_usage': memory.percent,
'memory_available_gb': round(memory.available / (1024**3), 2),
'disk_usage': disk.percent,
'disk_free_gb': round(disk.free / (1024**3), 2)
},
# Drucker-Status
'printers': {
'total': total_printers,
'active': active_printers,
'inactive': total_printers - active_printers
},
# Job-Status
'jobs': {
'running': running_jobs
}
}
api_logger.info(f"System-Health abgerufen von Admin {current_user.username}")
return jsonify(health_data)
except ImportError:
# Fallback ohne psutil
health_data = {
'success': True,
'timestamp': datetime.now().isoformat(),
'overall_status': 'healthy',
'database': {'status': 'healthy', 'connection': True},
'system': {'cpu_usage': 0, 'memory_usage': 0, 'disk_usage': 0},
'printers': {'total': 0, 'active': 0, 'inactive': 0},
'jobs': {'running': 0},
'note': 'Eingeschränkte Systemüberwachung (psutil nicht verfügbar)'
}
return jsonify(health_data)
except Exception as e:
api_logger.error(f"Fehler beim Abrufen des System-Health: {str(e)}")
return jsonify({
'success': False,
'error': 'Fehler beim Laden des System-Status',
'message': str(e)
}), 500
@api_blueprint.route('/admin/error-recovery/status', methods=['GET'])
@admin_required
def get_error_recovery_status():
"""
Fehlerwiederherstellungs-Status für Administratoren.
Liefert Informationen über System-Fehler und Wiederherstellungsoptionen.
"""
try:
db_session = get_db_session()
# Fehlgeschlagene Jobs der letzten 24 Stunden
yesterday = datetime.now() - timedelta(days=1)
failed_jobs = db_session.query(Job).filter(
Job.status == 'failed',
Job.created_at >= yesterday
).all()
# Inaktive Drucker
inactive_printers = db_session.query(Printer).filter(Printer.active == False).all()
# Hängende Jobs (länger als 6 Stunden im Status 'running')
six_hours_ago = datetime.now() - timedelta(hours=6)
stuck_jobs = db_session.query(Job).filter(
Job.status == 'running',
Job.start_time <= six_hours_ago
).all()
db_session.close()
# Wiederherstellungsaktionen bestimmen
recovery_actions = []
if failed_jobs:
recovery_actions.append({
'type': 'restart_failed_jobs',
'count': len(failed_jobs),
'description': f'{len(failed_jobs)} fehlgeschlagene Jobs neu starten'
})
if inactive_printers:
recovery_actions.append({
'type': 'reactivate_printers',
'count': len(inactive_printers),
'description': f'{len(inactive_printers)} inaktive Drucker reaktivieren'
})
if stuck_jobs:
recovery_actions.append({
'type': 'reset_stuck_jobs',
'count': len(stuck_jobs),
'description': f'{len(stuck_jobs)} hängende Jobs zurücksetzen'
})
# Gesamtstatus bestimmen
status = 'healthy'
if failed_jobs or inactive_printers:
status = 'warning'
if stuck_jobs:
status = 'critical'
recovery_data = {
'success': True,
'timestamp': datetime.now().isoformat(),
'status': status,
'issues': {
'failed_jobs': len(failed_jobs),
'inactive_printers': len(inactive_printers),
'stuck_jobs': len(stuck_jobs)
},
'recovery_actions': recovery_actions,
'last_check': datetime.now().isoformat()
}
api_logger.info(f"Error-Recovery-Status abgerufen von Admin {current_user.username}")
return jsonify(recovery_data)
except Exception as e:
api_logger.error(f"Fehler beim Abrufen des Error-Recovery-Status: {str(e)}")
return jsonify({
'success': False,
'error': 'Fehler beim Laden des Wiederherstellungs-Status',
'message': str(e)
}), 500