feat(监控): 实时服务状态界面 - Oracle 新增 service_activity 活动表(只保留7天,写入时清理)与 /api/oracle/activity 接口(队列实时状态/当前处理视频/模型调用/rclone/人物合并/最近50条活动);VideoQueue 打点+当前处理跟踪+status();PersonService 打点;rclone_sync.sh 同步结果写活动表;fam-ui 新增'🖥 服务状态'页(状态卡+活动时间流,直连 Oracle 实时拉取)
This commit is contained in:
@@ -52,6 +52,11 @@ def _sync_token():
|
||||
return _SYNC_TOK or ''
|
||||
|
||||
|
||||
def _now_iso_str() -> str:
|
||||
from datetime import datetime, timezone, timedelta
|
||||
return datetime.now(timezone(timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
|
||||
@api_bp.route('/api/oracle/sync', methods=['GET'])
|
||||
def sync_pull():
|
||||
"""NAS 拉取增量数据。since=ISO 时间字符串(默认 '' 拉全量)。
|
||||
@@ -145,6 +150,45 @@ def event_thumb(event_id):
|
||||
return send_file(path, mimetype='image/jpeg')
|
||||
|
||||
|
||||
@api_bp.route('/api/oracle/activity', methods=['GET'])
|
||||
def activity():
|
||||
"""实时服务状态 + 最近活动流(token 校验)。
|
||||
|
||||
返回各服务当前状态(队列/当前处理视频/rclone 最近同步/人物合并/模型调用)
|
||||
与最近 50 条活动(service_activity,只保留 7 天)。
|
||||
"""
|
||||
if not _check_token():
|
||||
return jsonify({"error": "unauthorized"}), 401
|
||||
db = state.get_db()
|
||||
queue = state.get_queue()
|
||||
# 队列实时状态
|
||||
q_status = None
|
||||
if queue is not None:
|
||||
try:
|
||||
q_status = queue.status()
|
||||
except Exception as e:
|
||||
logger.warning(f"queue.status 异常: {e}")
|
||||
# 各服务最近活动(rclone / person / model 切换)
|
||||
def _last_activity(service):
|
||||
row = db._conn.execute(
|
||||
"SELECT service, action, detail, ts FROM service_activity "
|
||||
"WHERE service=? ORDER BY id DESC LIMIT 1", (service,)).fetchone()
|
||||
return dict(row) if row else None
|
||||
# 最近模型调用(实时模型卡)
|
||||
model_calls = db._conn.execute(
|
||||
"SELECT id, provider, model, filename, started_at, duration_sec, "
|
||||
"success, error FROM model_calls ORDER BY id DESC LIMIT 5").fetchall()
|
||||
return jsonify({
|
||||
"queue": q_status,
|
||||
"db": db.get_queue_status(),
|
||||
"rclone": _last_activity('rclone'),
|
||||
"person": _last_activity('person'),
|
||||
"model_calls": [dict(m) for m in model_calls],
|
||||
"activities": db.get_recent_activities(50),
|
||||
"ts": _now_iso_str(),
|
||||
}), 200
|
||||
|
||||
|
||||
@api_bp.route('/health', methods=['GET'])
|
||||
def health():
|
||||
"""健康检查"""
|
||||
|
||||
Reference in New Issue
Block a user