第 41 章

监控与可观测性:结构化日志、健康检查与告警配置

第41章 监控与可观测性:结构化日志、健康检查与告警配置

41.1 AI Agent 的可观测性挑战

传统软件的行为基本可以预测:给定相同输入,输出稳定一致。然而 AI Agent 的运行方式根本不同——它的决策由大语言模型驱动,同一条指令在不同时间、不同上下文中可能走向完全不同的工具调用路径。这种非确定性使得传统的监控思路在 Agent 场景下严重失效。

41.1.1 为什么 AI Agent 更难监控

路径爆炸:一个简单的"帮我整理邮件"指令可能触发 3 到 20 个工具调用,具体路径取决于当前邮箱状态、模型版本、上下文窗口长度。你无法像传统 API 那样只监控一个固定的调用链。

错误的语义模糊性:当工具返回 HTTP 200 但内容是"找不到相关数据",Agent 可能正常处理,也可能进入无限重试。传统的错误率指标无法捕捉这类语义层面的失败。

时间尺度跨越:一个 Session 可能持续 30 秒(简单查询),也可能持续 4 小时(复杂重构任务)。固定时间窗口的监控指标在这里意义有限。

资源消耗不可预测:LLM 调用的 Token 消耗与 Context Compaction 频率直接影响成本和延迟,而这些在任务开始前难以估计。

工具副作用不可逆:Agent 删除文件、发送邮件、部署服务的操作是单向的。监控必须能在问题发生前发出告警,而不仅仅是事后记录。

41.1.2 OpenClaw 的可观测性设计哲学

OpenClaw 采用结构化日志优先的设计:所有运行时事件以 JSON 格式输出,每个字段都有固定语义,便于机器解析和聚合。健康检查端点提供实时状态快照,而非依赖日志的延迟聚合。告警规则基于业务语义(连续失败、Session 异常),而非简单的技术阈值(CPU > 80%)。

这三个层次共同构成了一套适合 AI Agent 的可观测性体系:日志(发生了什么)、健康检查(现在状态如何)、告警(需要立即响应什么)。


41.2 logging 配置详解

OpenClaw 的日志行为通过 openclaw.jsonlogging 节点控制。

41.2.1 完整配置结构

{
  "logging": {
    "level": "info",
    "format": "json",
    "output": {
      "console": {
        "enabled": true,
        "colorize": false
      },
      "file": {
        "enabled": true,
        "path": "~/.openclaw/logs/openclaw.log",
        "rotation": {
          "maxSize": "100MB",
          "maxFiles": 7,
          "compress": true
        }
      },
      "syslog": {
        "enabled": false,
        "facility": "local0",
        "host": "127.0.0.1",
        "port": 514
      }
    },
    "fields": {
      "service": "openclaw",
      "environment": "production",
      "version": "${OPENCLAW_VERSION}"
    },
    "sampling": {
      "enabled": false,
      "rate": 0.1,
      "excludeLevels": ["error", "warn"]
    }
  }
}

41.2.2 日志级别选择

级别 适用场景 日志量估算
debug 本地开发、问题排查 极高(每工具调用 10-50 条)
info 生产默认,记录关键事件 中等(每工具调用 3-8 条)
warn 只关注潜在问题 低(仅异常情况)
error 只记录失败 极低(仅告警用途)

生产环境建议:默认使用 info 级别。在排查特定 Session 时,可通过以下命令临时切换,无需重启 Gateway:

# 临时升级到 debug 级别(重启后恢复)
openclaw config set logging.level debug

# 仅对特定 Agent 开启 debug
openclaw config set logging.agentFilter "my-agent-id:debug"

# 恢复默认
openclaw config set logging.level info

41.2.3 输出路径规划

生产推荐目录结构:

~/.openclaw/logs/
├── openclaw.log          # 当前日志文件(滚动写入)
├── openclaw.2026-04-25.gz # 压缩归档(自动生成)
├── openclaw.2026-04-24.gz
└── gateway-access.log    # Gateway HTTP 访问日志(独立)

日志轮转参数说明

41.2.4 结构化日志字段示例

一条典型的工具调用日志记录如下:

{
  "timestamp": "2026-04-26T09:23:41.882Z",
  "level": "info",
  "event": "tool_call_completed",
  "agentId": "agent_7f3k2m",
  "sessionId": "sess_9a1b3c",
  "tool": "bash",
  "duration": 342,
  "tokenUsage": {
    "input": 1204,
    "output": 387
  },
  "exitCode": 0,
  "error": null,
  "service": "openclaw",
  "environment": "production",
  "version": "2026.4.22"
}

一条 Session 启动日志:

{
  "timestamp": "2026-04-26T09:23:40.001Z",
  "level": "info",
  "event": "session_started",
  "agentId": "agent_7f3k2m",
  "sessionId": "sess_9a1b3c",
  "trigger": "cron",
  "model": "claude-opus-4-5",
  "thinkingMode": "standard",
  "maxTokenBudget": 50000,
  "parentSessionId": null,
  "service": "openclaw"
}

一条工具失败日志:

{
  "timestamp": "2026-04-26T09:24:11.543Z",
  "level": "error",
  "event": "tool_call_failed",
  "agentId": "agent_7f3k2m",
  "sessionId": "sess_9a1b3c",
  "tool": "web_fetch",
  "duration": 30001,
  "error": {
    "code": "TIMEOUT",
    "message": "Request exceeded 30s timeout",
    "retryCount": 2,
    "willRetry": false
  },
  "service": "openclaw"
}

41.3 健康检查端点解析

Gateway 在本地暴露健康检查端点,用于快速判断服务状态。

41.3.1 端点地址

http://127.0.0.1:18789/health

默认仅监听本地回环地址,不对外网暴露。如需在 CI/CD 或监控系统中远程访问,需在配置中显式开启:

{
  "gateway": {
    "health": {
      "host": "0.0.0.0",
      "port": 18789,
      "auth": {
        "enabled": true,
        "token": "${HEALTH_CHECK_TOKEN}"
      }
    }
  }
}

41.3.2 响应字段完整解析

{
  "status": "healthy",
  "version": "2026.4.22",
  "uptime": 86432,
  "gateway": {
    "status": "running",
    "pid": 12847,
    "port": 18789,
    "connections": {
      "active": 3,
      "idle": 12,
      "total": 58204
    }
  },
  "sessions": {
    "active": 2,
    "queued": 0,
    "completed24h": 147,
    "failed24h": 3,
    "successRate24h": 0.9796
  },
  "models": {
    "current": "claude-opus-4-5",
    "available": ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5"],
    "lastModelCallMs": 1843
  },
  "resources": {
    "memoryUsedMB": 412,
    "memoryLimitMB": 2048,
    "cpuPercent": 12.4,
    "diskAvailableGB": 48.3
  },
  "tools": {
    "registered": 28,
    "errorsLastHour": 1,
    "errorRate1h": 0.012
  },
  "compaction": {
    "count24h": 7,
    "lastCompactionAt": "2026-04-26T08:41:12Z"
  },
  "timestamp": "2026-04-26T09:30:00Z"
}

字段监控价值说明

41.3.3 使用 curl 进行健康检查

# 基础检查
curl -s http://127.0.0.1:18789/health | jq '.status'

# 检查 Session 成功率
curl -s http://127.0.0.1:18789/health | jq '.sessions.successRate24h'

# 检查内存使用
curl -s http://127.0.0.1:18789/health | \
  jq '(.resources.memoryUsedMB / .resources.memoryLimitMB * 100 | round | tostring) + "% memory used"'

# 用于 Kubernetes readiness probe
curl -sf http://127.0.0.1:18789/health && echo "READY" || echo "NOT READY"

41.4 关键日志字段的监控价值

41.4.1 字段索引与含义

字段 类型 监控价值
timestamp ISO 8601 字符串 精确到毫秒,用于延迟计算和时序关联
level 枚举 过滤严重事件,error 级别应立即关注
agentId 字符串 跨 Session 追踪同一 Agent 的行为模式
sessionId 字符串 将单次任务的所有日志归组,根因分析的核心维度
tool 字符串 识别高错误率工具,定位配置或权限问题
duration 整数(毫秒) P99 延迟分析,检测工具性能退化
error.code 字符串 错误分类(TIMEOUT/AUTH_FAIL/RATE_LIMIT 等)
error.retryCount 整数 高重试次数说明上游不稳定
tokenUsage.input 整数 Context 增长速度,预判 Compaction 触发点
tokenUsage.output 整数 模型输出量,与质量评估相关

41.4.2 字段组合查询示例

使用 jq 从日志文件中提取有价值的分析维度:

# 按工具统计错误率
cat ~/.openclaw/logs/openclaw.log | \
  jq -r 'select(.event == "tool_call_failed") | .tool' | \
  sort | uniq -c | sort -rn

# 查找最慢的工具调用(超过 10 秒)
cat ~/.openclaw/logs/openclaw.log | \
  jq 'select(.duration > 10000) | {tool, duration, sessionId}' | \
  jq -s 'sort_by(-.duration) | .[0:10]'

# 计算特定 Session 的总 Token 消耗
SESSION_ID="sess_9a1b3c"
cat ~/.openclaw/logs/openclaw.log | \
  jq --arg sid "$SESSION_ID" \
  'select(.sessionId == $sid and .tokenUsage != null) | .tokenUsage.input + .tokenUsage.output' | \
  paste -sd+ | bc

# 找出连续失败的 Session
cat ~/.openclaw/logs/openclaw.log | \
  jq -r 'select(.event == "session_failed") | .sessionId' | \
  awk 'seen[$0]++ {print $0 " appeared " seen[$0] " times"}' | head -10

41.5 10个关键指标及阈值参考

41.5.1 指标定义

指标名称 计算方式 警告阈值 严重阈值 说明
Session 成功率 成功数/总数(24h滑动窗口) < 0.95 < 0.90 核心业务健康度
工具错误率 工具失败数/工具调用总数(1h) > 0.03 > 0.08 工具层稳定性
P99 工具延迟 99% 分位 duration 值 > 5000ms > 15000ms 工具调用性能
Compaction 频率 count/24h 每个 Agent > 10 > 25 Token 预算匹配度
LLM 响应时间 最后一次 modelCallMs > 3000ms > 8000ms API 健康状态
Token 每 Session 平均 tokenUsage.input+output > 40000 > 80000 成本控制
内存使用比例 usedMB/limitMB > 0.75 > 0.90 资源容量规划
Gateway 重启次数 event=gateway_restart(24h) > 1 > 3 稳定性指标
活跃连接数 connections.active > 50 > 100 并发容量
高重试工具调用 retryCount > 2 的比例 > 0.05 > 0.15 上游依赖稳定性

41.5.2 指标的业务解读

Session 成功率是最重要的业务指标。低于 95% 通常意味着某个常用工具存在配置问题,或 LLM 无法正确理解 SKILL.md 中的指令。优先排查最近变更了什么。

Compaction 频率是隐藏的性能信号。每次 Compaction 都会截断上下文,可能导致 Agent 遗忘之前的操作结果,从而产生重复工作或逻辑错误。频率过高说明任务设计时没有充分考虑 Token 预算。

Token 每 Session 平均值与 LLM API 成本直接挂钩。超过 8 万 Token 的 Session 意味着可能存在无效的上下文膨胀,例如将完整的大文件内容注入 Context 而非使用工具按需读取。


41.6 与 Prometheus / Grafana 集成

OpenClaw 的结构化日志是集成现有监控栈的天然接口。推荐使用 prometheus-json-exporter 桥接健康检查端点,并使用 LokiVector 处理结构化日志。

41.6.1 prometheus-json-exporter 配置

安装:

# macOS
brew install prometheus-json-exporter

# 或使用 Docker
docker run -d -p 7979:7979 \
  -v $(pwd)/json_exporter.yml:/etc/json_exporter/config.yml \
  prometheuscommunity/json-exporter \
  --config.file /etc/json_exporter/config.yml

json_exporter.yml 配置(采集 OpenClaw 健康检查端点):

modules:
  openclaw:
    metrics:
      - name: openclaw_session_success_rate
        type: gauge
        help: "Session success rate over last 24 hours"
        path: "{ .sessions.successRate24h }"

      - name: openclaw_session_active
        type: gauge
        help: "Currently active sessions"
        path: "{ .sessions.active }"

      - name: openclaw_tool_error_rate_1h
        type: gauge
        help: "Tool error rate in the last hour"
        path: "{ .tools.errorRate1h }"

      - name: openclaw_memory_used_mb
        type: gauge
        help: "Gateway memory used in MB"
        path: "{ .resources.memoryUsedMB }"

      - name: openclaw_memory_limit_mb
        type: gauge
        help: "Gateway memory limit in MB"
        path: "{ .resources.memoryLimitMB }"

      - name: openclaw_compaction_count_24h
        type: gauge
        help: "Context compaction events in last 24 hours"
        path: "{ .compaction.count24h }"

      - name: openclaw_last_model_call_ms
        type: gauge
        help: "Last LLM API call latency in milliseconds"
        path: "{ .models.lastModelCallMs }"

      - name: openclaw_gateway_uptime_seconds
        type: counter
        help: "Gateway uptime in seconds"
        path: "{ .uptime }"

在 Prometheus scrape_configs 中添加:

scrape_configs:
  - job_name: 'openclaw'
    metrics_path: /probe
    params:
      module: [openclaw]
      target: ['http://127.0.0.1:18789/health']
    static_configs:
      - targets: ['localhost:7979']
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - target_label: __address__
        replacement: 'localhost:7979'

41.6.2 Vector 日志采集配置

使用 Vector 将 OpenClaw 的 JSON 日志采集到 Loki 或 Elasticsearch:

# vector.toml

[sources.openclaw_logs]
type = "file"
include = ["~/.openclaw/logs/openclaw.log"]
read_from = "beginning"

[transforms.parse_openclaw]
type = "remap"
inputs = ["openclaw_logs"]
source = '''
  . = parse_json!(string!(.message))
  .source = "openclaw"
'''

[transforms.filter_errors]
type = "filter"
inputs = ["parse_openclaw"]
condition = '.level == "error" || .level == "warn"'

[sinks.loki]
type = "loki"
inputs = ["parse_openclaw"]
endpoint = "http://localhost:3100"
labels.job = "openclaw"
labels.level = "{{ level }}"
labels.agent_id = "{{ agentId }}"
encoding.codec = "json"

[sinks.error_alerts]
type = "http"
inputs = ["filter_errors"]
uri = "http://alertmanager:9093/api/v1/alerts"
encoding.codec = "json"

41.6.3 Grafana Dashboard 核心面板

推荐的 Dashboard 布局(4行布局):

行1:总览(Session 成功率 / 活跃 Session / 工具错误率 / Gateway 运行时间)
行2:性能(LLM 响应延迟趋势 / P99 工具延迟 / Token 消耗热图)
行3:资源(内存使用率 / Compaction 频率趋势 / 连接数)
行4:错误详情(错误日志流 / 按工具的错误分布 / 高重试调用)

关键 PromQL 查询:

# Session 成功率(低于 0.95 高亮显示)
openclaw_session_success_rate < 0.95

# 内存使用比例
openclaw_memory_used_mb / openclaw_memory_limit_mb

# 工具错误率变化趋势(5分钟平均)
avg_over_time(openclaw_tool_error_rate_1h[5m])

# Gateway 是否在线(1=在线,0=离线)
up{job="openclaw"}

41.7 告警规则设计

41.7.1 Prometheus AlertManager 规则

# openclaw_alerts.yml
groups:
  - name: openclaw_critical
    rules:
      - alert: OpenClawGatewayDown
        expr: up{job="openclaw"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "OpenClaw Gateway 不可达"
          description: "健康检查端点已连续 1 分钟无响应,请立即检查 Gateway 进程状态。"

      - alert: OpenClawSessionSuccessRateLow
        expr: openclaw_session_success_rate < 0.90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Session 成功率严重下降(当前: {{ $value | humanize }})"
          description: "过去 24 小时 Session 成功率低于 90%,可能存在系统性故障。"

      - alert: OpenClawMemoryOverLimit
        expr: (openclaw_memory_used_mb / openclaw_memory_limit_mb) > 0.90
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "Gateway 内存使用超过 90%"
          description: "当前内存使用 {{ $value | humanizePercentage }},OOM 风险极高,建议立即重启或扩容。"

  - name: openclaw_warning
    rules:
      - alert: OpenClawToolErrorRateHigh
        expr: openclaw_tool_error_rate_1h > 0.05
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "工具错误率过高({{ $value | humanizePercentage }})"
          description: "最近 1 小时工具调用错误率超过 5%,请检查相关工具配置和权限。"

      - alert: OpenClawCompactionFrequencyHigh
        expr: openclaw_compaction_count_24h > 20
        for: 0m
        labels:
          severity: warning
        annotations:
          summary: "Context Compaction 频率过高({{ $value }} 次/天)"
          description: "每日 Compaction 超过 20 次可能导致上下文丢失和任务逻辑错误。建议优化 Token 预算配置。"

      - alert: OpenClawLLMLatencyHigh
        expr: openclaw_last_model_call_ms > 5000
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "LLM API 响应延迟过高({{ $value }}ms)"
          description: "最后一次 LLM 调用耗时超过 5 秒,可能是 API 限速或网络问题。"

      - alert: OpenClawSessionSuccessRateDegraded
        expr: openclaw_session_success_rate < 0.95
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Session 成功率下降(当前: {{ $value | humanize }})"
          description: "成功率低于 95%,建议检查最近的失败 Session 日志。"

41.7.2 告警通知渠道配置

# alertmanager.yml
route:
  group_by: ['alertname', 'severity']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'default'
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty-critical'
      repeat_interval: 30m
    - match:
        severity: warning
      receiver: 'slack-warnings'

receivers:
  - name: 'pagerduty-critical'
    pagerduty_configs:
      - routing_key: '${PAGERDUTY_KEY}'
        description: '{{ .CommonAnnotations.summary }}'

  - name: 'slack-warnings'
    slack_configs:
      - api_url: '${SLACK_WEBHOOK_URL}'
        channel: '#openclaw-alerts'
        title: '[{{ .Status | toUpper }}] {{ .CommonAnnotations.summary }}'
        text: '{{ .CommonAnnotations.description }}'

41.8 openclaw doctor 命令

openclaw doctor 是内置的诊断工具,在告警触发或怀疑配置有误时应第一时间运行。

41.8.1 doctor 检查项清单

openclaw gateway doctor

典型输出:

OpenClaw Diagnostic Report — 2026-04-26 09:30:00

[✓] Gateway process running (PID: 12847)
[✓] Gateway port 18789 accessible
[✓] Health check responding (status: healthy)
[✓] Configuration file valid (openclaw.json)
[✓] Model API reachable (claude-opus-4-5, latency: 1843ms)
[✓] Log directory writable (~/.openclaw/logs)
[✗] Disk space low: 2.1 GB available (threshold: 5 GB)
[✓] All registered tools (28) responding to ping
[!] Tool 'web_fetch' error rate 8.2% in last hour (threshold: 5%)
[✓] No active sessions in error state
[✓] Memory usage 20.1% (412/2048 MB)
[✓] Context compaction count: 7/day (threshold: 20)

Summary: 1 error, 1 warning
Action required: Free disk space; investigate web_fetch errors

41.8.2 常用 doctor 子命令

# 仅检查 Gateway 连接
openclaw gateway doctor --check connectivity

# 检查所有工具的配置完整性
openclaw gateway doctor --check tools

# 输出机器可读的 JSON 格式
openclaw gateway doctor --format json

# 详细模式(输出每个检查项的原始数据)
openclaw gateway doctor --verbose

# 检查特定 Agent 的配置
openclaw gateway doctor --agent my-agent-id

41.9 调试技巧

41.9.1 日志级别临时调整

无需重启 Gateway 即可动态调整日志级别:

# 调整到 debug 级别,捕获完整工具调用细节
openclaw config set logging.level debug

# 实时跟踪日志
tail -f ~/.openclaw/logs/openclaw.log | jq '.'

# 过滤特定 Session 的日志
tail -f ~/.openclaw/logs/openclaw.log | \
  jq 'select(.sessionId == "sess_9a1b3c")'

# 只显示错误和警告
tail -f ~/.openclaw/logs/openclaw.log | \
  jq 'select(.level == "error" or .level == "warn")'

# 完成调试后恢复 info 级别
openclaw config set logging.level info

41.9.2 RPC 手动测试

Gateway 暴露 RPC 端点,可用于手动测试工具响应:

# 测试工具列表
curl -X POST http://127.0.0.1:18789/rpc \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/list", "id": 1}'

# 手动调用工具(测试 bash 工具)
curl -X POST http://127.0.0.1:18789/rpc \
  -H "Content-Type: application/json" \
  -d '{
    "method": "tools/call",
    "params": {
      "name": "bash",
      "arguments": {"command": "echo hello"}
    },
    "id": 2
  }'

# 检查当前 Session 状态
curl -s http://127.0.0.1:18789/sessions | jq '.'

41.9.3 sandbox 模式调试

使用 openclaw sandbox explain 在沙盒中分析工具调用路径,不触发真实副作用:

# 在沙盒中运行 Agent 并解释决策
openclaw sandbox explain \
  --agent my-agent-id \
  --message "整理今天的邮件" \
  --show-tool-calls \
  --show-reasoning

41.10 生产问题诊断流程

41.10.1 标准诊断 SOP

当收到告警时,按以下顺序执行诊断:

Step 1:确认 Gateway 在线

curl -sf http://127.0.0.1:18789/health | jq '.status'
# 若无响应:openclaw gateway status
# 若 Gateway 已停止:openclaw gateway dashboard 查看历史

Step 2:运行 doctor

openclaw gateway doctor --format json > /tmp/doctor_$(date +%s).json
cat /tmp/doctor_*.json | jq '.issues'

Step 3:查看失败 Session 的日志

# 找出最近失败的 Session ID
cat ~/.openclaw/logs/openclaw.log | \
  jq 'select(.event == "session_failed") | {sessionId, timestamp, error}' | \
  tail -5

# 提取完整 Session 日志
SESSION_ID="sess_xxxx"
cat ~/.openclaw/logs/openclaw.log | \
  jq --arg sid "$SESSION_ID" 'select(.sessionId == $sid)'

Step 4:定位根因工具

# 找出错误最多的工具
cat ~/.openclaw/logs/openclaw.log | \
  jq 'select(.event == "tool_call_failed") | .tool' | \
  sort | uniq -c | sort -rn | head -5

Step 5:验证修复

# 手动测试问题工具
openclaw sandbox explain --message "测试 <工具名> 是否正常" --show-tool-calls

# 重新运行 doctor 确认问题解决
openclaw gateway doctor

41.10.2 常见问题速查

症状 最可能原因 快速验证命令
Gateway 无法启动 端口冲突或配置文件错误 openclaw gateway doctor --check config
Session 全部超时 LLM API Key 失效或网络问题 openclaw models list
工具调用权限错误 SKILL.md 权限声明不完整 openclaw security audit
内存持续增长 大文件内容被注入 Context 检查 tokenUsage 趋势
Compaction 频繁 Token 预算设置过低 调整 maxTokenBudget 参数

下一章将通过 10 个真实案例,展示如何在不同业务场景下部署和使用 OpenClaw。

本章评分
4.9  / 5  (3 评分)

💬 留言讨论