mindnet/app/core/logging_setup.py
Lars fa653be031 Make logging configurable via LOG_LEVEL and smaller rotating files.
Adds env overrides for log size and backup count, and documents them for operators. Drops noisy uvicorn/httpx/qdrant lines to WARNING so logs stay readable.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 17:25:09 +02:00

79 lines
3.0 KiB
Python

import logging
import os
from logging.handlers import RotatingFileHandler
# Umgebungsvariablen für Log-Begrenzung (weniger Zeilen, bessere Auswertbarkeit)
# LOG_LEVEL: INFO | WARNING | ERROR | DEBUG (Default: INFO, oder DEBUG wenn DEBUG=true)
# LOG_MAX_BYTES: Max. Größe einer Log-Datei in Bytes (Default: 1MB)
# LOG_BACKUP_COUNT: Anzahl rotierter Backups (Default: 2)
_LOG_LEVEL_MAP = {
"debug": logging.DEBUG,
"info": logging.INFO,
"warning": logging.WARNING,
"error": logging.ERROR,
}
# Laute Bibliotheken: nur WARNING+ in Datei/Konsole, reduziert Zeilen deutlich
_NOISY_LOGGERS = ("uvicorn", "uvicorn.access", "httpx", "httpcore", "qdrant_client")
def setup_logging(log_level: int = None):
"""
Konfiguriert das Logging-System mit File- und Console-Handler.
WP-24c v4.4.0-DEBUG: Unterstützt DEBUG-Level für End-to-End Tracing.
Log-Auswertbarkeit: Rotation und LOG_LEVEL begrenzen Dateigröße/Zeilen.
Args:
log_level: Optionales Log-Level (logging.DEBUG, logging.INFO, etc.)
Falls nicht gesetzt: LOG_LEVEL env, sonst DEBUG env, sonst INFO.
"""
# 1. Log-Level bestimmen (LOG_LEVEL hat Vorrang vor DEBUG)
if log_level is None:
env_level = (os.getenv("LOG_LEVEL") or "").strip().lower()
if env_level and env_level in _LOG_LEVEL_MAP:
log_level = _LOG_LEVEL_MAP[env_level]
else:
debug_mode = os.getenv("DEBUG", "false").lower() == "true"
log_level = logging.DEBUG if debug_mode else logging.INFO
# 2. Log-Verzeichnis erstellen (falls nicht vorhanden)
log_dir = "logs"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
log_file = os.path.join(log_dir, "mindnet.log")
# 3. Formatter definieren (Zeitstempel | Level | Modul | Nachricht)
formatter = logging.Formatter(
'%(asctime)s | %(levelname)-8s | %(name)s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 4. Rotation: kleinere Dateien = weniger Zeilen pro Datei, bessere Auswertbarkeit
max_bytes = int(os.getenv("LOG_MAX_BYTES", str(1 * 1024 * 1024))) # Default 1 MB
backup_count = int(os.getenv("LOG_BACKUP_COUNT", "2"))
file_handler = RotatingFileHandler(
log_file, maxBytes=max_bytes, backupCount=backup_count, encoding='utf-8'
)
file_handler.setFormatter(formatter)
file_handler.setLevel(log_level)
# 5. Stream Handler: Schreibt weiterhin auf die Konsole
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
console_handler.setLevel(log_level)
# 6. Root Logger konfigurieren
logging.basicConfig(
level=log_level,
handlers=[file_handler, console_handler],
force=True
)
# 7. Laute Bibliotheken drosseln (weniger Zeilen bei uvicorn/httpx/qdrant)
for name in _NOISY_LOGGERS:
logging.getLogger(name).setLevel(logging.WARNING)
level_name = logging.getLevelName(log_level)
logging.info(f"📝 Logging initialized (Level: {level_name}). File: {log_file}, maxBytes={max_bytes}, backups={backup_count}")