feat: Register scheduled GEO tracker (07:30 daily)

- New MODULE entry: scheduled_geo_tracker
- New LOG_FILE_MAP entry
- New MODULE_JOBS entry
- _run_geo_tracker method: subprocess invokes geo_tracker.py

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Yuzhiran Dev
2026-06-16 08:26:13 +08:00
parent 2aedb69efd
commit 93d1d511e5
+39
View File
@@ -57,6 +57,7 @@ MODULES = {
"scheduled_reset_search_usage": {"name": "🔁 搜索用量重置", "cron": "00:05"},
"scheduled_task_monitor": {"name": "⏰ 任务监控", "cron": "*"},
"scheduled_rank_tracker": {"name": "🔍 搜索排名追踪", "cron": "07:00"},
"scheduled_geo_tracker": {"name": "🌐 AI 搜索引用追踪", "cron": "07:30"},
}
LOG_FILE_MAP = {
@@ -69,6 +70,7 @@ LOG_FILE_MAP = {
"scheduled_reset_search_usage": "reset_search_usage",
"scheduled_task_monitor": "task_monitor",
"scheduled_rank_tracker": "rank_tracker",
"scheduled_geo_tracker": "geo_tracker",
}
def _log_to_file(module_id: str, status: str, message: str = None, error_trace: str = None):
@@ -185,6 +187,7 @@ class TaskScheduler:
("scheduled_metrics_sync", self._run_metrics_sync, "指标同步"),
("scheduled_reset_search_usage", self._run_reset_search_usage, "搜索用量重置"),
("scheduled_rank_tracker", self._run_rank_tracker, "搜索排名追踪"),
("scheduled_geo_tracker", self._run_geo_tracker, "AI 搜索引用追踪"),
]
for module_id, fn, name in MODULE_JOBS:
@@ -381,6 +384,7 @@ class TaskScheduler:
started_at=started, finished_at=datetime.now(timezone.utc), triggered_by=triggered_by)
db.close()
except Exception as e:
db.close()
_log_task("scheduled_optimize_sources", "failed", log_id=log_id,
message=str(e),
error_trace=traceback.format_exc(),
@@ -493,6 +497,7 @@ class TaskScheduler:
logger.info("[Scheduled] Metrics sync: no zhihu articles to sync")
db.close()
except Exception as e:
db.close()
_log_task("scheduled_metrics_sync", "failed", log_id=log_id,
message=str(e),
error_trace=traceback.format_exc(),
@@ -622,6 +627,40 @@ class TaskScheduler:
started_at=started, finished_at=datetime.now(timezone.utc))
logger.exception("[RankTracker] 排名追踪失败: %s", e)
def _run_geo_tracker(self):
"""每日 AI 搜索引用追踪"""
started = datetime.now(timezone.utc)
log_id = _log_task("scheduled_geo_tracker", "running", started_at=started)
try:
import subprocess
result = subprocess.run(
[sys.executable, str(PROJECT_ROOT / "scripts" / "geo_tracker.py")],
capture_output=True, text=True, timeout=600
)
if result.returncode == 0:
try:
data = json.loads(result.stdout.strip())
except json.JSONDecodeError:
data = {"raw": result.stdout.strip()[:200]}
_log_task("scheduled_geo_tracker", "success", log_id=log_id,
message=f"GEO 追踪完成: {data.get('articles_checked', 0)} 篇, "
f"AI 引用 {data.get('ai_citations', 0)}",
result_data=data,
started_at=started, finished_at=datetime.now(timezone.utc))
logger.info("[GeoTracker] 完成: %s", result.stdout.strip()[:200])
else:
_log_task("scheduled_geo_tracker", "failed", log_id=log_id,
message=f"返回码 {result.returncode}",
error_trace=result.stderr[-500:],
started_at=started, finished_at=datetime.now(timezone.utc))
except Exception as e:
import traceback
_log_task("scheduled_geo_tracker", "failed", log_id=log_id,
message=str(e),
error_trace=traceback.format_exc(),
started_at=started, finished_at=datetime.now(timezone.utc))
logger.exception("[GeoTracker] AI 搜索引用追踪失败: %s", e)
def get_jobs(self):
"""返回当前所有定时任务的状态"""
jobs = []