6.8 KiB
系统监测简易运维指南
定位与访问边界
系统监测用于单实例或小规模 CTMS 部署的日常巡检、访问追踪和初步故障定位,不替代集中式指标、日志和告警平台。监测页面及 /api/v1/permission-monitoring/* 仅允许系统管理员访问,项目 PM 不具备系统级监测权限。
健康检查
GET /health:进程存活探针,不访问数据库,适合判断 HTTP 服务是否仍在响应。GET /readyz:服务就绪探针,会执行数据库查询;数据库不可用时返回503。Nginx、安装脚本和后端容器健康检查均使用或暴露此探针。GET /api/v1/permission-monitoring/health:管理员健康详情,包含权限检查质量、缓存、进程内告警、数据库延迟、权限/安全日志写入队列、留存任务和监测表数据量。
部署后的最小检查:
curl -fsS http://127.0.0.1:8888/health
curl -fsS http://127.0.0.1:8888/readyz
docker compose ps
数据留存
后台任务在应用启动后立即清理一次,之后按固定间隔执行。默认策略:
- 权限访问日志和安全访问日志:90 天。
- 权限小时指标:400 天。
- 账号登录活动:180 天。
- 清理周期:86400 秒(每天)。
可通过后端环境变量调整:
MONITORING_ACCESS_LOG_RETENTION_DAYS=90
MONITORING_METRIC_RETENTION_DAYS=400
MONITORING_RETENTION_INTERVAL_SECONDS=86400
MONITORING_IP_GEO_FALLBACK_ENABLED=true
MONITORING_IP_GEO_FALLBACK_TIMEOUT_SECONDS=2.5
MONITORING_IP_GEO_FALLBACK_CACHE_SECONDS=604800
MONITORING_IP_GEO_FALLBACK_MAX_LOOKUPS=10
USER_LOGIN_ACTIVITY_RETENTION_DAYS=180
USER_SESSION_ONLINE_SECONDS=300
访问日志留存范围为 7–3650 天,指标留存范围为 30–3650 天,清理周期范围为 60–604800 秒。修改后需重启后端。正式环境部署新版本前必须先执行 Alembic migration。
账号管理页的“在线”状态由服务端会话心跳计算:最近 USER_SESSION_ONLINE_SECONDS 秒内成功心跳且未退出的会话视为在线。登录记录保存客户端类型、版本、服务端观测到的登录 IP、登录/最近活动/退出时间;IP 属地由本地离线数据库按需解析,不发送到外部服务。登录记录接口仅限系统管理员访问并禁止 HTTP 缓存,不保存 Token 或密码,并与登录活动一起按 USER_LOGIN_ACTIVITY_RETENTION_DAYS 清理。
登录 IP 只接受可信反向代理提供的转发地址。Docker Compose 默认信任容器常用的 172.16.0.0/12 和 192.168.0.0/16 内部网段;其他部署必须通过 TRUSTED_PROXY_CIDRS 明确配置实际代理网段,不得直接信任任意来源的 X-Forwarded-For。
来源地图服务器位置
来源地图中的服务器标记不使用固定城市或前端坐标。后端启动时按以下顺序确定部署服务器的公网地址,并缓存定位结果:
MONITORING_SERVER_PUBLIC_IP明确指定的公网 IP,适用于禁止主动访问公网探测服务的生产网络。FRONTEND_PUBLIC_URL主机名解析出的公网 IP。MONITORING_PUBLIC_IP_DISCOVERY_URLS配置的公网出口 IP 查询服务。
默认公网查询服务为 https://api64.ipify.org,https://icanhazip.com,单次超时 2.5 秒。解析成功后通过本地 ip2region 数据库确定属地并转换为地图坐标;本地库没有坐标时复用下述 IP2Location.io 受控兜底。两条链路均失败时 API 返回 server_location: null,地图不会使用任意默认城市代替。默认打开全球视图,以便服务器与访问来源分属不同国家时仍能完整显示飞线。
访问来源坐标兜底
访问来源始终先使用本地 ip2region 和内置行政区质心解析。只有公网 IP 已识别、但本地链路无法得到地图坐标时,后端才调用 IPAddress.my 使用的 IP2Location.io 官方 JSON API https://api.ip2location.io/ 补充经纬度;私网、回环、链路本地和无效地址不会发送给第三方。
兜底默认启用,单次请求最多查询 10 个尚未缓存的公网 IP,最多并发 5 个请求,超时 2.5 秒。成功结果缓存 7 天,失败结果缓存 1 小时;第三方不可用时继续返回本地解析结果,不影响访问来源接口。可设置 MONITORING_IP_GEO_FALLBACK_ENABLED=false 完全禁用外部查询。无密钥模式受服务方每日额度限制;如需配置 API Key,使用 MONITORING_IP_GEO_FALLBACK_API_KEY,后端通过 Authorization: Bearer 发送,禁止把密钥写入 URL 或日志。
受限网络建议显式配置:
MONITORING_SERVER_PUBLIC_IP=<部署服务器公网IP>
MONITORING_PUBLIC_IP_DISCOVERY_URLS=
公网 IP 仅用于服务端定位,不写入来源分析 API 响应或浏览器界面。
日志完整性与隐私
- 每个请求由服务端生成 UUID 请求标识,并通过响应头
X-Request-ID返回;权限日志和安全日志以该标识消除同一请求的重复统计。 - 写入队列保持非阻塞;队列满或数据库批次写入最终失败时不阻塞业务请求,但会累计丢弃量、失败批次、队列占用和最近错误时间,并在管理员健康页显示降级。
- 请求正文不采集。请求头仅保留运维白名单字段,认证、Cookie、密钥类字段统一脱敏;查询参数中的令牌、账号、受试者/患者、姓名、邮箱、电话、证件和地址类值会替换为
[redacted]。 - IP、User-Agent 和请求路径仍属于运维审计数据,应按管理员最小授权和上述留存策略管理,不应复制到公开工单或通知正文。
常见异常处理
| 现象 | 首要检查 | 建议处理 |
|---|---|---|
/health 正常、/readyz 返回 503 |
数据库容器、连接串、迁移状态 | 检查 docker compose ps、数据库日志和 alembic current |
| 日志写入器降级 | 队列占用、丢弃量、失败批次、最近错误 | 检查数据库连接和容量;恢复后确认队列回落并重启以清零进程累计计数 |
| 留存任务异常 | 最近成功/错误时间 | 检查数据库权限、表结构和后端日志,确认 migration 已升级 |
| 页面显示“可能是上次成功结果” | 对应 API 或网络请求 | 使用刷新按钮重试,并结合 /readyz 与浏览器网络面板定位 |
| 安全事件突然增多 | 分类、来源 IP、路径和状态码 | 优先核对敏感路径探测、5xx 和无效令牌,不要仅按 4xx 总量或地理位置判断 |
当前边界与后续升级
权限缓存指标、告警列表和写入器累计计数仍为单进程内存状态,重启后会重置;当前也不负责短信、邮件、Slack 等外部通知。需要多实例部署、跨重启趋势、值班通知或长期容量分析时,应接入 Prometheus/OpenTelemetry、集中日志和 Alertmanager 类告警链路,并保留本模块作为管理员快速诊断入口。