From d51c07355611e2e58dfd4c113d4e539dec8c2a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Murat=20=C3=96ZDEM=C4=B0R?= Date: Fri, 26 Jun 2026 20:37:42 +0300 Subject: [PATCH] fix(health-agent): fix uk_tokens.yml load race and LogRecord msg conflict - config.py: Replace exists()+open() with try/except open() to avoid TOCTOU race on SSHFS mounts where stat can succeed but open can fail with FileNotFoundError. - uptime_kuma.py: Rename msg key to push_msg in logger extra dicts. Python LogRecord reserves the msg field; passing it in extra raises ValueError which was being silently swallowed by the except block, masking successful pushes as errors. --- health-agent/src/health_agent/config.py | 8 ++++---- health-agent/src/health_agent/uptime_kuma.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/health-agent/src/health_agent/config.py b/health-agent/src/health_agent/config.py index dbff2be..c00ad28 100644 --- a/health-agent/src/health_agent/config.py +++ b/health-agent/src/health_agent/config.py @@ -16,10 +16,10 @@ EXTERNAL_DOMAIN = os.getenv("EXTERNAL_DOMAIN", "iklim.co") EXTERNAL_SUBDOMAIN_SUFFIX = os.getenv("EXTERNAL_SUBDOMAIN_SUFFIX", "") def load_uk_tokens(): - token_file = Path("config/generated/uk_tokens.yml") - if not token_file.exists(): + try: + with open("config/generated/uk_tokens.yml", "r") as f: + return yaml.safe_load(f) or {} + except (FileNotFoundError, OSError): return {} - with open(token_file, "r") as f: - return yaml.safe_load(f) or {} UK_TOKENS = load_uk_tokens() diff --git a/health-agent/src/health_agent/uptime_kuma.py b/health-agent/src/health_agent/uptime_kuma.py index 357bc90..b0fcf53 100644 --- a/health-agent/src/health_agent/uptime_kuma.py +++ b/health-agent/src/health_agent/uptime_kuma.py @@ -15,7 +15,7 @@ def push(monitor_name: str, status: str, msg: str, ping_ms: int): return if DRY_RUN: - logger.info(f"[DRY-RUN] Would push {monitor_name} status={status} msg={msg} ping={ping_ms}ms", extra={"check": monitor_name, "status": status, "msg": msg, "ping_ms": ping_ms, "source": "uptime_kuma"}) + logger.info(f"[DRY-RUN] Would push {monitor_name} status={status} msg={msg} ping={ping_ms}ms", extra={"check": monitor_name, "status": status, "push_msg": msg, "ping_ms": ping_ms, "source": "uptime_kuma"}) return url = f"{UK_PUSH_URL_BASE}/{token}" @@ -28,6 +28,6 @@ def push(monitor_name: str, status: str, msg: str, ping_ms: int): try: response = requests.get(url, params=params, timeout=10) response.raise_for_status() - logger.info(f"Pushed {monitor_name} status={status}", extra={"check": monitor_name, "status": status, "msg": msg, "ping_ms": ping_ms, "source": "uptime_kuma"}) + logger.info(f"Pushed {monitor_name} status={status}", extra={"check": monitor_name, "status": status, "push_msg": msg, "ping_ms": ping_ms, "source": "uptime_kuma"}) except Exception as e: logger.error(f"Failed to push {monitor_name}: {e}", extra={"check": monitor_name, "status": "push_failed", "error": str(e), "source": "uptime_kuma"})