Seed scripts and local development tools for the Forge observability stack.
Three seeders populate the observability stack with realistic synthetic data. Langfuse seeder must be run first — every other seeder reads the output of the langfuse seeder.
devtools/langfuse/seed.py → devtools/seed_output.json
devtools/redis/seed.py → forge:alerts:* Hashes and forge:stats:alerts:* in Redis
devtools/prometheus/seed.py → forge_* metrics in Prometheus
uv run python -m devtools.langfuse.seedSeeds 150 tickets (50 features, 100 bugs) as Langfuse traces spanning 730 days.
Writes devtools/seed_output.json — consumed by the Redis and Prometheus seeders.
Requires: Langfuse running (LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY in .env).
uv run python -m devtools.redis.seedReads devtools/seed_output.json, identifies outlier issues, and writes all alert data
directly as Redis-native structures (no JSON strings):
forge:alerts:{issue_id}:{alert_type}— Hash per individual alertforge:stats:alerts:summary— Hash with total, critical, warning, cost_outlier, latency_outlier countsforge:stats:alerts:by_type— Hash with per-alert-type countsforge:stats:alerts:ts:cost_outlier/forge:stats:alerts:ts:latency_outlier— TimeSeriesforge:alerts:idx— RediSearch index over alert Hashes (enablesFT.SEARCHtable queries in Grafana)forge:alerts:stream— Redis Stream with all alert entries
Requires:
- Forge Redis running (
REDIS_PORT=6380in.envis the default). - Redis Stack server (
redis/redis-stack-server) — needed for the TimeSeries module and Redis Streams. devtools/seed_output.jsonto exist (run the Langfuse seeder first).
uv run python -m devtools.prometheus.seedReads devtools/seed_output.json for ticket volumes, then writes 1 day of backdated
Forge metric time-series to Prometheus via the remote write API (protobuf + snappy),
at a 15-second scrape interval (~5,760 samples per metric).
Requires:
-
python-snappyinstalled —uv add python-snappy -
Forge Prometheus running (
PROMETHEUS_PORT=9092in.envis the default) -
Two startup flags must be added to the
prometheusservice inforge/docker-compose.yml:command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=15d' - '--web.enable-lifecycle' - '--web.enable-remote-write-receiver' # required: enables /api/v1/write - '--web.enable-admin-api' # required: enables delete_series for cleanup
Without
--web.enable-remote-write-receiverthe seeder fails with HTTP 404. Without--web.enable-admin-apithe cleanup step is skipped and old data accumulates on re-runs.Restart after changes:
podman compose -f forge/docker-compose.yml up -d prometheus -
Out-of-order ingestion must be enabled in prometheus.yml (in the forge repo):
storage: tsdb: out_of_order_time_window: 15d
-
devtools/seed_output.jsonto exist (run the Langfuse seeder first).
| Variable | Used by |
|---|---|
CLICKHOUSE_HOST |
Grafana ClickHouse datasource |
CLICKHOUSE_PORT |
Grafana ClickHouse datasource |
CLICKHOUSE_HTTP_PORT |
Grafana ClickHouse datasource |
CLICKHOUSE_DATABASE |
Grafana ClickHouse datasource |
CLICKHOUSE_USER |
Grafana ClickHouse datasource |
CLICKHOUSE_PASSWORD |
Grafana ClickHouse datasource |
REDIS_HOST |
Redis seeders + Grafana Redis datasource |
REDIS_PORT |
Redis seeders + Grafana Redis datasource |
PROMETHEUS_HOST |
Prometheus seeder + Grafana Prometheus datasource |
PROMETHEUS_PORT |
Prometheus seeder + Grafana Prometheus datasource |
See .env.example for the full list.
See grafana/README.md for starting the local Grafana instance
and configuring the MCP server for Claude Code dashboard development.