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("/")
|
@app.route("/")
|
||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
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()
|
entries = get_parsed_logs()
|
||||||
|
stats = get_stats()
|
||||||
cfg = get_all_config()
|
cfg = get_all_config()
|
||||||
# P1-2: surface any active alert rules at the top of the dashboard so
|
# P1-2: surface any active alert rules at the top of the dashboard so
|
||||||
# operators see them without having to navigate to /alerts.
|
# operators see them without having to navigate to /alerts.
|
||||||
@@ -1060,10 +1062,14 @@ def logs_import():
|
|||||||
@app.route("/logs/live")
|
@app.route("/logs/live")
|
||||||
@login_required
|
@login_required
|
||||||
def logs_live():
|
def logs_live():
|
||||||
"""Live tail view (auto-refresh)."""
|
"""Live tail view (auto-refresh). Reads directly from file for real-time."""
|
||||||
cfg = get_all_config()
|
cfg = get_all_config()
|
||||||
n = int(cfg.get("live_tail_lines", 100))
|
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))
|
entries = list(reversed(entries))
|
||||||
return render_template("logs_live.html", entries=entries,
|
return render_template("logs_live.html", entries=entries,
|
||||||
cfg=cfg, n=n,
|
cfg=cfg, n=n,
|
||||||
@@ -1264,7 +1270,7 @@ def config_acls():
|
|||||||
type=types[i] if i < len(types) else "src",
|
type=types[i] if i < len(types) else "src",
|
||||||
values=vals, comment=cmnt))
|
values=vals, comment=cmnt))
|
||||||
struct["acls"] = new_acls
|
struct["acls"] = new_acls
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_acls"))
|
return redirect(url_for("config_acls"))
|
||||||
@@ -1314,7 +1320,7 @@ def config_rules():
|
|||||||
idx = int(request.form.get("index", "-1"))
|
idx = int(request.form.get("index", "-1"))
|
||||||
if 0 <= idx < len(struct["rules"]):
|
if 0 <= idx < len(struct["rules"]):
|
||||||
del struct["rules"][idx]
|
del struct["rules"][idx]
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_rules"))
|
return redirect(url_for("config_rules"))
|
||||||
@@ -1364,7 +1370,7 @@ def config_cache():
|
|||||||
idx = int(request.form.get("index", "-1"))
|
idx = int(request.form.get("index", "-1"))
|
||||||
if 0 <= idx < len(struct["cache_dirs"]):
|
if 0 <= idx < len(struct["cache_dirs"]):
|
||||||
del struct["cache_dirs"][idx]
|
del struct["cache_dirs"][idx]
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_cache"))
|
return redirect(url_for("config_cache"))
|
||||||
@@ -1415,7 +1421,7 @@ def config_refresh():
|
|||||||
idx = int(request.form.get("index", "-1"))
|
idx = int(request.form.get("index", "-1"))
|
||||||
if 0 <= idx < len(struct["refresh_patterns"]):
|
if 0 <= idx < len(struct["refresh_patterns"]):
|
||||||
del struct["refresh_patterns"][idx]
|
del struct["refresh_patterns"][idx]
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_refresh"))
|
return redirect(url_for("config_refresh"))
|
||||||
@@ -1468,7 +1474,7 @@ def config_auth():
|
|||||||
idx = int(request.form.get("index", "-1"))
|
idx = int(request.form.get("index", "-1"))
|
||||||
if 0 <= idx < len(struct["auth_params"]):
|
if 0 <= idx < len(struct["auth_params"]):
|
||||||
del struct["auth_params"][idx]
|
del struct["auth_params"][idx]
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_auth"))
|
return redirect(url_for("config_auth"))
|
||||||
@@ -1521,7 +1527,7 @@ def config_peers():
|
|||||||
idx = int(request.form.get("index", "-1"))
|
idx = int(request.form.get("index", "-1"))
|
||||||
if 0 <= idx < len(struct["cache_peers"]):
|
if 0 <= idx < len(struct["cache_peers"]):
|
||||||
del struct["cache_peers"][idx]
|
del struct["cache_peers"][idx]
|
||||||
content_preview = msg if ok else ""
|
ok, msg, content_preview = save_struct(struct)
|
||||||
if not ok:
|
if not ok:
|
||||||
flash(msg, "error")
|
flash(msg, "error")
|
||||||
return redirect(url_for("config_peers"))
|
return redirect(url_for("config_peers"))
|
||||||
|
|||||||
Reference in New Issue
Block a user