# 运行监控与 Prometheus 接入(v0.14) 后台「运行监控」提供只读状态,每 10 秒刷新,可关闭自动刷新。权限是 `monitor.read`,系统管理员默认可访问。管理员可以创建仅含此权限的监控角色;监控角色不因此获得应用启停、用户管理或发布权限。模块不得使用保留 ID `monitor`。 ## 指标口径 - HTTP:按服务器路由模板聚合完成数、错误数、处理中请求、耗时直方图。包括 4xx/5xx,不按原始 URL、账号、IP 或请求号分组。未匹配请求共用固定标签。 - 动作:按模块/动作记录执行入口的接纳、排队、权限和后端调用总耗时;完成数包含被限流和拒绝的请求。HTTP 层提前拒绝的请求只进入 HTTP 指标,不进入动作指标。业务失败、限流、超时、结果未知分别统计。 - 反向 RPC:按模块与公共服务聚合完成、失败、处理中和耗时,包括身份、记录等服务;kind 为 callback,与外层 HTTP/动作计数不可直接相加。 - P95:页面按累计直方图计算所在区间上界,不是精确采样百分位,也不是近一分钟 P95。 - 近 60 秒:显示动作完成数和失败数,失败包含限流、拒绝和取消;不是独立的服务器故障率。 - 模块:运行/异常/主动停止、执行中、等待、自动恢复周期内重试次数。重试次数会随稳定运行/手动启动清零,不是单调累加的 counter。 - Go:堆内存、运行时向系统申请的内存、goroutine、GC 次数及累计暂停。Go memory 不是宿主内存,也不是进程 RSS。 - 容器:通过一次 `docker stats --no-stream` 批量读取 OA 当前模块,缓存 15 秒,最多 64 个。CPU 100% 对应一核;内存采用 Docker CLI 工作集口径,限额和运行策略见 Docker 管理。原生模式没有容器资源样本。 指标和最多 100 条最近请求保存在内存,底座重启清零。指标最多 512 个常规序列,额外请求汇入一个 other 序列,防止未知模块制造无限标签。容器采集有 5 秒期限;采集和模块状态读锁均有边界,采集失败显示不可用,不能当成 0。并发采集可能短暂显示正在采集。监控请求自身也在 HTTP 统计中。 界面内置提示:模块异常、等待队列至少 3、容器内存至少 80%,以及最近 60 秒至少 10 次动作且失败比例至少 20%。这些只是当前状态提示,不会发送邮件或消息。持续告警、历史趋势和长期保留需配置 Prometheus/Grafana/Alertmanager 等外部服务;本次未安装这些服务。 ## 接口与请求定位 `GET /api/monitoring` 返回 JSON;`GET /api/monitoring/metrics` 返回 Prometheus text 0.0.4。两个接口均要求已登录且具 `monitor.read`,或使用具有该权限的个人 API Key。接口没有匿名豁免。建议创建明确限制为 `["monitor.read"]` 的 Key,不使用拥有全部管理权限的 Key。 每个 HTTP 响应包含底座生成的 `X-Trace-ID`。动作与其 HTTP 请求使用相同 Trace ID;它与用于业务去重的 request_id 不同。最近请求只含时间、接口模板/模块动作、结果、耗时和 Trace ID,不含正文、用户邮箱、Key、Cookie 或业务 request_id。 失败 HTTP 请求写 JSON 结构化平台日志,包括 event、trace_id、route、status、duration_ms;每进程最多 10 条/秒,超出部分仍计数但日志被采样丢弃。可在已有轮转日志或 `journalctl -u oa-platform` 中按 trace_id 检索。当前没有跨服务 OpenTelemetry span、调用链存储或远程日志聚合。 `GET /healthz` 只检查进程响应。`GET /readyz` 在所有已注册且未主动停止的模块正常时返回 200,否则返回 503;维护时读取状态超时也会 503。两者只公开通用状态,不暴露模块清单和错误详情;主动暂停不影响 ready。当前 readiness 不验证业务数据读写、邮件、云连接器或所有外部依赖。 ## Prometheus 采集示例 把真实监控 Key 保存在 Prometheus 主机的受保护文件 `/etc/prometheus/secrets/oa-monitor-key`,不要写入源码、URL 或 YAML。设置文件所有权为 Prometheus 服务账号,权限 0600。示例仅为接入配置,不自动创建任何生产凭据。 ```yaml scrape_configs: - job_name: oa-platform scheme: https metrics_path: /api/monitoring/metrics scrape_interval: 15s scrape_timeout: 8s authorization: type: Bearer credentials_file: /etc/prometheus/secrets/oa-monitor-key static_configs: - targets: [www.miniyun.com] ``` 常用查询: ```promql # 每秒完成的业务动作(包括拒绝和限流) sum(rate(oa_requests_total{kind="action"}[5m])) # 按模块估计近 5 分钟 P95 histogram_quantile(0.95, sum by (le, module) (rate(oa_request_duration_seconds_bucket{kind="action"}[5m]))) # 读超时或写结果未知 sum by (module, code) (increase(oa_requests_total{kind="action",code=~"DEADLINE_EXCEEDED|OUTCOME_UNKNOWN"}[5m])) # 不运行模块;主动停止也为 0,需按维护策略设置告警抑制 oa_module_up == 0 # 容器采集不可用 oa_container_sample_available == 0 ``` 容器指标只在有效样本时输出,并附采样时间 `oa_container_sample_timestamp_seconds`;采集失败时不输出伪造的 0 资源值。外部告警应同时检查 Prometheus 自身 `up`、样本新鲜度和采集可用性。API Key 到期/撤销会使抓取失败,应纳入值守流程。 指标没有用户或租户标签,不适合作为用户级计费依据。记录范围与业务授权仍由原有机制执行,监控权限不授权访问业务记录正文。 参考官方格式与配置:[Prometheus exposition formats](https://prometheus.io/docs/instrumenting/exposition_formats/)、[Prometheus configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/)。