Skip to content

feat(observability): ship OTel Collector config, Grafana dashboard pack and demo - #473

Merged
jamby77 merged 11 commits into
masterfrom
feat/otel-collector-dashboard-pack
Sep 23, 2026
Merged

jamby77 merged 11 commits into
masterfrom
feat/otel-collector-dashboard-pack

Conversation

@jamby77

@jamby77 jamby77 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Ships the observability pack from the planning board item "[P0] Ship OTel
Collector config, Grafana dashboard pack, and side-by-side demo". Branches off
master and touches nothing the open Prometheus stack (#462/#467/#470) touches.

What's here

  • Collector configdeploy/observability/collector/otel-collector.yaml
    scrapes Monitor's /api/prometheus/metrics and re-exports on :8889;
    otel-collector.fanout.yaml is the same pipeline plus a secondary OTLP
    endpoint for users who already ship elsewhere.
  • Dashboard pack — four Grafana dashboards under
    deploy/observability/dashboards/: instance vitals, query patterns, cluster
    slots, anomalies. Each takes a Data source variable, so they import into any
    Grafana without editing JSON, plus Scrape job and Connection variables.
  • Side-by-side demodeploy/observability/demo/ brings up Valkey, Monitor,
    the collector, Prometheus and Grafana with everything provisioned; Prometheus
    scrapes both the direct path and the OTLP path so you can compare them by
    flipping one variable.
  • Docsdeploy/observability/README.md, a new docs/pmm-integration.md,
    and updates to docs/prometheus-integration.md and docs/opentelemetry.md.
  • Testsapps/api/src/prometheus/observability-assets.spec.ts (59) checks
    the assets against the live metric registry: no dashboard can reference a metric
    that is not registered, every target filters by job and connection, every table
    panel queries in table format, every dashboard is provisioned, and the collector
    configs use every component they define.

Verified

The stack was brought up end to end: five containers healthy, both Prometheus
targets up, seeded traffic visible, all four dashboards rendering.

Known gaps

  • The demo runs a standalone Valkey, so the Cluster Slots dashboard stays empty
    there and the anomaly detectors need a longer run to warm up. The README says so.
  • deploy/ is a new top-level directory; the repo keeps compose files at the root
    and charts in charts/. Happy to move it if you'd rather it lived elsewhere.
  • The root prometheus.yml still scrapes host.docker.internal:3001 with no
    metrics_path, which is the wrong endpoint. Pre-existing; left alone here.
  • betterdb_correlated_groups_by_severity is registered but never written by the
    service. The panel that read it is gone; the gauge itself is tracked separately.

🤖 Generated with Claude Code


Note

Low Risk
Mostly additive deploy assets, documentation, and contract tests; runtime API behavior is unchanged aside from a new dev dependency.

Overview
Adds a deploy/observability/ pack: OTLP intake Collector configs (base + optional fanout to SECONDARY_OTLP_ENDPOINT), four importable Grafana dashboards (vitals, query patterns, cluster slots, anomalies) with shared ds / job / connection variables, and a demo-only Docker Compose stack (Valkey, Monitor, Collector, Prometheus, Grafana) plus seed traffic and provisioning.

observability-assets.spec.ts locks the pack to runtime reality by parsing shipped YAML/JSON and asserting Collector pipeline wiring, demo compose mounts/scrape jobs, and that every dashboard PromQL target uses registered betterdb_* metrics and consistent job/connection filters. Adds yaml as an API dev dependency for those tests.

Docs gain the observability README, PMM integration guidance, Grafana pack sections in Prometheus integration, and Collector/dashboard notes in OpenTelemetry (plus table formatting touch-ups).

Reviewed by Cursor Bugbot for commit 72228c0. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added an observability pack with OpenTelemetry Collector configurations, Prometheus integration, and four Grafana dashboards for instance health, query patterns, cluster slots, and anomalies.
    • Added a Docker Compose demo environment with Valkey, BetterDB Monitor, OpenTelemetry Collector, Prometheus, and Grafana.
    • Added a traffic-seeding script to populate demo metrics.
  • Documentation

    • Expanded OpenTelemetry, Prometheus, PMM integration, dashboard, and demo setup guidance.

- Ship a base config and a two-backend fan-out config
- Validate receiver protocols and pipeline wiring in CI
- Ship two importable Grafana dashboards with a connection variable
- Gate every panel query on a metric the service registers
- Chart slot key distribution, hot slots and slot IO rates
- Chart anomaly counts, correlated groups, baselines and forecasts
- Compose Valkey, the monitor, the collector, Prometheus and Grafana
- Provision the dashboard pack and a seed script that populates it
- Describe importing the pack into an existing Grafana
- Add a PMM joint-docs skeleton for query analytics
- Make the datasource a `ds` template variable instead of a fixed uid,
  so the pack imports into any Grafana
- Add a `job` variable and pin every selector to it, so the demo's two
  scrape paths no longer double-count
- Give the five table panels `format: table` and a field-organizing
  transformation so they render rows
- Read correlated groups and active anomalies through `sum by
  (connection)` over the gauge families
- Drop the scrape config's reference to a non-existent metrics token
- Mark the demo compose file as demo-only
- Correct the `resource_to_telemetry_conversion` claim and say which
  dashboards the demo populates
- Extend the asset spec with datasource, job, selector and table-format
  assertions
- Point the "Correlated groups" stat at
  `betterdb_correlated_groups_by_pattern`; the by-severity gauge is
  registered but never written, so it always reads empty
- Describe the demo's anomaly dashboard as it actually behaves
- Remove "Correlated groups by severity"; no gauge the service writes
  carries a correlated-group severity breakdown, and widen "Correlated
  groups by pattern" to fill the row
- Exclude `exported_job` and `service_name` in the table panels'
  organize transformations, so tables stay clean on the collector job
- fail rather than pass vacuously when a dashboard has no table panel
- the datasource test now describes what it checks after the ds variable
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

Warning

Review limit reached

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 09d3a032-d733-420d-8695-fa85b1620f71

📥 Commits

Reviewing files that changed from the base of the PR and between 96ef3d3 and 72228c0.

📒 Files selected for processing (3)
  • apps/api/src/prometheus/observability-assets.spec.ts
  • deploy/observability/README.md
  • deploy/observability/dashboards/betterdb-cluster-slots.json

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 8f3ae09b-42f8-4240-84a9-88967766a5a4

📥 Commits

Reviewing files that changed from the base of the PR and between 074c0d3 and 96ef3d3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • apps/api/package.json
  • apps/api/src/prometheus/observability-assets.spec.ts
  • deploy/observability/README.md
  • deploy/observability/collector/otel-collector.fanout.yaml
  • deploy/observability/collector/otel-collector.yaml
  • deploy/observability/dashboards/betterdb-anomalies.json
  • deploy/observability/dashboards/betterdb-cluster-slots.json
  • deploy/observability/dashboards/betterdb-instance-vitals.json
  • deploy/observability/dashboards/betterdb-query-patterns.json
  • deploy/observability/demo/docker-compose.yml
  • deploy/observability/demo/grafana/provisioning/dashboards/betterdb.yaml
  • deploy/observability/demo/grafana/provisioning/datasources/prometheus.yaml
  • deploy/observability/demo/prometheus.yml
  • deploy/observability/demo/seed/seed.sh
  • docs/opentelemetry.md
  • docs/pmm-integration.md
  • docs/prometheus-integration.md

Included review availability: Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

The pull request adds OpenTelemetry Collector configurations, four Grafana dashboards, a Docker Compose observability demo, asset contract tests, and integration documentation.

Changes

BetterDB observability pack

Layer / File(s) Summary
Collector configurations
deploy/observability/collector/*
Adds base and fan-out Collector configurations with OTLP receivers, memory and batch processors, Prometheus export, debug output, and optional secondary OTLP forwarding.
Grafana dashboard pack
deploy/observability/dashboards/*
Adds dashboards for instance vitals, query patterns, cluster slots, and anomalies. Each dashboard uses Prometheus variables and BetterDB metric queries.
Demo stack wiring
deploy/observability/demo/*
Adds Valkey, BetterDB Monitor, Collector, Prometheus, and Grafana services with provisioning, scrape configuration, and demo traffic generation.
Observability asset contract tests
apps/api/package.json, apps/api/src/prometheus/observability-assets.spec.ts
Adds the YAML dependency and tests for Collector configuration, registered metrics, dashboard contracts, Compose services, datasource provisioning, and scrape targets.
Integration documentation
deploy/observability/README.md, docs/opentelemetry.md, docs/pmm-integration.md, docs/prometheus-integration.md
Documents the observability pack, Collector usage, dashboard imports, PMM integration, demo limitations, and Prometheus integration.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Valkey
  participant BetterDBMonitor
  participant OTELCollector
  participant Prometheus
  participant Grafana
  Valkey->>BetterDBMonitor: Provide Valkey metrics and command activity
  BetterDBMonitor->>OTELCollector: Export OTLP metrics
  BetterDBMonitor->>Prometheus: Expose direct Prometheus metrics
  OTELCollector->>Prometheus: Expose OTLP-converted metrics
  Grafana->>Prometheus: Query BetterDB dashboards
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. (15 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding the OTel Collector configuration, Grafana dashboards, and demo.
Description check ✅ Passed The description provides a detailed summary of the observability pack, its components, tests, verification results, and known gaps. It does not include the template's explicit checklist section, but t…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. (15 skipped: 15 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

- the pinned 2.6.1 conflicted with the root yaml@2 override, so CI's
  frozen-lockfile install rejected the tree
- slot read rate, write rate and volatile keys read fields that
  CLUSTER SLOT-STATS never emits, so all three rendered flat zeros
- the table-frame rule now bites at pack level, since the cluster
  dashboard no longer carries a table panel

@KIvanow KIvanow left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clean, well-scoped pack - thanks for branching it off master so it doesn't tangle with the Prometheus stack. Approving.

What I like: the demo compose leads with an unmissable "DEMO ONLY" banner that names every insecure choice, so nobody copies it into prod by accident. And observability-assets.spec.ts is the right call - pinning the dashboards and collector/demo wiring to the live registry is what stops this pack from silently rotting the next time a metric is renamed.

On your open questions: deploy/ as a new top-level dir is fine by me - it's a conventional home for this and keeps it out of the app tree. Keep it.

Minor, none blocking:

  • The demo pins every image except betterdb/monitor:latest. Consider pinning it to a released tag so the demo is reproducible as the image moves.
  • You flagged the root prometheus.yml scraping the wrong endpoint (host.docker.internal:3001, no metrics_path). Since this PR is squarely about getting the scrape config right, folding a one-line fix in here would be a natural fit - but I'm happy to take it as a follow-up if you'd rather keep this pack pure additions.
  • betterdb_correlated_groups_by_severity registered-but-never-written: fine as tracked separately since the panel's gone.

None of that holds the merge.

@jamby77
jamby77 merged commit 2fb7b09 into master Sep 23, 2026
21 checks passed
@jamby77
jamby77 deleted the feat/otel-collector-dashboard-pack branch September 23, 2026 14:13
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants