zcbot/core/provider_credentials/monitor.py

51 lines
1.9 KiB
Python

"""蓝绿单轮选主的 Provider 巡检与开发者邮件。"""
from __future__ import annotations
import os
from core.storage import get_engine
from .registry import get_provider
from .service import due_provider_ids, test_current_credentials
from .testing import TestResult
_LOCK_SQL = "SELECT pg_try_advisory_lock(31331, 2)"
_UNLOCK_SQL = "SELECT pg_advisory_unlock(31331, 2)"
def send_notification(provider_id: str, event: str, result: TestResult) -> None:
provider = get_provider(provider_id)
label = "恢复正常" if event == "recovered" else result.detail
print(f"[provider] {provider_id} {event}: {label}")
email = os.getenv("ZCBOT_DEVELOPER_EMAIL", "").strip()
if not email:
return
try:
from tools.send_email import send_email_smtp, smtp_configured
if smtp_configured():
send_email_smtp(
email, f"[zcbot] {provider.display_name} {label}",
f"Provider: {provider.display_name}\n状态: {event}\n详情: {result.detail}",
)
except Exception as exc: # noqa: BLE001 - 告警失败不得影响业务状态
print(f"[provider] notification failed: {type(exc).__name__}")
def run_due_checks() -> int:
engine = get_engine()
with engine.connect() as connection:
claimed = bool(connection.exec_driver_sql(_LOCK_SQL).scalar())
if not claimed:
return 0
try:
count = 0
for provider_id in due_provider_ids():
try:
test_current_credentials(provider_id, notify=send_notification)
count += 1
except Exception as exc: # noqa: BLE001 - 单 Provider 隔离
print(f"[provider] {provider_id} check failed: {type(exc).__name__}")
return count
finally:
connection.exec_driver_sql(_UNLOCK_SQL)