diff --git a/Dockerfile b/Dockerfile index 35ce411..d841956 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,6 +37,9 @@ RUN mkdir -p /app/config && mkdir -p /app/data # und Container-Erkennung für den Bridge-Restart (Supervisor startet neu statt subprocess). ENV KX_DATA_DIR=/app/data ENV KX_IN_DOCKER=1 +# Ohne das puffert Python stdout/stderr komplett wenn kein TTY angehängt ist - +# "docker logs" bleibt dann leer bis der Prozess beendet wird. +ENV PYTHONUNBUFFERED=1 EXPOSE 7125 diff --git a/kobrax_moonraker_bridge.py b/kobrax_moonraker_bridge.py index f369b7a..ba851e2 100644 --- a/kobrax_moonraker_bridge.py +++ b/kobrax_moonraker_bridge.py @@ -40,6 +40,21 @@ import sys import time import threading +# Must run before any extracted-module import below: bridge_endpoints pulls in +# bridge_logging, which attaches its browser-log handler to the root logger at +# import time. If that happens first, basicConfig() becomes a no-op (it only +# configures the root logger when it has no handlers yet) and every log.info/ +# warning call silently stops reaching stdout/stderr - "docker logs" then only +# ever shows whatever fired before this point (e.g. an early config warning). +logging.basicConfig(level=logging.INFO, + format="[%(asctime)s] %(levelname)-5s %(name)s: %(message)s", + datefmt="%H:%M:%S") +log = logging.getLogger("bridge") +# aiohttp logs one INFO line per HTTP request (access log) — with 2s frontend +# polling that drowns out the bridge's own logs by default. Toggleable at +# runtime via the verbose_http_log setting (see handle_api_settings_post). +logging.getLogger("aiohttp.access").setLevel(logging.WARNING) + # For PyInstaller binaries everything sits next to sys.executable, otherwise next to __file__ _BASE = os.path.dirname(sys.executable) if getattr(sys, "frozen", False) else os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, _BASE) @@ -74,15 +89,6 @@ except ImportError: print("Error: aiohttp is not installed. Run: pip install aiohttp") sys.exit(1) -logging.basicConfig(level=logging.INFO, - format="[%(asctime)s] %(levelname)-5s %(name)s: %(message)s", - datefmt="%H:%M:%S") -log = logging.getLogger("bridge") -# aiohttp logs one INFO line per HTTP request (access log) — with 2s frontend -# polling that drowns out the bridge's own logs by default. Toggleable at -# runtime via the verbose_http_log setting (see handle_api_settings_post). -logging.getLogger("aiohttp.access").setLevel(logging.WARNING) - # UI theme-name validation (used in __init__); the /kx/ui asset-serving # constants live in bridge_endpoints alongside their only consumers.