Observability v2 — ClickHouse only¶
One store, one agent, a straight line. Customer logs and metrics both live in the per-region ClickHouse droplet — no VictoriaMetrics, no vmagent, no Vector.
The pipeline has three stops: Collect — one OpenTelemetry Collector grabs app logs,
Envoy request logs and cAdvisor meters and tags each row with its tenant; Store — a
few ClickHouse tables hold it, with retention set from the customer's plan; Read & query —
Starbase queries behind a forced tenant filter and Stardeck renders. The 7 metrics are SQL over the
rows (four from the request log, three from the scraped meters); logs are a tail. Identity on request
rows rides the HTTPRoute name (read from route metadata and split once — not v1's per-scrape
envoy_cluster_name regex).
VPC topology¶
Diagram — v2 VPC topology. The regional VPC (one per region) holds the customer cluster and its single ClickHouse telemetry droplet, so ingest is intra-VPC at $0. One OTel Collector agent per cluster ships app logs, Envoy access logs and cAdvisor metrics to the regional OTel Collector gateway, which batches into ClickHouse — no VictoriaMetrics, no Vector, no vmauth. The central control plane (its own VPC) peers in to read, only through one authed front-door: a read-only ClickHouse user (native RBAC, not a service). Starbase injects the tenant filter (FR-065); the store stays private. Grafana Alloy ships platform series to Grafana Cloud (external) — unchanged. Blue = telemetry / reads · amber = platform · dashed = external.
What's covered, and where¶
Every requirement, its v2 home, and its status:
| Area | Requirement | v2 home | Status |
|---|---|---|---|
| Metrics — latency, RPS, error rate, throughput (L7) | FR-063 | Read & query (from otel_http) |
MVP |
| Metrics — CPU, memory, network | FR-050 | Read & query (scraped otel_metrics_*) |
MVP |
| Logs — app runtime, live tail (build logs → §16.6, outside ClickHouse) | FR-049 | Read & query (otel_logs) |
MVP |
| Attribution — tenant identity on every row | FR-064 | Collect (labels / route metadata) | MVP |
| Isolation — server-side tenant filter | FR-065 | Read & query | MVP |
| Retention — per plan (7/30/90 d) | FR-051 | Store (dictionary + TTL) | MVP · fixed |
| Transport — private VPC, cross-region reads | FR-071 | this page + Read & query | MVP (x-region dormant) |
| Preview-env metrics — no per-route cardinality blowup | FR-067 | rows in otel_http, no active-series limit |
MVP |
| Platform self-monitoring | FR-069 | §35.5 (shared section, unchanged) | MVP |
| Rollup materialized views | — | Store (deferred; raw-first) | post-MVP |
| Distributed tracing | — | — (OTel-native when needed) | future |
What changed from v1¶
| v1 (superseded) | v2 | |
|---|---|---|
| Stores (per region) | VictoriaMetrics + ClickHouse | ClickHouse only |
| Metrics agent | vmagent | OTel Collector |
| Logs agent | Fluent Bit → Vector | OTel Collector |
| L7 identity | envoy_cluster_name regex, per scrape (EG-version-coupled) |
HTTPRoute name from route metadata, split once |
| Per-plan retention | ✗ — metrics global 90 d (FR-051 gap) | ✓ — project → days dictionary + TTL (logs and metrics) |
| Read front-doors | vmauth + ClickHouse user | ClickHouse user |
| Query languages | PromQL + SQL | SQL |
Build order¶
The throughline is get → store → read: collect the signals, land them in ClickHouse, read them out behind the tenant filter. Each page walks its stop end-to-end with the configs to copy.
- Collect — the one agent — one collector, three inputs, identity stamped, batched into ClickHouse.
- Store & retention — the ClickHouse tables, tenant keys, plan-based retention.
- Read & query — the tenant filter, the 7 metrics as SQL, and log tail.
- Bootstrap — the ordered bring-up that ties it together.