This commit is contained in:
Your Name
2026-04-17 15:13:46 +08:00
parent fe87c7b343
commit 0e096947fc
19 changed files with 791 additions and 151 deletions

View File

@@ -3,10 +3,8 @@ from __future__ import annotations
import json
import re
from datetime import datetime, timezone
from pathlib import Path
from app.core.db import get_db
from app.core.files import tail_lines
from app.core.files import resolve_domain_path, tail_lines
from app.core.redis_client import get_redis
from app.services.runtime_settings_service import get_runtime_settings
from app.services.detect_run_service import sync_detect_runs
@@ -20,6 +18,7 @@ _PROXY_COUNT_RE = re.compile(r"当前可用代理数[:]\s*(\d+)")
_THREAD_COUNT_RE = re.compile(r"当前实际线程数量[:]\s*(\d+)\s*/\s*(\d+)")
_RUNTIME_STATE_KEY = "domain_tool:detect_runtime_state"
_TIMESTAMP_FORMATS = ("%Y-%m-%d %H:%M:%S.%f", "%Y-%m-%d %H:%M:%S")
_REMOTE_LOG_MAX_CHARS = 500
def _extract_dependency_alerts(lines: list[str]) -> list[dict]:
@@ -141,6 +140,61 @@ def _recent_event(lines: list[str]) -> str:
return ""
def _build_remote_log_lines(
active_job: dict | None,
*,
enabled: bool,
mode: str,
limit: int = 240,
) -> list[str]:
if not enabled:
return []
if not active_job:
return []
events = list(active_job.get("current_cycle_events") or active_job.get("recent_events") or [])
if not events:
return []
lines: list[str] = []
normalized_mode = str(mode or "key").strip().lower()
if normalized_mode not in {"key", "full"}:
normalized_mode = "key"
current_cycle_token = str(active_job.get("current_cycle_token") or "").strip()
for event in reversed(events):
event_type = str(event.get("event_type") or "").strip()
if event_type != "worker_log":
continue
created_at = str(event.get("created_at") or "").strip()
node_code = str(event.get("node_code") or "").strip() or "unknown"
message = str(event.get("message") or "").strip()
if not message:
continue
payload = event.get("payload") if isinstance(event.get("payload"), dict) else {}
event_cycle_token = str(payload.get("cycle_token") or "").strip()
if current_cycle_token and event_cycle_token and event_cycle_token != current_cycle_token:
continue
event_mode = str(payload.get("log_mode") or "key").strip().lower()
if event_mode not in {"key", "full"}:
event_mode = "key"
if normalized_mode != "full" and event_mode == "full":
continue
if len(message) > _REMOTE_LOG_MAX_CHARS:
message = f"{message[:_REMOTE_LOG_MAX_CHARS]}..."
lines.append(f"[{created_at}] [{node_code}] {message}")
return lines[-max(1, int(limit or 240)) :]
def _resolve_remote_log_lines(
active_job: dict | None,
runs: list[dict],
*,
enabled: bool,
mode: str,
limit: int = 240,
) -> list[str]:
return _build_remote_log_lines(active_job, enabled=enabled, mode=mode, limit=limit)
def _load_runtime_state() -> dict:
try:
redis_client = get_redis()
@@ -282,17 +336,18 @@ def get_detect_status() -> dict:
with get_db() as conn:
with conn.cursor() as cur:
for key, query in queries.items():
cur.execute(query)
progress[key] = cur.fetchone()[0]
try:
cur.execute(query)
progress[key] = cur.fetchone()[0]
except Exception:
progress[key] = 0
settings_payload = get_settings_payload()
worker_log = Path(__file__).resolve().parents[3] / "domainCheck" / "detect_worker.log"
if not worker_log.exists():
worker_log = Path(__file__).resolve().parents[3] / "domainCheck" / "logs" / "detect_worker.log"
worker_log = resolve_domain_path("detect_worker.log", "logs/detect_worker.log")
worker_online = False
last_log_time = None
if worker_log.exists():
if worker_log and worker_log.exists():
modified = datetime.fromtimestamp(worker_log.stat().st_mtime, tz=timezone.utc)
last_log_time = modified.isoformat()
worker_online = (datetime.now(timezone.utc) - modified).total_seconds() < 180
@@ -335,7 +390,7 @@ def get_detect_status() -> dict:
"allow_direct": settings_payload["proxy_config"].get("allow_direct", False),
"proxy_pool_count": len(settings_payload["proxy_config"].get("proxy_urls", [])),
}
active_job = get_active_detect_job_summary()
active_job = get_active_detect_job_summary(event_limit=240)
runtime_snapshot = {
**runtime,
"detecting": runtime_state.get("detecting", False),
@@ -347,6 +402,15 @@ def get_detect_status() -> dict:
"proxy_supplier_empty": proxy_runtime["supplier_empty"],
}
runs = sync_detect_runs(runtime_snapshot, progress, settings_summary, active_job=active_job)
worker_log_sync_enabled = bool(runtime_settings.get("worker_log_sync_enabled", False))
worker_log_sync_mode = str(runtime_settings.get("worker_log_sync_mode", "key") or "key")
remote_log_lines = _resolve_remote_log_lines(
active_job,
runs,
enabled=worker_log_sync_enabled,
mode=worker_log_sync_mode,
limit=240,
)
dependency_alerts = _extract_dependency_alerts(recent_lines)
append_detect_result_projection_if_changed(
detect={
@@ -400,6 +464,9 @@ def get_detect_status() -> dict:
"recent_event": runtime_state.get("detail") or _recent_event(recent_lines),
"recent_warning": recent_proxy_warning,
"log_lines": recent_lines,
"remote_log_lines": remote_log_lines,
"runs": runs,
"active_job": active_job,
"worker_log_sync_enabled": worker_log_sync_enabled,
"worker_log_sync_mode": worker_log_sync_mode,
}