问题现象
服务器环境:Debian 12 + 宝塔面板 11.8.1,Gitea 以 Docker 方式部署,通过 Nginx 反向代理对外提供 gitea.example.com 服务。某天发现宝塔插件”网站监控报表”中 Gitea 站点的访问日志一直是空的,但原始 Nginx 日志文件持续有数据写入;同时面板”修复数据收集问题”一直提示 /www/server/monitor/ip_filter.sock 文件权限异常。
关键对照组:同机器的 node.example.com(3.6 万条)、wiki.example.com(894 条)监控数据库都正常,只有 Gitea 站点当天和历史数据库全部 0 条记录。这说明不是 monitor 进程整体挂了,也不是查询时间范围问题,而是 只针对这个站点 的采集被丢弃了。
先厘清采集链路
网站监控报表的实际数据链路是:
Nginx access_log / error_log
→ Unix Datagram Socket /tmp/bt-monitor.sock
→ /www/server/monitor/monitor 进程
→ SQLite 数据库 /www/server/monitor/data/dbs/<域名>/
→ 宝塔网站监控报表
排查中确认了几点,排除了几个常见怀疑方向:
- Gitea 与正常站点用的是同一个 socket(
/tmp/bt-monitor.sock),只是 tag 不同(Gitea 是tag=31__access,正常站点是tag=20__access),排除”用错采集通道”; - UDP 9030 端口是 monitor 的内部命令控制端口,不是网站日志输入端口,排除”UDP 没配好”;
- Gitea 还挂了一个站点统计扩展(site_total.sock),与 bt-monitor.sock 相互独立,无证据表明它阻断了监控链路,排除”统计插件抢占 socket”。
发现配置矛盾
继续对比正常站点和 Gitea 的监控配置,发现 Gitea 这条记录里有一个别的站点都没有的标记:
// /www/server/monitor/config/sites.json 中 Gitea 的条目
{
"site_id": 31,
"is_docker": true
}
矛盾点在于:宝塔站点数据库里这个站点登记的是 PHP 类型,实际 Nginx 配置是反代到 127.0.0.1:2280 的 Docker 服务,而监控配置里却标了 is_docker: true。监控插件源码里,Docker 站点会被走一条单独的处理路径(按 Docker 站点名解析),这个标记和站点实际状态对不上,是最可疑的差异。
修改前备份了 sites.json,然后移除 is_docker 字段,只保留 site_id: 31 和原有日志 tag,其他配置(open、save_err_log、slow_time)保持不变。
改完文件还是 0 条?strace 抓出真正根因
改完配置后发真实请求,数据库依然 0 条。这里踩了一个关键坑:只改配置文件不生效。
对时间线做了核对:monitor 进程 08:00:03 启动时加载的是含 is_docker: true 的旧配置,而 sites.json 的修改发生在 08:08——monitor 内存里的站点表从未更新。
用 strace 跟踪 monitor 进程后拿到了实锤:monitor 确实收到了完整的 31__access 报文,但因为它按 Docker 站点路径处理(内部调用 GetDockerSiteNameById,去 docker.db 的 docker_sites 表查名字),而该表是空的,于是记录被静默丢弃,日志里也没有任何报错。这就是”改了文件但现象不变”的原因。
修复:通过面板自带命令通道重载配置
monitor 有一条 UDP 命令通道(就是前面提到的 9030 端口),面板自带 Python 工具可以直接发命令,无需重启进程、无需动 systemd:
cat > /tmp/reload_monitor.py <<EOF
import sys
sys.path.insert(0, "/www/server/panel/plugin/monitor")
from monitor_cmd import udp_cmd
print(udp_cmd("reload_config", timeout=3))
EOF
/www/server/panel/pyenv/bin/python3 /tmp/reload_monitor.py
# 输出: ok
等价于用宝塔面板自带的 Python 解释器执行一行 python3 -c 命令导入 monitor_cmd 模块并调用 udp_cmd("reload_config", timeout=3),返回 ok 即重载成功。
重载配置后,顺带把一直提示的 ip_filter.sock 权限问题也修了:该 socket 属主是 root,改回 bt-monitor:bt-monitor 即可。
验证结果
- 修复前:当天
access-20260822.db记录数为 0,测试请求也不入库; - 修复后:真实请求开始持续入库(首批 6 条,十几分钟后 11 条,随流量增长)。注意 monitor 是批处理的,有 10~20 秒延迟,刚发完请求立刻查库是 0 条属正常现象;
- 监控报表 URI 维度里能看到
/api/v1/version等 Gitea 请求记录; - 对照组
node.example.com全程正常,证明链路本身没问题。
防复发与经验总结
防复发:面板的周期性配置检查(plugin/monitor/service.py 的 check_config)会把 Docker 管理中登记的站点重新写回 is_docker 标记。本次场景下 docker.db 的 docker_sites 表为空,不会复发;如果将来在宝塔 Docker 管理中登记该站点,需要重新评估这个标记。
排查经验:
- 先看对照组:同机器正常站点和异常站点逐层对比(socket、tag、数据库、配置字段),能快速锁定差异点;
- 改配置要确认进程重载:monitor 这类常驻进程启动时把配置读进内存,改文件 ≠ 生效。排查”改了没用”时,先对比进程启动时间和文件修改时间;
- strace 是黑盒进程的透视眼:monitor 收包后静默丢弃、不报错,常规日志排查毫无头绪,strace 一看便知”收到了但没处理”;
- 优先用面板自带通道:reload_config 这类命令比重启进程安全,比手动重建服务可控;
- 改动前留备份:sites.json 这类面板管理的文件,改之前一定要留
.bak备份,出问题可以直接回滚。