fix(logging): ensure docker logs show bridge output
logging.basicConfig() ran after bridge_endpoints (via bridge_logging) had already attached a handler to the root logger at import time, making basicConfig() a no-op per Python's docs (it only configures the root logger when it has none yet). Every log.info/warning call after that point silently stopped reaching stdout/stderr - "docker logs" only ever showed whatever fired before this point. Moved basicConfig() to run before any extracted-module import, and added PYTHONUNBUFFERED=1 so output isn't buffered away under a non-TTY container stdout.
This commit is contained in:
@ -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
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user