Quiet routine per-tick service logs, surface real failures at WARNING
BaseService logged "Next run in Ns" at INFO on every single execution of every service, including the 1-2s-interval pub/sub bridges (presence/notification/live-view relays), drowning the console in routine noise while actual failures (run_once errors, loop errors, on_disable errors) were logged at the same INFO level and got lost in it. log() now takes an optional level (default INFO, unchanged for existing callers); the routine tick line drops to DEBUG and the three failure paths move to WARNING. Added DEVPLACE_LOG_LEVEL (default INFO) so DEBUG-level ticks stay available on demand without a code change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vnp7vzE4hvsytMo5YjszJm
This commit is contained in:
@@ -12,6 +12,8 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
STATIC_DIR = BASE_DIR / "devplacepy" / "static"
|
STATIC_DIR = BASE_DIR / "devplacepy" / "static"
|
||||||
TEMPLATES_DIR = BASE_DIR / "devplacepy" / "templates"
|
TEMPLATES_DIR = BASE_DIR / "devplacepy" / "templates"
|
||||||
|
|
||||||
|
LOG_LEVEL = environ.get("DEVPLACE_LOG_LEVEL", "INFO").upper()
|
||||||
|
|
||||||
DATA_DIR = Path(environ.get("DEVPLACE_DATA_DIR", str(BASE_DIR / "data")))
|
DATA_DIR = Path(environ.get("DEVPLACE_DATA_DIR", str(BASE_DIR / "data")))
|
||||||
UPLOADS_DIR = DATA_DIR / "uploads"
|
UPLOADS_DIR = DATA_DIR / "uploads"
|
||||||
ATTACHMENTS_DIR = UPLOADS_DIR / "attachments"
|
ATTACHMENTS_DIR = UPLOADS_DIR / "attachments"
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ from devplacepy.config import (
|
|||||||
PORT,
|
PORT,
|
||||||
SERVICE_LOCK_FILE,
|
SERVICE_LOCK_FILE,
|
||||||
INIT_LOCK_FILE,
|
INIT_LOCK_FILE,
|
||||||
|
LOG_LEVEL,
|
||||||
ensure_data_dirs,
|
ensure_data_dirs,
|
||||||
)
|
)
|
||||||
from devplacepy.database import (
|
from devplacepy.database import (
|
||||||
@@ -130,7 +131,7 @@ from devplacepy.services.telegram import TelegramService
|
|||||||
from devplacepy.services.telegram.outbox_service import TelegramOutboxService
|
from devplacepy.services.telegram.outbox_service import TelegramOutboxService
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=logging.INFO,
|
level=getattr(logging, LOG_LEVEL, logging.INFO),
|
||||||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
||||||
)
|
)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@@ -213,10 +213,10 @@ class BaseService(ABC):
|
|||||||
def get_config(self) -> dict:
|
def get_config(self) -> dict:
|
||||||
return {field.key: field.read() for field in self.all_fields()}
|
return {field.key: field.read() for field in self.all_fields()}
|
||||||
|
|
||||||
def log(self, message: str) -> None:
|
def log(self, message: str, level: int = logging.INFO) -> None:
|
||||||
stamp = datetime.now(timezone.utc).strftime("%H:%M:%S")
|
stamp = datetime.now(timezone.utc).strftime("%H:%M:%S")
|
||||||
self.log_buffer.append(f"[{stamp}] {message}")
|
self.log_buffer.append(f"[{stamp}] {message}")
|
||||||
logger.info(f"[{self.name}] {message}")
|
logger.log(level, f"[{self.name}] {message}")
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def run_once(self) -> None:
|
async def run_once(self) -> None:
|
||||||
@@ -265,7 +265,7 @@ class BaseService(ABC):
|
|||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"Loop error: {e}")
|
self.log(f"Loop error: {e}", level=logging.WARNING)
|
||||||
try:
|
try:
|
||||||
await asyncio.sleep(self.TICK_SECONDS)
|
await asyncio.sleep(self.TICK_SECONDS)
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
@@ -303,7 +303,7 @@ class BaseService(ABC):
|
|||||||
try:
|
try:
|
||||||
await self.on_disable()
|
await self.on_disable()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"on_disable error: {e}")
|
self.log(f"on_disable error: {e}", level=logging.WARNING)
|
||||||
|
|
||||||
async def _execute_run(self) -> None:
|
async def _execute_run(self) -> None:
|
||||||
self.interval_seconds = self.current_interval()
|
self.interval_seconds = self.current_interval()
|
||||||
@@ -315,13 +315,13 @@ class BaseService(ABC):
|
|||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"Error in run_once: {e}")
|
self.log(f"Error in run_once: {e}", level=logging.WARNING)
|
||||||
self.interval_seconds = self.current_interval()
|
self.interval_seconds = self.current_interval()
|
||||||
self._next_due = datetime.now(timezone.utc) + timedelta(
|
self._next_due = datetime.now(timezone.utc) + timedelta(
|
||||||
seconds=self.interval_seconds
|
seconds=self.interval_seconds
|
||||||
)
|
)
|
||||||
self._next_run = self._next_due.isoformat()
|
self._next_run = self._next_due.isoformat()
|
||||||
self.log(f"Next run in {self.interval_seconds}s")
|
self.log(f"Next run in {self.interval_seconds}s", level=logging.DEBUG)
|
||||||
self._persist_state(force=True)
|
self._persist_state(force=True)
|
||||||
|
|
||||||
def _handle_commands(self) -> None:
|
def _handle_commands(self) -> None:
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "devplacepy"
|
name = "devplacepy"
|
||||||
version = "1.0.8"
|
version = "1.0.9"
|
||||||
description = "DevPlace - The Developer Social Network"
|
description = "DevPlace - The Developer Social Network"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
Reference in New Issue
Block a user