数据统计改为后台热缓存与 SSE,曲线放大置底并支持选机,对比增加模式与收益率。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -63,7 +63,8 @@ from lib.instances_lib import (
|
||||
)
|
||||
from lib.overview_cache_lib import overview_store
|
||||
from lib.sso_lib import build_embed_open_url
|
||||
from lib.stats_agg_lib import build_stats_curve, build_stats_summary, normalize_window
|
||||
from lib.stats_agg_lib import normalize_window
|
||||
from lib.stats_cache_lib import stats_store
|
||||
from lib.wechat_lib import (
|
||||
hub_alert_cooldown_sec,
|
||||
hub_health_fail_threshold,
|
||||
@@ -157,21 +158,43 @@ def stats_page():
|
||||
@app.route("/api/stats/summary")
|
||||
@login_required
|
||||
def api_stats_summary():
|
||||
"""只读统计热缓存;后台常驻刷新各窗口."""
|
||||
window = normalize_window(request.args.get("window") or "7d")
|
||||
try:
|
||||
return jsonify(build_stats_summary(window))
|
||||
except Exception as e:
|
||||
return jsonify({"ok": False, "msg": str(e) or "统计失败"}), 500
|
||||
force = (request.args.get("force") or "").strip().lower() in ("1", "true", "yes")
|
||||
if force:
|
||||
stats_store.request_refresh()
|
||||
return jsonify(stats_store.summary_dict(window))
|
||||
|
||||
|
||||
@app.route("/api/stats/curve")
|
||||
@login_required
|
||||
def api_stats_curve():
|
||||
range_key = normalize_window(request.args.get("range") or request.args.get("window") or "7d")
|
||||
try:
|
||||
return jsonify(build_stats_curve(range_key))
|
||||
except Exception as e:
|
||||
return jsonify({"ok": False, "msg": str(e) or "曲线失败"}), 500
|
||||
force = (request.args.get("force") or "").strip().lower() in ("1", "true", "yes")
|
||||
if force:
|
||||
stats_store.request_refresh()
|
||||
return jsonify(stats_store.curve_dict(range_key))
|
||||
|
||||
|
||||
@app.route("/api/stats/refresh", methods=["POST"])
|
||||
@login_required
|
||||
def api_stats_refresh():
|
||||
stats_store.request_refresh()
|
||||
return jsonify({"ok": True, "msg": "已触发统计后台刷新"})
|
||||
|
||||
|
||||
@app.route("/api/stats/stream")
|
||||
@login_required
|
||||
def api_stats_stream():
|
||||
return Response(
|
||||
stream_with_context(stats_store.iter_sse()),
|
||||
mimetype="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@app.route("/instances", methods=["GET", "POST"])
|
||||
@@ -533,7 +556,12 @@ def start_overview_cache() -> None:
|
||||
overview_store.start(pull_all_enabled, on_pull=_on_overview_pulled)
|
||||
|
||||
|
||||
def start_stats_cache() -> None:
|
||||
stats_store.start()
|
||||
|
||||
|
||||
start_overview_cache()
|
||||
start_stats_cache()
|
||||
|
||||
try:
|
||||
start_hub_backup_scheduler(
|
||||
|
||||
Reference in New Issue
Block a user