fix: 修复6个配置路由500错误 + 实时日志直读文件 + 开启自动同步
- 修复 config_cache/config_refresh/config_acls/config_rules/config_auth/config_peers 6个路由缺少 save_struct() 调用导致 NameError: name 'ok' is not defined - logs_live 改为直接读 access.log 文件,不经过 SQLite 缓存,确保实时性 - 仪表盘调整调用顺序:先同步日志再计算统计 - 设置 log_sync_interval=30 开启自动同步(原为0=关闭)
This commit is contained in:
@@ -818,8 +818,10 @@ def change_password():
|
||||
@app.route("/")
|
||||
@login_required
|
||||
def dashboard():
|
||||
stats = get_stats()
|
||||
# Trigger auto-sync first (get_parsed_logs checks _should_auto_sync),
|
||||
# then compute stats from the now-fresh SQLite data.
|
||||
entries = get_parsed_logs()
|
||||
stats = get_stats()
|
||||
cfg = get_all_config()
|
||||
# P1-2: surface any active alert rules at the top of the dashboard so
|
||||
# operators see them without having to navigate to /alerts.
|
||||
@@ -1060,10 +1062,14 @@ def logs_import():
|
||||
@app.route("/logs/live")
|
||||
@login_required
|
||||
def logs_live():
|
||||
"""Live tail view (auto-refresh)."""
|
||||
"""Live tail view (auto-refresh). Reads directly from file for real-time."""
|
||||
cfg = get_all_config()
|
||||
n = int(cfg.get("live_tail_lines", 100))
|
||||
entries = get_parsed_logs(force=False)[-n:]
|
||||
# Read directly from file - bypass SQLite cache for true real-time
|
||||
limit = max(n * 3, 500)
|
||||
text = read_access_log_tail(max_lines=limit)
|
||||
entries = log_parser.parse_lines(text)
|
||||
entries = entries[-n:]
|
||||
entries = list(reversed(entries))
|
||||
return render_template("logs_live.html", entries=entries,
|
||||
cfg=cfg, n=n,
|
||||
@@ -1264,7 +1270,7 @@ def config_acls():
|
||||
type=types[i] if i < len(types) else "src",
|
||||
values=vals, comment=cmnt))
|
||||
struct["acls"] = new_acls
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_acls"))
|
||||
@@ -1314,7 +1320,7 @@ def config_rules():
|
||||
idx = int(request.form.get("index", "-1"))
|
||||
if 0 <= idx < len(struct["rules"]):
|
||||
del struct["rules"][idx]
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_rules"))
|
||||
@@ -1364,7 +1370,7 @@ def config_cache():
|
||||
idx = int(request.form.get("index", "-1"))
|
||||
if 0 <= idx < len(struct["cache_dirs"]):
|
||||
del struct["cache_dirs"][idx]
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_cache"))
|
||||
@@ -1415,7 +1421,7 @@ def config_refresh():
|
||||
idx = int(request.form.get("index", "-1"))
|
||||
if 0 <= idx < len(struct["refresh_patterns"]):
|
||||
del struct["refresh_patterns"][idx]
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_refresh"))
|
||||
@@ -1468,7 +1474,7 @@ def config_auth():
|
||||
idx = int(request.form.get("index", "-1"))
|
||||
if 0 <= idx < len(struct["auth_params"]):
|
||||
del struct["auth_params"][idx]
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_auth"))
|
||||
@@ -1521,7 +1527,7 @@ def config_peers():
|
||||
idx = int(request.form.get("index", "-1"))
|
||||
if 0 <= idx < len(struct["cache_peers"]):
|
||||
del struct["cache_peers"][idx]
|
||||
content_preview = msg if ok else ""
|
||||
ok, msg, content_preview = save_struct(struct)
|
||||
if not ok:
|
||||
flash(msg, "error")
|
||||
return redirect(url_for("config_peers"))
|
||||
|
||||
Reference in New Issue
Block a user