# app/logging_setup.py import logging import sys _LOGGING_WIRED = False # module-level guard def _clear(logger: logging.Logger) -> None: for h in list(logger.handlers): logger.removeHandler(h) def wire_logging_once(app) -> None: global _LOGGING_WIRED if _LOGGING_WIRED: return _LOGGING_WIRED = True # Reuse gunicorn handlers if present guni = logging.getLogger("gunicorn.error") # Clear Flask's default handlers try: app.logger.handlers.clear() except Exception: for h in list(app.logger.handlers): app.logger.removeHandler(h) for name in ("sneakyscope.app", "sneakyscope.engine"): _clear(logging.getLogger(name)) # Fallback formatter shows logger name to distinguish engine/app h = logging.StreamHandler(sys.stdout) fmt = logging.Formatter( "[%(asctime)s] pid=%(process)d %(levelname)-8s %(name)s %(module)-18s %(message)s (line %(lineno)s)" ) h.setFormatter(fmt) h.setFormatter(fmt) h.setLevel(logging.INFO) # 3) Attach to app + project loggers; stop propagation everywhere app.logger.addHandler(h); app.logger.setLevel(logging.INFO); app.logger.propagate = False eng = logging.getLogger("sneakyscope.engine") app_lg = logging.getLogger("sneakyscope.app") eng.addHandler(h); eng.setLevel(logging.INFO); eng.propagate = False app_lg.addHandler(h); app_lg.setLevel(logging.INFO); app_lg.propagate = False def get_engine_logger() -> logging.Logger: logger = logging.getLogger("sneakyscope.engine") logger.propagate = False if logger.level == logging.NOTSET: logger.setLevel(logging.INFO) return logger def get_app_logger() -> logging.Logger: logger = logging.getLogger("sneakyscope.app") logger.propagate = False if logger.level == logging.NOTSET: logger.setLevel(logging.INFO) return logger