51 lines
1.9 KiB
Python
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)
|