""" utils/logger.py - Logging-Modul für den Dr. Franz Psychochatbot Dieses Modul stellt Logging-Funktionalitäten bereit: - Protokollierung von Aktivitäten - Unterstützung beim Debugging - Überwachung der Performance """ import logging import os import time from datetime import datetime from typing import Optional, Dict, Any # Importieren der Konfiguration import config class Logger: """Klasse zur Verwaltung des Loggings""" def __init__(self, log_level: str = config.LOG_LEVEL): """ Initialisiert den Logger Args: log_level: Das Log-Level (DEBUG, INFO, WARNING, ERROR, CRITICAL) """ self.log_level = log_level self.logger = self._setup_logger() self.start_time = time.time() self.interaction_count = 0 def _setup_logger(self) -> logging.Logger: """ Richtet den Logger ein Returns: Konfigurierter Logger """ # Log-Level aus String in Logging-Konstante umwandeln numeric_level = getattr(logging, self.log_level.upper(), logging.INFO) # Logger konfigurieren logger = logging.getLogger("psychobot") logger.setLevel(numeric_level) # Handler für Konsolenausgabe console_handler = logging.StreamHandler() console_handler.setLevel(numeric_level) # Formatter für lesbares Format formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) # Handler hinzufügen, falls noch nicht vorhanden if not logger.handlers: logger.addHandler(console_handler) return logger def log_startup(self) -> None: """Protokolliert den Start der Anwendung""" self.logger.info(f"=== {config.CHATBOT_TITLE} gestartet ===") self.logger.info(f"Verwende Modell: {config.MODEL_ID}") self.logger.info(f"Debug-Modus: {config.DEBUG_MODE}") self.logger.info(f"API-Token vorhanden: {bool(config.API_TOKEN)}") def log_user_input(self, user_input: str) -> None: """ Protokolliert eine Nutzereingabe Args: user_input: Die Eingabe des Nutzers """ self.interaction_count += 1 self.logger.info(f"Nutzeranfrage #{self.interaction_count}: {user_input[:50]}...") def log_bot_response(self, response: str, generation_time: float) -> None: """ Protokolliert eine Bot-Antwort Args: response: Die Antwort des Bots generation_time: Die Zeit zur Generierung der Antwort in Sekunden """ self.logger.info(f"Bot-Antwort #{self.interaction_count}: {response[:50]}... (Generiert in {generation_time:.2f}s)") def log_api_request(self, model_id: str, prompt_length: int) -> None: """ Protokolliert eine API-Anfrage Args: model_id: Die ID des verwendeten Modells prompt_length: Die Länge des Prompts in Zeichen """ self.logger.debug(f"API-Anfrage an {model_id} mit Prompt-Länge: {prompt_length} Zeichen") def log_api_response(self, status_code: int, response_time: float) -> None: """ Protokolliert eine API-Antwort Args: status_code: Der HTTP-Statuscode response_time: Die Antwortzeit in Sekunden """ self.logger.debug(f"API-Antwort erhalten: Status {status_code}, Zeit: {response_time:.2f}s") def log_error(self, error_type: str, error_message: str, details: Optional[Dict[str, Any]] = None) -> None: """ Protokolliert einen Fehler Args: error_type: Der Typ des Fehlers error_message: Die Fehlermeldung details: Optional, zusätzliche Details zum Fehler """ self.logger.error(f"FEHLER - {error_type}: {error_message}") if details and config.DEBUG_MODE: self.logger.error(f"Details: {details}") def log_performance_stats(self) -> Dict[str, Any]: """ Protokolliert Performance-Statistiken Returns: Dictionary mit Performance-Statistiken """ uptime = time.time() - self.start_time hours, remainder = divmod(uptime, 3600) minutes, seconds = divmod(remainder, 60) stats = { "uptime": f"{int(hours)}h {int(minutes)}m {int(seconds)}s", "interactions": self.interaction_count, "interactions_per_hour": round(self.interaction_count / (uptime / 3600), 2) if uptime > 0 else 0 } self.logger.info(f"Performance-Statistiken: Laufzeit {stats['uptime']}, " f"{stats['interactions']} Interaktionen, " f"{stats['interactions_per_hour']} Interaktionen/Stunde") return stats