from __future__ import annotations import logging import os logger = logging.getLogger("s2s") _logging_configured = False if not _logging_configured: _handler = logging.StreamHandler() _handler.setFormatter( logging.Formatter( "%(asctime)s %(levelname)-7s [%(name)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) ) logging.basicConfig(level=logging.DEBUG, handlers=[_handler], force=True) _lvl_env = (os.environ.get("LOG_LEVEL") or os.environ.get("S2S_LOG_LEVEL") or "INFO").strip().upper() _is_debug = _lvl_env in {"DEBUG", "TRACE", "10"} # Keep noisy loggers quiet unless LOG_LEVEL explicitly enables debug. logging.getLogger("httpx").setLevel(logging.DEBUG if _is_debug else logging.WARNING) logging.getLogger("websockets").setLevel(logging.DEBUG if _is_debug else logging.INFO) logging.getLogger("uvicorn").setLevel(logging.DEBUG if _is_debug else logging.INFO) logging.getLogger("uvicorn.access").setLevel(logging.DEBUG if _is_debug else logging.INFO) logging.getLogger("httpcore").setLevel(logging.DEBUG if _is_debug else logging.WARNING) # The MCP SDK logs raw protocol messages and error bodies. Our integration # reports safe operation metadata and public errors at its own boundary. logging.getLogger("mcp").setLevel(logging.CRITICAL) logger.setLevel(logging.DEBUG if _is_debug else logging.DEBUG) # s2s always uses at least DEBUG in development _logging_configured = True logger.debug( "LOG_LEVEL env=%s — noisy-logger levels: httpx=%s uvicorn=%s websockets=%s", _lvl_env, logging.getLevelName(logging.getLogger("httpx").level), logging.getLevelName(logging.getLogger("uvicorn").level), logging.getLevelName(logging.getLogger("websockets").level), )