From f6fbb66cdcbbe078b9ee045f06952685b59195ba Mon Sep 17 00:00:00 2001 From: SashegDev Date: Thu, 7 May 2026 17:45:36 +0000 Subject: [PATCH] Server: PID-based logging - only master logs startup - Only master PID logs blocklist loading, pack scanning, etc. - Worker processes stay silent during startup - Much cleaner logs --- server/main.py | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/server/main.py b/server/main.py index ee81e00..c95cdad 100644 --- a/server/main.py +++ b/server/main.py @@ -1,5 +1,6 @@ import re import logging +import os from contextlib import asynccontextmanager from datetime import datetime from pathlib import Path @@ -17,6 +18,12 @@ from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("httpcore").setLevel(logging.WARNING) +# PID for logging (only master logs startup) +MASTER_PID = os.getpid() + +def is_master() -> bool: + return os.getpid() == MASTER_PID + from pack_manager import DATA_DIR, scan_pack, get_cached_manifest, PACKS_DIR from models import PackMeta from middleware import LoggingMiddleware @@ -64,10 +71,11 @@ async def lifespan(app: FastAPI): if BLOCKLIST_CACHE_FILE.exists(): try: cached_ips = set(BLOCKLIST_CACHE_FILE.read_text().strip().splitlines()) - if cached_ips: + if cached_ips and is_master(): logger.info(f"Loaded {len(cached_ips)} IPs from blocklist cache") except Exception as e: - logger.warning(f"Failed to load blocklist cache: {e}") + if is_master(): + logger.warning(f"Failed to load blocklist cache: {e}") # If no cache, download (only one worker will do this) if not cached_ips: @@ -84,20 +92,22 @@ async def lifespan(app: FastAPI): cached_ips = mw.load_public_blocklists() if cached_ips: BLOCKLIST_CACHE_FILE.write_text("\n".join(cached_ips)) - logger.info(f"Downloaded and saved {len(cached_ips)} IPs to blocklist cache") + if is_master(): + logger.info(f"Downloaded and saved {len(cached_ips)} IPs to blocklist cache") except BlockingIOError: # Another process is downloading - wait for cache pass finally: lock_fd.close() except Exception as e: - logger.warning(f"Lock error: {e}") + if is_master(): + logger.warning(f"Lock error: {e}") # Re-read cache after download if BLOCKLIST_CACHE_FILE.exists() and not cached_ips: try: cached_ips = set(BLOCKLIST_CACHE_FILE.read_text().strip().splitlines()) - if cached_ips: + if cached_ips and is_master(): logger.info(f"Loaded {len(cached_ips)} IPs from blocklist cache (after wait)") except Exception: pass @@ -105,7 +115,8 @@ async def lifespan(app: FastAPI): all_blocked.update(cached_ips) mw.set_ip_config(blocked=all_blocked) - logger.info(f"IP blocklist loaded: {len(all_blocked)} IPs") + if is_master(): + logger.info(f"IP blocklist loaded: {len(all_blocked)} IPs") # Determine environment if args.test: @@ -115,7 +126,8 @@ async def lifespan(app: FastAPI): else: env = "production" - logger.info(f"Starting ZernMC Launcher Server (environment: {env})") + if is_master(): + logger.info(f"Starting ZernMC Launcher Server (environment: {env})") # Create directories if they don't exist BUILDS_DIR.mkdir(exist_ok=True) @@ -129,21 +141,26 @@ async def lifespan(app: FastAPI): yield return - logger.info("Scanning packs on startup...") + if is_master(): + logger.info("Scanning packs on startup...") pack_dirs = [p for p in PACKS_DIR.iterdir() if p.is_dir()] if not pack_dirs: - logger.warning(f"No packs found in directory: {PACKS_DIR}") + if is_master(): + logger.warning(f"No packs found in directory: {PACKS_DIR}") else: for pack_dir in pack_dirs: try: meta = await scan_pack(pack_dir.name) - logger.info(f"Pack scanned successfully: {pack_dir.name} v{meta.version} ({len(meta.files)} files)") + if is_master(): + logger.info(f"Pack scanned successfully: {pack_dir.name} v{meta.version} ({len(meta.files)} files)") except Exception as e: - logger.error(f"Failed to scan pack: {pack_dir.name} - {e}", exc_info=True) + if is_master(): + logger.error(f"Failed to scan pack: {pack_dir.name} - {e}", exc_info=True) - logger.info("All packs ready. Server is running.") + if is_master(): + logger.info("All packs ready. Server is running.") # Initialize proxy client global proxy_client @@ -155,7 +172,8 @@ async def lifespan(app: FastAPI): if proxy_client: await proxy_client.aclose() - logger.info("Server shutting down...") + if is_master(): + logger.info("Server shutting down...")