Skip to content

hidearmoon/clawpulse

Repository files navigation

ClawPulse

English | 中文

Real-time monitoring and observability dashboard for OpenClaw instances.

ClawPulse collects key metrics from one or more OpenClaw gateways — request latency, throughput, error rate, token usage, and channel health — stores them in a local SQLite database, surfaces them through a dark-theme web dashboard, and fires webhook alerts when thresholds are breached.

Python License: MIT CI

ClawPulse Dashboard

Screenshot placeholder – replace with an actual screenshot after first run


Features

  • Real-time metrics – polling every 30 s (configurable); latency, RPM, TPM, error rate, channel status
  • Multi-instance – monitor any number of OpenClaw deployments from one dashboard
  • Historical trends – 15 m / 1 h / 6 h / 24 h / 7 d time-range charts with bucketed averages
  • Alert engine – rule-based alerts with configurable thresholds, duration (sustained breach), and severity (warning / critical)
  • Webhook notifications – POST JSON to Slack, Discord, PagerDuty, Feishu, DingTalk, or any custom endpoint; fires on alert and on resolution
  • Zero external dependencies – SQLite only; no Redis, no Postgres
  • Docker-first – single docker compose up to get started

Quick Start (30 seconds)

Docker Compose (recommended)

# 1. Clone and enter the repo
git clone https://github.com/hidearmoon/clawpulse.git
cd clawpulse

# 2. Start ClawPulse
docker compose up -d

# 3. Open the dashboard
open http://localhost:8765

Add your first OpenClaw instance via the "Add Instance" panel in the dashboard, or set it in config.yaml before starting.

Local Python

# Requires Python 3.10+
pip install -e .

# Optional: copy and edit the config
cp config.example.yaml config.yaml

clawpulse --port 8765

Configuration

Environment Variables

All settings can be overridden via environment variables prefixed with CLAWPULSE_.

Variable Default Description
CLAWPULSE_HOST 0.0.0.0 Bind host
CLAWPULSE_PORT 8765 Bind port
CLAWPULSE_DEBUG false Enable debug logging
CLAWPULSE_DB_PATH clawpulse.db SQLite file path
CLAWPULSE_DATA_RETENTION_DAYS 7 Days to keep metric history
CLAWPULSE_COLLECT_INTERVAL_SECONDS 30 Collection interval (min 5)
CLAWPULSE_COLLECT_TIMEOUT_SECONDS 10 Per-request HTTP timeout
CLAWPULSE_WEBHOOK_URL (empty) Global default webhook URL
CLAWPULSE_WEBHOOK_HEADERS {} Global webhook headers (JSON)
CLAWPULSE_KEY_<INSTANCE_ID_UPPER> (empty) API key for a persisted instance

API key env var example: for an instance with id prod, set CLAWPULSE_KEY_PROD=sk-xxx.

config.yaml

server:
  port: 8765

database:
  retention_days: 30

collector:
  interval_seconds: 15

alerting:
  webhook_url: "https://hooks.slack.com/services/xxx/yyy/zzz"

instances:
  - id: "prod"
    name: "Production"
    base_url: "http://openclaw.example.com:3000"
    api_key: ""    # prefer CLAWPULSE_KEY_PROD env var

See config.example.yaml for the full annotated reference.


API Reference

All responses use the envelope: {"success": bool, "data": ..., "message": str|null}

Instances

Method Path Description
GET /api/instances List monitored instances
POST /api/instances Add an instance
DELETE /api/instances/{id} Remove an instance

Add instance body:

{
  "name": "Production",
  "base_url": "http://openclaw.example.com:3000",
  "api_key": "sk-xxxxxxxxxxxxxxxxx"
}

Metrics

Method Path Description
GET /api/metrics/realtime Latest value for every metric
GET /api/metrics/history Time-bucketed history (?metric=response_latency_ms&range=1h)
GET /api/metrics/summary Aggregate stats (?range=24h)

Alerts

Method Path Description
GET /api/alerts/rules List all alert rules
POST /api/alerts/rules Create an alert rule
DELETE /api/alerts/rules/{id} Delete an alert rule
GET /api/alerts/states Current state per rule/instance
GET /api/alerts/history Alert firing/resolved history

Create alert rule body:

{
  "name": "High latency",
  "metric_name": "response_latency_ms",
  "operator": ">",
  "threshold": 2000,
  "duration_seconds": 60,
  "severity": "warning",
  "instance_id": null,
  "webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz",
  "webhook_headers": {}
}

Other

Method Path Description
GET /api/health Liveness probe
GET /docs Interactive Swagger UI

Alert Configuration Examples

High-latency alert (Slack)

curl -X POST http://localhost:8765/api/alerts/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "High latency",
    "metric_name": "response_latency_ms",
    "operator": ">",
    "threshold": 2000,
    "duration_seconds": 60,
    "severity": "warning",
    "webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz"
  }'

Error-rate alert (critical, immediate)

curl -X POST http://localhost:8765/api/alerts/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Error rate spike",
    "metric_name": "error_rate",
    "operator": ">",
    "threshold": 0.1,
    "duration_seconds": 0,
    "severity": "critical"
  }'

Webhook payload example

{
  "event": "alert.firing",
  "alert": {
    "id": 1,
    "name": "High latency",
    "severity": "warning",
    "state": "firing",
    "metric_name": "response_latency_ms",
    "operator": ">",
    "threshold": 2000.0,
    "current_value": 3241.5
  },
  "instance": { "id": "prod" },
  "fired_at": "2025-01-15T10:23:45Z",
  "timestamp": "2025-01-15T10:23:45Z"
}

The same structure is sent for alert.resolved, with resolved_at instead of fired_at.


Alert State Machine

normal ──(condition met, duration=0)──► firing
normal ──(condition met, duration>0)──► pending ──(duration elapsed)──► firing
firing ──(condition cleared)──────────► resolved
resolved ──(condition met again)──────► firing

Development Guide

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# Run tests (excluding integration)
pytest tests/ --ignore=tests/integration -v

# Run with auto-reload
clawpulse --debug

# Lint
pip install ruff
ruff check clawpulse/

Project Structure

clawpulse/
  __init__.py        # Package version
  main.py            # FastAPI app factory + CLI entry point
  api.py             # REST API routes
  collector.py       # Metrics collection scheduler
  storage.py         # SQLite layer (metrics + alert tables)
  alerting.py        # Alert engine + state machine
  notifier.py        # Webhook notification delivery
  config.py          # Configuration (env vars + YAML)
static/              # Frontend (dark-theme Chart.js dashboard)
tests/               # pytest suite (42+ tests)
Dockerfile
docker-compose.yml
config.example.yaml

Metrics Reference

Metric Source Description
request_total /api/status Cumulative request count
rpm /api/status Requests per minute
tpm /api/status Tokens per minute
uptime_seconds /api/status Instance uptime
today_request_count /api/dashboard/ Today's request count
token_total /api/dashboard/ Today's total tokens
response_latency_ms /api/channel/ + /api/log/ Average response latency (ms)
error_rate /api/log/ Error ratio (0–1)
channels_enabled /api/channel/ Number of enabled channels
channels_disabled /api/channel/ Number of disabled channels
channel_status /api/channel/ Per-channel status (labelled)
channel_response_time_ms /api/channel/ Per-channel response time
channel_balance /api/channel/ Per-channel balance

License

MIT © OpenClaw Labs – see LICENSE



中文

English | 中文

ClawPulse 是 OpenClaw 的实时监控与可观测性仪表盘。

它从一个或多个 OpenClaw 网关采集关键指标(请求延迟、吞吐量、错误率、Token 用量、渠道健康状态),存入本地 SQLite 数据库,通过深色主题的 Web 仪表盘展示,并在指标超出阈值时触发 Webhook 告警。


功能特性

  • 实时指标 – 默认每 30 秒轮询一次(可配置),覆盖延迟、RPM、TPM、错误率、渠道状态
  • 多实例 – 在一个仪表盘中监控任意数量的 OpenClaw 部署
  • 历史趋势 – 支持 15 分钟 / 1 小时 / 6 小时 / 24 小时 / 7 天时间范围的分桶平均折线图
  • 告警引擎 – 基于规则的告警,支持阈值配置、duration(持续触发时长)和告警级别(warning / critical
  • Webhook 通知 – 向 Slack、Discord、PagerDuty、飞书、钉钉或任意自定义端点 POST JSON;告警触发和恢复时均发送通知
  • 零外部依赖 – 仅使用 SQLite,无需 Redis、PostgreSQL
  • Docker 优先 – 一条 docker compose up 即可启动

快速开始(30 秒)

Docker Compose(推荐)

# 1. 克隆项目
git clone https://github.com/hidearmoon/clawpulse.git
cd clawpulse

# 2. 启动 ClawPulse
docker compose up -d

# 3. 打开仪表盘
open http://localhost:8765

在仪表盘的"添加实例"面板中添加你的 OpenClaw 实例,或在启动前编辑 config.yaml

本地 Python

# 需要 Python 3.10+
pip install -e .

# 可选:复制并编辑配置
cp config.example.yaml config.yaml

clawpulse --port 8765

配置说明

环境变量

所有设置均可通过 CLAWPULSE_ 前缀的环境变量覆盖。

变量 默认值 说明
CLAWPULSE_HOST 0.0.0.0 监听地址
CLAWPULSE_PORT 8765 监听端口
CLAWPULSE_DEBUG false 开启调试日志
CLAWPULSE_DB_PATH clawpulse.db SQLite 文件路径
CLAWPULSE_DATA_RETENTION_DAYS 7 指标历史保留天数
CLAWPULSE_COLLECT_INTERVAL_SECONDS 30 采集间隔(最小 5 秒)
CLAWPULSE_COLLECT_TIMEOUT_SECONDS 10 单次 HTTP 请求超时
CLAWPULSE_WEBHOOK_URL (空) 全局默认 Webhook 地址
CLAWPULSE_WEBHOOK_HEADERS {} 全局 Webhook 请求头(JSON)
CLAWPULSE_KEY_<实例ID大写> (空) 已持久化实例的 API Key

API Key 环境变量示例: 对于 id 为 prod 的实例,设置 CLAWPULSE_KEY_PROD=sk-xxx


API 文档

所有响应格式:{"success": bool, "data": ..., "message": str|null}

方法 路径 说明
GET /api/instances 列出所有实例
POST /api/instances 添加实例
DELETE /api/instances/{id} 删除实例
GET /api/metrics/realtime 所有指标最新值
GET /api/metrics/history 分桶历史数据
GET /api/metrics/summary 聚合统计
GET /api/alerts/rules 告警规则列表
POST /api/alerts/rules 创建告警规则
DELETE /api/alerts/rules/{id} 删除告警规则
GET /api/alerts/states 当前告警状态
GET /api/alerts/history 告警历史记录
GET /api/health 健康检查
GET /docs Swagger 交互文档

告警配置示例

高延迟告警(推送到 Slack)

curl -X POST http://localhost:8765/api/alerts/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "高延迟告警",
    "metric_name": "response_latency_ms",
    "operator": ">",
    "threshold": 2000,
    "duration_seconds": 60,
    "severity": "warning",
    "webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz"
  }'

告警状态机

normal ──(条件满足, duration=0)──► firing
normal ──(条件满足, duration>0)──► pending ──(持续达到 duration)──► firing
firing ──(条件消失)──────────────► resolved
resolved ──(条件再次满足)──────────► firing

开发指南

# 安装开发依赖
pip install -e ".[dev]"

# 运行单元测试(跳过集成测试)
pytest tests/ --ignore=tests/integration -v

# 开发模式(热重载)
clawpulse --debug

# 代码检查
pip install ruff
ruff check clawpulse/

License

MIT © OpenClaw Labs – 见 LICENSE

About

Real-time monitoring & observability dashboard for OpenClaw instances

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors