Files
squid-manager/templates/logs_live.html
T
Hermes Agent 0d413cfeaf fix: 缓存目录保存 404 + 日志时间显示为本地时区 + 持久化同步
修复 4 个相关 bug:

1. **缓存目录配置保存后 404 (核心 bug)**
   - 原因: _show_config_preview 把 endpoint 名 'config_cache' 存进 session 作
     为 return_to,config_preview 把它当 URL 跳到 'config_cache' 报 404
   - 修法: _show_config_preview 自动用 url_for() 解析 endpoint 名

2. **日志时间显示 UTC 而不是本地时间 (次生 bug)**
   - 原因: log_parser 把 timestamp 解析成 UTC datetime,模板直接
     e.timestamp.strftime('%H:%M:%S') 显示 UTC
   - 修法: LogEntry 新增 timestamp_local 属性 (astimezone()),
     3 个模板改用 e.timestamp_local

3. **DB 同步永远不工作 (次生 bug)**
   - 原因: _should_auto_sync 调 get_config('log_sync_interval') ->
     _resolve_active_instance -> session.get 在 app_context 里炸,
     try/except 静默吞,永远返回 False
   - 修法: 新增 _resolve_access_log_path() 不走 session 链,
     _should_auto_sync 直接查 AppConfig 表

4. **default_struct 规则引用 Safe_ports/SSL_ports 但 ACL 是 safeports/sslports**
   - 大小写不一致导致 squid -k parse 报 FATAL
   - 修法: 改成小写统一

测试: cache save 流程全链路跑通 (POST -> preview -> confirm -> /config/cache 200)
所有 config 页面 (main/acls/rules/cache/refresh/auth/peers) 的 preview+confirm
return_to 字段都正确解析为 URL
2026-07-16 15:08:18 +08:00

61 lines
2.3 KiB
HTML

{% extends "base.html" %}
{% block title %}实时日志 - Squid Manager{% endblock %}
{% block head %}
<meta http-equiv="refresh" content="{{ cfg.auto_refresh_seconds }}">
{% endblock %}
{% block content %}
<div class="page-header">
<h1>⚡ 实时日志 (Live Tail)</h1>
<div class="page-actions">
<span class="meta-text">显示最近 {{ n }} 条 · 每 {{ cfg.auto_refresh_seconds }} 秒自动刷新</span>
<a href="{{ url_for('config_paths') }}" class="btn btn-small btn-secondary">⚙️ 调整</a>
<button onclick="location.reload()" class="btn btn-small btn-primary">🔄 立即刷新</button>
</div>
</div>
<div class="card">
{% if entries %}
<div class="table-scroll">
<table class="data-table log-table">
<thead>
<tr>
<th>时间</th>
<th>客户端</th>
<th>结果码</th>
<th>HTTP</th>
<th>方法</th>
<th>大小</th>
<th>耗时</th>
<th>URL</th>
<th>层级</th>
</tr>
</thead>
<tbody>
{% for e in entries %}
<tr>
<td class="time-cell">{{ e.timestamp_local.strftime('%H:%M:%S') if e.timestamp_local else e.time }}</td>
<td>{{ e.client }}</td>
<td>
<span class="badge badge-{% if e.category == 'Hit' %}green{% elif e.category == 'Miss' %}blue{% elif e.category == 'Tunnel' %}cyan{% elif e.category == 'Denied' %}red{% elif e.category == 'Aborted' %}orange{% elif e.category == 'Error' %}red{% else %}gray{% endif %}">{{ e.result_code }}</span>
</td>
<td><span class="badge badge-gray">{{ e.http_code or '-' }}</span></td>
<td>{{ e.method }}</td>
<td>{{ format_bytes(e.size) }}</td>
<td>{{ format_duration(e.elapsed_ms) }}</td>
<td class="url-cell" title="{{ e.url }}">{{ e.url }}</td>
<td><code>{{ e.hier_code }}</code></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="card-empty">
<div class="empty-icon">📭</div>
<p>暂无日志数据。请确认访问日志路径正确:
<code>{{ cfg.access_log_path }}</code></p>
</div>
{% endif %}
</div>
{% endblock %}