首页
/ OpenClaw diagnostics-prometheus 插件:从安装、受保护端点到 2048 序列上限的运行时指标导出全解

OpenClaw diagnostics-prometheus 插件:从安装、受保护端点到 2048 序列上限的运行时指标导出全解

2026-09-04 17:39:36作者:滑思眉Philip

OpenClaw 的 diagnostics-prometheus 插件把 Gateway 的运行时诊断事件(模型调用、工具执行、消息收发、队列与内存信号等)转换成标准 Prometheus 文本格式,供 Prometheus、Grafana、VictoriaMetrics 等抓取器拉取。本文以 插件参考文档 为主体,结合插件源码与 Gateway 指标文档,完整覆盖分发信息、安装启用、端点注册、指标目录、标签策略与排障要点,并逐层展开到源码级的实现证据。

插件概览:Surface 是 plugin,分发渠道是 npm 与 ClawHub

参考文档对该插件的定位非常明确:它是 OpenClaw 的诊断 Prometheus 导出器(exporter for runtime metrics),分发信息如下:

  • 包名:@openclaw/diagnostics-prometheus
  • 安装渠道:npm;ClawHub 规格为 clawhub:@openclaw/diagnostics-prometheus
  • Surface(能力面):plugin

仓库中的元数据可以进一步印证这些事实。package.json 中声明了两种安装规格与宿主版本约束:

"install": {
  "clawhubSpec": "clawhub:@openclaw/diagnostics-prometheus",
  "npmSpec": "@openclaw/diagnostics-prometheus",
  "defaultChoice": "npm",
  "minHostVersion": ">=2026.4.25"
},
"compat": {
  "pluginApi": ">=2026.8.1"
}

也就是说,该插件默认通过 npm 安装,要求 OpenClaw 宿主版本不低于 2026.4.25。插件清单 openclaw.plugin.json 则声明了插件 id 为 diagnostics-prometheus,且 activation.onStartuptrue——Gateway 启动时即激活该插件:

{
  "id": "diagnostics-prometheus",
  "name": "Diagnostics Prometheus",
  "description": "OpenClaw diagnostics Prometheus exporter for runtime metrics.",
  "activation": { "onStartup": true },
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}

值得注意的是,configSchema 是一个带 additionalProperties: false 的空对象。从源码结构看,当前版本的抓取端点路径、认证方式是固定的,插件没有对外暴露可配置项;plugins.entries.diagnostics-prometheus.config 下无需(也不允许)添加额外字段。

安装、启用与抓取端点

安装命令

插件 README 的说明,安装命令为:

openclaw plugins install @openclaw/diagnostics-prometheus

安装或更新插件后需要重启 Gateway,因为 HTTP 路由是在插件启动阶段注册的。

启用插件

docs/gateway/prometheus.md 给出了配置与 CLI 两种启用方式。配置方式(JSON5):

{
  plugins: {
    allow: ["diagnostics-prometheus"],
    entries: {
      "diagnostics-prometheus": { enabled: true },
    },
  },
  diagnostics: {
    enabled: true,
  },
}

CLI 方式:

openclaw plugins enable diagnostics-prometheus

其中 diagnostics.enabled 默认为 true;只有强约束环境才建议设为 false。文档明确提示:即使该值为 false,插件仍会注册 HTTP 路由,但没有任何诊断事件流入导出器,抓取响应将为空。

抓取受保护端点

端点为 GET /api/diagnostics/prometheus,Content-Type 是 text/plain; version=0.0.4; charset=utf-8,即标准 Prometheus exposition 格式。该路由使用 Gateway 认证(operator 作用域、trusted-operator 表面),不应作为无认证的公开 /metrics 端点暴露。带同一套 Gateway 鉴权的手动验证命令:

curl -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
  http://127.0.0.1:18789/api/diagnostics/prometheus

Prometheus 侧接入示例:

# prometheus.yml
scrape_configs:
  - job_name: openclaw
    scrape_interval: 30s
    metrics_path: /api/diagnostics/prometheus
    authorization:
      credentials_file: /etc/prometheus/openclaw-gateway-token
    static_configs:
      - targets: ["openclaw-gateway:18789"]

端点注册与事件订阅:源码级调用链

插件入口 index.ts 通过 definePluginEntry 完成两件事——注册服务与注册 HTTP 路由:

export default definePluginEntry({
  id: "diagnostics-prometheus",
  name: "Diagnostics Prometheus",
  description: "Expose OpenClaw diagnostics metrics in Prometheus text format",
  register(api) {
    api.registerService(exporter.service);
    api.registerHttpRoute({
      path: "/api/diagnostics/prometheus",
      auth: "gateway",
      match: "exact",
      gatewayRuntimeScopeSurface: "trusted-operator",
      handler: exporter.handler,
    });
  },
});

几个关键点:

  • auth: "gateway" + gatewayRuntimeScopeSurface: "trusted-operator":这就是文档中"operator 作用域"警告的源码出处,端点与其余 operator API 走同一认证路径;
  • match: "exact":精确匹配 /api/diagnostics/prometheus,不接受前缀路径;
  • 路由 handler 与指标存储由 createDiagnosticsPrometheusExporter() 统一创建,二者共享同一个内存存储实例。

核心实现位于 src/service.ts。服务生命周期(service.ts 约 L1019-L1089):

  • start:从 ctx.internalDiagnostics.onEvent 订阅诊断事件流,每个事件调用 recordDiagnosticEvent(store, event, metadata),单事件处理失败只记日志、不中断订阅;随后向内部诊断桥上报 telemetry.exporter 启动事件(status: "started")。若内部诊断能力不可用,仅记录 error 日志。
  • stop:取消订阅,上报 status: "dropped",并调用 store.reset() 清空全部指标。

事件过滤逻辑在 shouldRecordDiagnosticEventservice.ts L215-L217):

function shouldRecordDiagnosticEvent(metadata: DiagnosticEventMetadata): boolean {
  return metadata.trusted || isInternalDiagnosticEventMetadata(metadata);
}

即只有"可信(trusted)"事件或"内部标记、由 dispatcher 持有"的诊断事件(队列、内存、会话恢复等信号)会被计入指标,与 Gateway 指标文档 开头的描述一致。

内存指标存储与 2048 序列上限

createPrometheusMetricStoreservice.ts L96-L203)用三个 Map(counters / gauges / histograms)维护全部指标序列,序列键为 指标名|排序后的标签 JSON,保证同标签组合幂等聚合:

  • counter:只接受正的有限数值,累加到既有样本;
  • gauge:直接覆盖为最新值;
  • histogram:按桶阈值 value <= bucket 累加计数,同时维护 countsum
  • snapshot:返回浅拷贝,保证渲染期间不被并发写入干扰;
  • reset:插件停止时整体清空。

防基数爆炸的核心机制是序列上限:

const MAX_PROMETHEUS_SERIES = 2048;
const DROPPED_SERIES_COUNTER_NAME = "openclaw_prometheus_series_dropped_total";

当三个 Map 的序列总数达到 2048 后,任何序列(既有序列除外)直接丢弃并累加 openclaw_prometheus_series_dropped_total。文档建议把这个计数器当作"上游某属性在泄漏高基数值"的硬信号——导出器从不会自动放宽上限,正确做法是修复标签来源而不是抬高上限。

直方图桶设计

service.ts L48-L56 定义了四组固定桶阈值,分别对应不同量纲的观测值:

桶数组 取值范围 用途
DURATION_BUCKETS_SECONDS 0.005s ~ 600s(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600) 各类耗时直方图的默认桶
TOKEN_BUCKETS 1 ~ 1048576(1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576) Token 用量分布
BYTE_BUCKETS 1KB ~ 16GB(1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296, 17179869184) 音频帧、RSS 内存、超大载荷字节数
RATIO_BUCKETS 0.01 ~ 16(0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 1, 2, 4, 8, 16) 事件循环利用率、CPU 核占比等比率

所有耗时事件在入库前经 seconds(ms) 将毫秒转为秒(service.ts L60-L63),非有限值会被丢弃。

标签策略与敏感信息边界

参考文档的"Surface: plugin"之下,这套指标体系最重要的约束是低基数标签策略。源码层面,所有标签值都经过 normalizeDiagnosticValue(来自 openclaw/plugin-sdk/diagnostic-runtime)归一化,并按指标不同在失败时回退为 unknown / other / none。文档与实现共同确认的边界:

  • 不出现在 Prometheus 输出中的原始标识runIdsessionKeysessionIdcallIdtoolCallId、消息 ID、聊天 ID、provider 请求 ID 一律不输出;看起来像 scope 化会话键的值会被替换为 unknown
  • 永不进入指标的内容:prompt/响应文本、工具输入输出、系统提示词、Talk 转录与音频载荷、会话键、主机名、文件路径、密钥值等。
  • 错误信息处理同样受控:safeErrorMessageservice.ts L205-L213)先经 redactSensitiveText 脱敏,再去除控制字符并截断到 500 字符,只用于内部日志,不进入指标标签。

指标目录

以下是 Gateway 指标文档 的完整指标表,与 recordDiagnosticEventservice.ts L538 起)中各 case 分支一一对应:

指标 类型 标签
openclaw_run_completed_total counter channel, model, outcome, provider, trigger
openclaw_run_duration_seconds histogram channel, model, outcome, provider, trigger
openclaw_model_call_total counter api, error_category, model, observation_unit, outcome, provider, transport
openclaw_model_call_duration_seconds histogram 同上
openclaw_model_failover_total counter from_model, from_provider, lane, reason, suspended, to_model, to_provider
openclaw_model_tokens_total counter agent, channel, model, provider, token_type
openclaw_gen_ai_client_token_usage histogram model, provider, token_type
openclaw_model_cost_usd_total counter agent, channel, model, provider
openclaw_model_usage_duration_seconds histogram agent, channel, model, provider
openclaw_skill_used_total counter activation, agent, skill, source
openclaw_tool_execution_total counter error_category, outcome, params_kind, tool, tool_owner, tool_source
openclaw_tool_execution_duration_seconds histogram 同上
openclaw_tool_execution_blocked_total counter denied_reason, params_kind, tool, tool_owner, tool_source
openclaw_harness_run_total counter channel, error_category, harness, model, outcome, phase, plugin, provider
openclaw_harness_run_duration_seconds histogram 同上
openclaw_webhook_received_total counter channel, webhook
openclaw_webhook_error_total counter channel, webhook
openclaw_webhook_duration_seconds histogram channel, webhook
openclaw_message_received_total counter channel, source
openclaw_message_dispatch_started_total counter channel, source
openclaw_message_dispatch_completed_total counter channel, outcome, reason, source
openclaw_message_dispatch_duration_seconds histogram channel, outcome, reason, source
openclaw_message_processed_total counter channel, outcome, reason
openclaw_message_processed_duration_seconds histogram channel, outcome, reason
openclaw_message_delivery_started_total counter channel, delivery_kind
openclaw_message_delivery_total counter channel, delivery_kind, error_category, outcome
openclaw_message_delivery_duration_seconds histogram 同上
openclaw_talk_event_total counter brain, event_type, mode, provider, transport
openclaw_talk_event_duration_seconds histogram 同上
openclaw_talk_audio_bytes histogram 同上
openclaw_queue_lane_size gauge lane
openclaw_queue_lane_wait_seconds histogram lane
openclaw_session_state_total counter reason, state
openclaw_session_queue_depth gauge state
openclaw_session_turn_created_total counter agent, channel, trigger
openclaw_session_stuck_total counter reason, state
openclaw_session_stuck_age_seconds histogram reason, state
openclaw_session_recovery_total counter action, active_work_kind, state, status
openclaw_session_recovery_age_seconds histogram 同上
openclaw_liveness_warning_total counter reason
openclaw_liveness_sessions gauge state
openclaw_liveness_event_loop_delay_p99_seconds histogram reason
openclaw_liveness_event_loop_delay_max_seconds histogram reason
openclaw_liveness_event_loop_utilization_ratio histogram reason
openclaw_liveness_cpu_core_ratio histogram reason
openclaw_payload_large_total counter action, channel, plugin, reason, surface
openclaw_payload_large_bytes histogram 同上
openclaw_memory_bytes gauge kind
openclaw_memory_rss_bytes histogram
openclaw_memory_pressure_total counter level, reason
openclaw_telemetry_exporter_total counter exporter, reason, signal, status
openclaw_prometheus_series_dropped_total counter
openclaw_diagnostic_async_queue_dropped_total counter drop_class
openclaw_diagnostic_async_queue_length gauge

两个值得在仪表盘设计时注意的语义细节:

  • observation_unit"request" 度量一次可观测的 provider 请求;"turn" 度量一次可能包含多次隐藏 provider 请求的合成 agent turn(如 Claude Code 或 Codex CLI 场景)。对比延迟时应把两类序列分开看。
  • openclaw_model_tokens_totaltoken_type 覆盖 inputoutputcache_readcache_writeprompttotal;其中仅 input/output 会额外写入符合 OpenTelemetry GenAI 语义约定的 openclaw_gen_ai_client_token_usage 直方图,便于跨 provider、跨服务统一做 Token 看板。
  • openclaw_memory_bytes 同时输出 kind="rss"kind="heap_total"kind="heap_used" 三条 gauge 序列,rss 样本另入字节桶直方图。

文本格式渲染与 HTTP 行为

renderPrometheusMetricsservice.ts L219-L277)负责把快照渲染成 exposition 文本:

  • 按指标名输出一次 # HELP / # TYPE 头(emitted Set 去重),help 文本中的反斜杠与换行会被转义;
  • counter、gauge、histogram 三类样本分别按序列键字典序排序后逐条输出,保证同一份数据的输出是确定性的;
  • 标签按 key 排序输出,标签值中的 \、换行、双引号均转义;
  • 每个直方图额外输出 +Inf 桶、_sum_count 行,符合 Prometheus 客户端库惯例;
  • 数值格式化:非有限值输出 0,整数按整数字面量输出,浮点保留 12 位有效精度。

HTTP handler 的行为(createMetricsHandlerservice.ts L979-L999):

  • 仅接受 GETHEAD,其他方法返回 405 并带 Allow: GET, HEAD
  • 响应头包含 Cache-Control: no-store、标准 Prometheus Content-Type 与精确 Content-Length
  • HEAD 只返回头不返回体。

常用 PromQL 配方

以下配方来自 Gateway 指标文档,可直接用于告警与看板:

# Tokens per minute, split by provider
sum by (provider) (rate(openclaw_model_tokens_total[1m]))

# Spend (USD) over the last hour, by model
sum by (model) (increase(openclaw_model_cost_usd_total[1h]))

# 95th percentile model run duration
histogram_quantile(
  0.95,
  sum by (le, provider, model)
    (rate(openclaw_run_duration_seconds_bucket[5m]))
)

# Queue wait time SLO (95p under 2s)
histogram_quantile(
  0.95,
  sum by (le, lane) (rate(openclaw_queue_lane_wait_seconds_bucket[5m]))
) < 2

# Skill usage, split by bounded source
sum by (skill, source) (increase(openclaw_skill_used_total[24h]))

# Dropped Prometheus series (cardinality alarm)
increase(openclaw_prometheus_series_dropped_total[15m]) > 0

跨 provider 的 Token 看板建议优先使用 openclaw_gen_ai_client_token_usage,因为它遵循 OpenTelemetry GenAI 语义约定,与非 OpenClaw 的 GenAI 服务指标保持口径一致。

与 OpenTelemetry 导出的分工

OpenClaw 同时提供两个相互独立的遥测面,可以只启用其一、两者都启用、或都不启用:

  • diagnostics-prometheus(本文主题):Pull 模型,Prometheus 抓取 /api/diagnostics/prometheus;无需外部 collector;走 Gateway 认证;仅指标面(无 trace、log)。适合已以 Prometheus + Grafana 为标准的栈。
  • diagnostics-otel:Push 模型,通过 OTLP/HTTP 推送到 collector 或兼容后端;覆盖指标、trace、log;如需要两者兼得,可经由 OpenTelemetry Collector 的 prometheus / prometheusremotewrite 导出器桥接到 Prometheus。

排障清单

结合文档与源码行为,常见问题与排查路径:

  1. 响应体为空:确认 diagnostics.enabled 未被设为 false(默认 true);用 openclaw plugins list --enabled 确认插件已启用并加载;制造一些真实流量——counter 与 histogram 至少需要一个事件后才会输出序列行。
  2. 401 / 未授权:端点要求 Gateway operator 作用域(auth: "gateway" + trusted-operator 表面),使用与其他 Gateway operator 路由相同的 token 或凭据;不存在公开的免认证模式。
  3. openclaw_prometheus_series_dropped_total 持续增长:某属性突破了 2048 序列上限。检查近期指标中意外高基数的标签并在源头修复;导出器刻意丢弃新序列而不是静默改写标签。
  4. 重启后出现陈旧序列:插件状态完全在内存中。Gateway 重启后 counter 归零、gauge 从下一次上报值重新开始;PromQL 中用 rate() / increase() 即可正确处理重置。

另外可从源码推断一个行为细节:store.reset()stop() 中调用(service.ts L1063-L1079),因此插件被禁用或 Gateway 重启后,指标状态不会残留,这与上述"重启后归零"的排障结论一致。插件行为另有单测与安装运行时 e2e 测试覆盖,可参考 service.test.tsinstall-runtime.e2e.test.ts

参考路径

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
983
503
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384