# Prometheus 指标

> 通过 diagnostics-prometheus 插件将 OpenClaw 诊断数据公开为 Prometheus 文本指标

- 网址：https://funcoding.ai/agents/openclaw/gateway/prometheus/
- 来源：OpenClaw 官方文档原文（中文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/gateway/prometheus

---
OpenClaw 可通过官方
`diagnostics-prometheus` 插件公开诊断指标。它会监听可信诊断以及
内部标记、由调度器负责的诊断事件（队列、内存和
会话恢复信号），并在以下地址提供 Prometheus 文本端点：

```text
GET /api/diagnostics/prometheus
```

内容类型为 `text/plain; version=0.0.4; charset=utf-8`，即标准的
Prometheus 展示格式。

<div class="callout callout-warning">

该路由使用 Gateway 网关身份验证（操作员权限范围、可信操作员接口）。不要将其作为公开且未经身份验证的 `/metrics` 端点暴露。请通过用于其他操作员 API 的同一身份验证路径抓取该端点。

</div>

有关跟踪、日志、OTLP 推送和 OpenTelemetry GenAI 语义属性，请参阅 [OpenTelemetry 导出](https://funcoding.ai/agents/openclaw/gateway/opentelemetry/)。

## 快速开始

**安装插件**

```bash
openclaw plugins install clawhub:@openclaw/diagnostics-prometheus
```

**启用插件**

**配置**

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

**CLI**

```bash
openclaw plugins enable diagnostics-prometheus
```

**重启 Gateway 网关**

HTTP 路由会在插件启动时注册，因此启用后需要重新加载。

**抓取受保护的路由**

发送操作员客户端所使用的同一 Gateway 网关身份验证信息：

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

**接入 Prometheus**

```yaml
# 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"]
```

<div class="callout callout-note">

`diagnostics.enabled` 默认为 `true`；仅在受到严格约束的环境中将其设为 `false`。如果它为 `false`，插件仍会注册 HTTP 路由，但不会有诊断事件流入导出器，因此响应为空。

</div>

## 导出的指标

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

对于模型调用指标，`observation_unit="request"` 衡量一次可观测的
提供商请求。`observation_unit="turn"` 衡量一次合成的 Claude Code
或 Codex CLI 智能体轮次，其中可能包含多个隐藏的提供商请求。
比较延迟时，请将这些序列分开。

## 标签策略

<details>
<summary>有界、低基数标签</summary>

Prometheus 标签保持有界且低基数。导出器不会发出原始诊断标识符，例如 `runId`、`sessionKey`、`sessionId`、`callId`、`toolCallId`、消息 ID、聊天 ID 或提供商请求 ID。

标签值会被脱敏，并且必须符合 OpenClaw 的低基数字符策略。不符合该策略的值将根据指标替换为 `unknown`、`other` 或 `none`。看起来像带作用域的智能体会话键的标签也会替换为 `unknown`。

</details>

<details>
<summary>序列上限和溢出计数</summary>

导出器将在内存中保留的时间序列总数限制为 **2048** 个，此限制涵盖计数器、仪表和直方图。超过此上限的新序列会被丢弃，并且每次都会使 `openclaw_prometheus_series_dropped_total` 增加 1。

请监控此计数器；它是上游某个属性正在泄漏高基数值的明确信号。导出器绝不会自动提高上限；如果该值持续上升，应修复来源，而不是禁用上限。

</details>

<details>
<summary>Prometheus 输出中绝不会出现的内容</summary>

- 提示词文本、响应文本、工具输入、工具输出、系统提示词
- Talk 转录文本、音频载荷、通话 ID、房间 ID、移交令牌、轮次 ID 和原始会话 ID
- 原始提供商请求 ID（如适用，仅在 span 上使用有界哈希值——绝不会用于指标）
- 会话键和会话 ID
- 主机名、文件路径、密钥值

</details>

## PromQL 配方

```promql
# 每分钟的 token 数，按提供商拆分
sum by (provider) (rate(openclaw_model_tokens_total[1m]))

# 过去一小时的支出（美元），按模型统计
sum by (model) (increase(openclaw_model_cost_usd_total[1h]))

# 模型运行时长的第 95 百分位数
histogram_quantile(
  0.95,
  sum by (le, provider, model)
    (rate(openclaw_run_duration_seconds_bucket[5m]))
)

# 队列等待时间 SLO（第 95 百分位数低于 2 秒）
histogram_quantile(
  0.95,
  sum by (le, lane) (rate(openclaw_queue_lane_wait_seconds_bucket[5m]))
) < 2

# Skills 使用情况，按有界来源拆分
sum by (skill, source) (increase(openclaw_skill_used_total[24h]))

# 被丢弃的 Prometheus 序列（基数警报）
increase(openclaw_prometheus_series_dropped_total[15m]) > 0
```

<div class="callout callout-tip">

对于跨提供商仪表板，优先使用 `gen_ai_client_token_usage`：它遵循 OpenTelemetry GenAI 语义约定，并与非 OpenClaw GenAI 服务的指标保持一致。

</div>

## 在 Prometheus 与 OpenTelemetry 导出之间进行选择

OpenClaw 独立支持这两种接口。你可以运行其中任意一种、同时运行两种，或两种都不运行。

**diagnostics-prometheus**

- **拉取**模型：Prometheus 抓取 `/api/diagnostics/prometheus`。
- 无需外部收集器。
- 通过常规 Gateway 网关身份验证进行认证。
- 该接口仅包含指标（不包含追踪或日志）。
- 最适合已标准化采用 Prometheus + Grafana 的技术栈。

**diagnostics-otel**

- **推送**模型：OpenClaw 通过 OTLP/HTTP 向收集器或兼容 OTLP 的后端发送数据。
- 该接口包含指标、追踪和日志。
- 需要同时使用两者时，可通过 OpenTelemetry Collector（`prometheus` 或 `prometheusremotewrite` 导出器）桥接到 Prometheus。
- 完整目录请参阅 [OpenTelemetry 导出](https://funcoding.ai/agents/openclaw/gateway/opentelemetry/)。

## 故障排查

<details>
<summary>响应正文为空</summary>

- 检查配置中的 `diagnostics.enabled` 是否未设置为 `false`（其默认值为 `true`）。
- 使用 `openclaw plugins list --enabled` 确认插件已启用并加载。
- 生成一些流量；计数器和直方图只有在至少发生一个事件后才会输出行。

</details>

<details>
<summary>401 / 未授权</summary>

该端点需要 Gateway 网关操作员权限范围（`auth: "gateway"` 和 `gatewayRuntimeScopeSurface: "trusted-operator"`）。请使用 Prometheus 访问任何其他 Gateway 网关操作员路由时所用的相同令牌或密码。不提供公开的未认证模式。

</details>

<details>
<summary>`openclaw_prometheus_series_dropped_total` 持续上升</summary>

某个新属性正在导致序列数超过 **2048** 个的上限。检查最近的指标，查找基数异常高的标签，并从源头修复。导出器会有意丢弃新序列，而不是静默重写标签。

</details>

<details>
<summary>重启后 Prometheus 显示陈旧序列</summary>

该插件仅在内存中保存状态。Gateway 网关重启后，计数器会重置为零，仪表则从下一次报告的值重新开始。使用 PromQL `rate()` 和 `increase()` 可正确处理重置。

</details>

## 相关内容

- [诊断导出](https://funcoding.ai/agents/openclaw/gateway/diagnostics/) — 用于支持包的本地诊断 zip 文件
- [健康状态和就绪状态](https://funcoding.ai/agents/openclaw/gateway/health/) — `/healthz` 和 `/readyz` 探针
- [日志](https://funcoding.ai/agents/openclaw/logging/) — 基于文件的日志记录
- [OpenTelemetry 导出](https://funcoding.ai/agents/openclaw/gateway/opentelemetry/) — 通过 OTLP 推送追踪、指标和日志
