Skip to main content

Dashboard

The coordinator ships with an embedded monitoring dashboard — a single-page application served from the same HTTP server as /metrics and /statusz. No CDN, no external dependencies, no build step: the HTML, JavaScript (Alpine.js + Chart.js), and CSS are compiled into the Go binary via //go:embed. It works on-prem, in air-gapped networks, and behind VPNs.

Enabling the dashboard

Pass --metrics-addr to the coordinator (or the collapsed urutau run CLI). The dashboard is served on the same address:

# Single-process mode
urutau run -f pipeline.yaml --metrics-addr :9090

# Distributed mode (coordinator)
urutau-coordinator run -f pipeline.yaml --metrics-addr :9090

On Kubernetes, set spec.coordinator.metricsAddr in the CDCPipeline CR:

CDCPipeline CR with metrics
apiVersion: urutau.maltzsama.github.io/v1alpha1
kind: CDCPipeline
spec:
coordinator:
metricsAddr: ":9090"

Open http://localhost:9090 in a browser. The dashboard is the root page; /metrics (Prometheus) and /statusz (JSON) remain available at their usual paths.

Views

Overview

The landing page shows the pipeline at a glance:

  • Pipeline name and run ID
  • Status indicator: healthy / degraded / failed
  • Source kind and sink type
  • Workers: online count, snapshot progress
  • Uptime since start
  • Maintenance enabled/disabled

Streams (Tables)

One card per source → target stream. Each card shows:

FieldMeaning
Source / Targetschema.tablenamespace.table
Write modeupsert, append, or append-idempotent
PositionCurrent CDC position (with copy button)
LagTime since last commit
RowsTotal written + rate (rows/s)
CommitsTotal + failures
Commit latencyAverage ms per commit
Equality deletesCount (upsert mode)
Snapshot progress0..1 during initial backfill

Clicking a stream card opens a drawer with throughput and commit latency charts (1-hour client-side buffer, window selector for 5m/15m/1h/6h).

Workers

One card per connected worker:

FieldMeaning
Worker name<pipeline>-<target>-<index>
Statusstarting, snapshotting, streaming
EpochReset count (bumped on supervisor reset)
Assigned tablesTables this worker owns
Last ackSeconds since last acknowledgement
Inflight bytesUnacked batch bytes
Committed positionsPer-table last committed position

Events

A scrollable, color-coded log of operational events:

  • Commit failure — catalog rejected a commit
  • Worker reset — supervisor restarted a stale worker
  • Schema change — DDL detected in source
  • Maintenance — compaction/expiry/orphan pass completed
  • Pipeline — start, stop, snapshot transitions

Filter by event type and worker. Events are kept in a 1000-entry ring buffer in memory.

Logs

The coordinator's structured log tail, with level filter (debug / info / warn / error). Useful for debugging without SSH-ing into the pod.

Actions

The dashboard exposes two actions, both requiring a confirmation dialog:

ActionWhat it does
Cancel pipelineSends Shutdown to all workers; terminates the pipeline gracefully
Restart workerBumps the worker's epoch, cancels its session, and triggers a supervisor reset

Actions are logged as events and visible in the Events view.

Real-time updates

The dashboard uses Server-Sent Events (SSE) for live updates. On connect, the server pushes a full snapshot (pipeline, tables, workers, events, logs). After that, only deltas are pushed — no polling, no WebSocket complexity. The browser's EventSource handles reconnection automatically.

The SSE endpoint is GET /api/v1/stream. A periodic comment (: ping) keeps idle proxies from timing out the connection.

API endpoints

The dashboard's JSON API is also available for programmatic access. See Dashboard API for the full reference.

EndpointMethodDescription
/api/v1/pipelineGETPipeline summary
/api/v1/tablesGETAll streams
/api/v1/tables/{name}GETOne stream (by source or target name)
/api/v1/workersGETAll workers
/api/v1/workers/{name}GETOne worker
/api/v1/eventsGETEvent log (filter: type, worker, limit)
/api/v1/logsGETCoordinator log tail (filter: level, limit)
/api/v1/streamGETSSE stream
/api/v1/actions/cancelPOSTCancel pipeline
/api/v1/actions/restart/{worker}POSTRestart worker
/healthzGETLiveness probe
/readyzGETReadiness probe

Security

The dashboard assumes a trusted network (same trust model as the gRPC control plane). There is no authentication in v0.2.0 — the endpoint is intended for internal monitoring, not public exposure.

For untrusted networks, put the dashboard behind a reverse proxy with authentication, or restrict access via network policies.

Architecture

The dashboard is a separate package (internal/dashboard) that reads coordinator state through the State interface — the same dependency direction the rest of the orchestration keeps. The coordinator implements State; the dashboard never imports the coordinator.

Dashboard architecture
coordinator.go
└── dashboard.Handler
├── /api/v1/* (JSON API)
├── /api/v1/stream (SSE)
├── /healthz, /readyz (probes)
└── /* (embedded SPA)

The SPA assets (index.html, app.js, style.css, plus vendored Alpine.js/Chart.js/Pico.css) are embedded at compile time via //go:embed static/*. No runtime filesystem access.