Add DEV_MODE with comprehensive logging for error diagnosis
- DEV_MODE flag in config.py (env var, default true for dev server) - Log rotation: 5 MB max, 5 backups (RotatingFileHandler) - DEBUG level in dev mode, INFO in production - HTTP request logging middleware (dev mode only, skips static files) - External library log levels suppressed (httpx, httpcore, uvicorn) - Customer version: set DEV_MODE=false to disable verbose logging Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -28,6 +28,10 @@ CLAUDE_MODEL_FAST = "claude-haiku-4-5-20251001" # Für einfache Aufgaben (Feed-
|
||||
# Ausgabesprache (Lagebilder, Faktenchecks, Zusammenfassungen)
|
||||
OUTPUT_LANGUAGE = "Deutsch"
|
||||
|
||||
# Dev-Modus: ausfuehrliches Logging (DEBUG-Level, HTTP-Request-Log)
|
||||
# In Kundenversion auf False setzen oder Env-Variable entfernen
|
||||
DEV_MODE = os.environ.get("DEV_MODE", "true").lower() == "true"
|
||||
|
||||
# RSS-Feeds (Fallback, primär aus DB geladen)
|
||||
RSS_FEEDS = {
|
||||
"deutsch": [
|
||||
|
||||
54
src/main.py
54
src/main.py
@@ -15,7 +15,7 @@ from fastapi.responses import FileResponse, RedirectResponse
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
|
||||
from config import STATIC_DIR, LOG_DIR, DATA_DIR, TIMEZONE
|
||||
from config import STATIC_DIR, LOG_DIR, DATA_DIR, TIMEZONE, DEV_MODE
|
||||
from database import init_db, get_db
|
||||
from auth import decode_token
|
||||
from agents.orchestrator import orchestrator
|
||||
@@ -25,15 +25,33 @@ from services.fact_consolidation import consolidate_fact_checks
|
||||
|
||||
# Logging
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
||||
handlers=[
|
||||
logging.StreamHandler(sys.stdout),
|
||||
logging.FileHandler(os.path.join(LOG_DIR, "osint-monitor.log")),
|
||||
],
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import time as _time
|
||||
|
||||
_log_level = logging.DEBUG if DEV_MODE else logging.INFO
|
||||
_file_handler = RotatingFileHandler(
|
||||
os.path.join(LOG_DIR, "osint-monitor.log"),
|
||||
maxBytes=5 * 1024 * 1024, # 5 MB
|
||||
backupCount=5,
|
||||
encoding="utf-8",
|
||||
)
|
||||
_file_handler.setLevel(_log_level)
|
||||
_console_handler = logging.StreamHandler(sys.stdout)
|
||||
_console_handler.setLevel(_log_level)
|
||||
|
||||
logging.basicConfig(
|
||||
level=_log_level,
|
||||
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
||||
handlers=[_console_handler, _file_handler],
|
||||
)
|
||||
# Externe Bibliotheken nicht auf DEBUG setzen
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|
||||
logging.getLogger("apscheduler").setLevel(logging.INFO)
|
||||
|
||||
logger = logging.getLogger("osint")
|
||||
logger.info(f"Monitor gestartet (DEV_MODE={DEV_MODE}, Log-Level={logging.getLevelName(_log_level)})")
|
||||
|
||||
|
||||
class WebSocketManager:
|
||||
@@ -255,6 +273,24 @@ app = FastAPI(
|
||||
)
|
||||
|
||||
|
||||
# Request-Logging Middleware (nur im Dev-Modus)
|
||||
if DEV_MODE:
|
||||
_req_logger = logging.getLogger("osint.http")
|
||||
|
||||
class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
start = _time.monotonic()
|
||||
response = await call_next(request)
|
||||
duration = (_time.monotonic() - start) * 1000
|
||||
# Statische Dateien und WebSocket-Upgrades nicht loggen
|
||||
path = request.url.path
|
||||
if not path.startswith(("/static/", "/favicon")) and "websocket" not in str(request.headers.get("upgrade", "")):
|
||||
_req_logger.debug(
|
||||
f"{request.method} {path} -> {response.status_code} ({duration:.0f}ms)"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
# Security-Headers Middleware
|
||||
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
@@ -275,6 +311,8 @@ class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
||||
|
||||
|
||||
app.add_middleware(SecurityHeadersMiddleware)
|
||||
if DEV_MODE:
|
||||
app.add_middleware(RequestLoggingMiddleware)
|
||||
|
||||
# CORS
|
||||
app.add_middleware(
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren