Skip to content

HYPERFLEET-1361 - feat: Add Grafana dashboard for API and DB metrics - #311

Open
tirthct wants to merge 3 commits into
openshift-hyperfleet:mainfrom
tirthct:hyperfleet-1361
Open

HYPERFLEET-1361 - feat: Add Grafana dashboard for API and DB metrics#311
tirthct wants to merge 3 commits into
openshift-hyperfleet:mainfrom
tirthct:hyperfleet-1361

Conversation

@tirthct

@tirthct tirthct commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a pre-built Grafana dashboard (charts/dashboards/hyperfleet-api.json) covering all 11 hyperfleet_api_* and hyperfleet_db_* Prometheus metrics across 12 panels
  • Update docs/metrics.md to replace the stub dashboard section with actual import instructions, coverage inventory, and behavioral notes
  • Bump Helm chart version 1.1.0 → 1.2.0 for the new dashboard artifact

Dashboard panels

# Panel Metric(s) Key PromQL
1 HTTP Request Rate requests_total sum by (code) (rate(...))
2 Build Info (API Status) build_info stat panel, value mapping
3 Request Duration request_duration_seconds histogram_quantile P50/P95/P99
4 Server Error Rate requests_total{code=~"5.."} sum by (path) (rate(...))
5 Reconciliation Started reconciliation_started_total sum by (resource_type, is_delete) (rate(...))
6 Pending Reconciliation resource_pending_reconciliation max by (resource_type, is_delete)
7 Stuck Resources resource_pending_reconciliation_stuck max by (resource_type, is_delete)
8 Max Stuck Duration resource_pending_reconciliation_stuck_duration_seconds max by (resource_type, is_delete)
9 DB Query Duration db_query_duration_seconds histogram_quantile P50/P95/P99
10 DB Error Rate db_errors_total sum by (error_type) (rate(...))
11 DB Connection Pool db_connections_open + db_connections_in_use sum(...)
12 Top Paths requests_total topk(10, ...) instant table

Design decisions

  • Parameterized datasource — no hardcoded UIDs; works across environments
  • Multi-replica aware — reconciliation gauges use max by (identical SQL results), connection pool uses sum (per-instance)
  • No stacking on error panels — error types shown as individual trends to avoid masking low-volume types
  • Reconciliation gauge panels show "No data" when no resources match (expected, not a broken datasource)

Test plan

  • Import dashboard into Grafana with a Prometheus datasource configured to scrape hyperfleet-api
  • Verify all 12 panels render data (or "No data" for reconciliation gauges when no resources are pending)
  • Confirm datasource variable dropdown works and panels update on selection
  • Validate helm-test CI check passes (make helm-docs already run)
  • Verify charts/README.md reflects version 1.2.0

Screenshots

image image

@openshift-ci
openshift-ci Bot requested review from crizzo71 and sherine-k July 23, 2026 18:47
@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign jsell-rh for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added a Grafana “HyperFleet API Metrics” dashboard covering API request rate/latency, API build/status, reconciliation (pending/stuck/max stuck), database query duration/errors, DB connection pool, and top request paths.
  • Bug Fixes

    • Updated reconciliation gauge panels to fall back to 0 when no matching resources exist (instead of showing “No data”).
  • Documentation

    • Refreshed dashboard import instructions to document the reconciliation gauge 0 fallback behavior.

Walkthrough

Adds the “HyperFleet API Metrics” Grafana dashboard with Prometheus panels for API, reconciliation, database, connection-pool, and request-path metrics. Reconciliation pending, stuck, and maximum stuck-duration queries now fall back to 0 when no series are returned. Documentation and the changelog describe the dashboard and updated fallback behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Grafana
  participant Prometheus
  participant HyperFleetAPI
  Grafana->>Prometheus: Query API, reconciliation, and database metrics
  Prometheus->>HyperFleetAPI: Scrape exported metric series
  Prometheus-->>Grafana: Return time-series data or zero fallback
  Grafana-->>Grafana: Render dashboard panels
Loading

Suggested reviewers: crizzo71, sherine-k

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a Grafana dashboard for API and DB metrics.
Description check ✅ Passed The description is clearly aligned with the dashboard, docs, and version bump changes in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Sec-02: Secrets In Log Output ✅ Passed No log statements were added in the PR diff; only markdown/JSON changed, so CWE-532 is not triggered.
No Hardcoded Secrets ✅ Passed No CWE-798/259 findings: touched files are changelog/docs/dashboard; scans found no apiKey/secret/token/password literals, embedded creds, private keys, or long base64.
No Weak Cryptography ✅ Passed PASS: PR is docs/dashboard-only; exact scan found no md5/des/rc4/SHA1/ECB or secret-comparison code (CWE-327/CWE-208).
No Injection Vectors ✅ Passed No CWE-89/78/79/502 injection sinks found in PR files; changes are Markdown and Grafana dashboard JSON only.
No Privileged Containers ✅ Passed HEAD only changes charts/dashboards/hyperfleet-api.json; no privileged settings appeared in changed manifests/templates/Dockerfiles.
No Pii Or Sensitive Data In Logs ✅ Passed Only changed file is a Grafana dashboard JSON; no slog/log/printf statements or PII-bearing logs were added (CWE-532 not triggered).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

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

@hyperfleet-ci-bot

hyperfleet-ci-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown

Risk Score: 2 — risk/medium

Signal Detail Points
PR size 1219 lines (>500) +2
Sensitive paths none +0

Computed by hyperfleet-risk-scorer

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/Chart.yaml`:
- Line 5: Add a short note to charts/templates/NOTES.txt mentioning the bundled
charts/dashboards/hyperfleet-api.json dashboard, alongside the existing API,
validation schema, and JWT settings notes, so install and upgrade output
includes this user-facing artifact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ee8bf80a-5749-467a-af9e-0ec817167be8

📥 Commits

Reviewing files that changed from the base of the PR and between 913cd01 and 9fe2730.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • charts/Chart.yaml
  • charts/README.md
  • charts/dashboards/hyperfleet-api.json
  • docs/metrics.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

Comment thread charts/Chart.yaml Outdated
description: HyperFleet API - Cluster Lifecycle Management Service
type: application
version: 1.1.0
version: 1.2.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -p 'NOTES.txt' charts | xargs -I{} sh -c 'echo "--- {} ---"; cat {}'

Repository: openshift-hyperfleet/hyperfleet-api

Length of output: 2053


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== chart files referencing dashboard =="
rg -n --hidden --glob 'charts/**' -i 'dashboard|grafana' charts || true

echo
echo "== chart NOTES file =="
cat -n charts/templates/NOTES.txt

Repository: openshift-hyperfleet/hyperfleet-api

Length of output: 2608


Add the bundled dashboard to charts/templates/NOTES.txt
charts/dashboards/hyperfleet-api.json ships with the chart, but the NOTES file only covers the API, validation schema, and JWT settings. Add a short dashboard note so install/upgrade output covers the user-facing artifact.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@charts/Chart.yaml` at line 5, Add a short note to charts/templates/NOTES.txt
mentioning the bundled charts/dashboards/hyperfleet-api.json dashboard,
alongside the existing API, validation schema, and JWT settings notes, so
install and upgrade output includes this user-facing artifact.

Source: Path instructions

@tirthct tirthct changed the title HYPERFLEET-1361: Add Grafana dashboard for API and database metrics HYPERFLEET-1361 - feat: Add Grafana dashboard for API and DB metrics Jul 23, 2026
Comment thread charts/Chart.yaml Outdated
description: HyperFleet API - Cluster Lifecycle Management Service
type: application
version: 1.1.0
version: 1.2.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why the version bump when the json chart is not part of the helm output yet?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed

Comment thread charts/dashboards/hyperfleet-api.json Outdated
"type": "prometheus",
"uid": "${datasource}"
},
"expr": "max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation_stuck)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When you append or vector(0) to any of the expressions, e.g. max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation_stuck) or vector(0) the output graph looks better imo, the y axis defaults to 0, reads better than No data and there are no gaps in the graph. What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ach, changed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
charts/dashboards/hyperfleet-api.json (1)

1156-1156: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Add coverage for hyperfleet_api_active_connections.

The architecture contract includes this metric, but none of the 12 panel targets queries it. The dashboard therefore misses a production visibility signal despite the PR objective claiming complete API/DB metric coverage. Add a panel or correct the metric inventory and documentation before merge (CWE-682).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@charts/dashboards/hyperfleet-api.json` at line 1156, Update the dashboard
metric inventory around the panel target definitions to cover
hyperfleet_api_active_connections by adding a panel target that queries it,
preserving the existing dashboard structure and coverage conventions;
alternatively, if the metric is intentionally unsupported, remove it from the
architecture contract and update the related documentation.

Source: Linked repositories

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/dashboards/hyperfleet-api.json`:
- Around line 564-570: Update the PromQL expressions for “Resources Pending
Reconciliation” at charts/dashboards/hyperfleet-api.json:564-570, :656-662, and
:748-754 to use a label-aware global fallback with `or on() vector(0)`,
preventing an unlabeled zero series from being unioned with labeled data. Apply
the same expression change at all three sites.

---

Outside diff comments:
In `@charts/dashboards/hyperfleet-api.json`:
- Line 1156: Update the dashboard metric inventory around the panel target
definitions to cover hyperfleet_api_active_connections by adding a panel target
that queries it, preserving the existing dashboard structure and coverage
conventions; alternatively, if the metric is intentionally unsupported, remove
it from the architecture contract and update the related documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 90635993-b78d-43a5-86ae-b06fff5e18ca

📥 Commits

Reviewing files that changed from the base of the PR and between 8880167 and 0f9a69a.

📒 Files selected for processing (2)
  • charts/dashboards/hyperfleet-api.json
  • docs/metrics.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/metrics.md

Comment thread charts/dashboards/hyperfleet-api.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/dashboards/hyperfleet-api.json`:
- Line 564: Update the PromQL expressions for this panel and the other two
related panels so fallback zeros preserve or generate the expected resource_type
and is_delete label combinations, rather than using a single unlabeled
vector(0); alternatively, revise each panel description to accurately describe
the unlabeled whole-vector fallback. Keep the query behavior and panel text
consistent across all three panels.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 16b2db62-a80f-431a-ad35-458e6c32f114

📥 Commits

Reviewing files that changed from the base of the PR and between 0f9a69a and 381e7f4.

📒 Files selected for processing (1)
  • charts/dashboards/hyperfleet-api.json
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

"type": "prometheus",
"uid": "${datasource}"
},
"expr": "max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation) or on() vector(0)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
: "${PROM_URL:?Set PROM_URL to a Prometheus base URL}"

query='max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation) or on() vector(0)'

curl -fsS -G "$PROM_URL/api/v1/query" \
  --data-urlencode "query=$query" |
  jq '.data.result[] | {metric, value}'

Repository: openshift-hyperfleet/hyperfleet-api

Length of output: 235


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file='charts/dashboards/hyperfleet-api.json'

# Show the changed query blocks and nearby panel text.
python3 - <<'PY'
from pathlib import Path
import json

p = Path('charts/dashboards/hyperfleet-api.json')
data = json.loads(p.read_text())
# Print panels containing the target metric/query fragments.
for panel in data.get('panels', []):
    s = json.dumps(panel)
    if 'hyperfleet_api_resource_pending_reconciliation' in s or 'resource_type' in s and 'is_delete' in s:
        print('--- PANEL ---')
        print('title:', panel.get('title'))
        print('description:', panel.get('description'))
        targets = panel.get('targets', [])
        for t in targets:
            expr = t.get('expr')
            if expr and 'hyperfleet_api_resource_pending_reconciliation' in expr:
                print('expr:', expr)
        print()
PY

Repository: openshift-hyperfleet/hyperfleet-api

Length of output: 1099


Make the fallback label-aware or update the panel text. or on() vector(0) only adds a single unlabeled zero when the whole vector is empty; it does not fill missing (resource_type, is_delete) combinations (CWE-682). The description says “for that combination,” so the query and copy disagree. Apply the same fix to the other two panels.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@charts/dashboards/hyperfleet-api.json` at line 564, Update the PromQL
expressions for this panel and the other two related panels so fallback zeros
preserve or generate the expected resource_type and is_delete label
combinations, rather than using a single unlabeled vector(0); alternatively,
revise each panel description to accurately describe the unlabeled whole-vector
fallback. Keep the query behavior and panel text consistent across all three
panels.

Comment thread CHANGELOG.md

### Added

- Grafana dashboard for API and database metrics (`charts/dashboards/hyperfleet-api.json`) — covers HTTP request rate/latency, reconciliation pending/stuck gauges, DB query duration/errors, connection pool, and build info ([#TBD](https://github.com/openshift-hyperfleet/hyperfleet-api/pull/TBD))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(#TBD) you can update this to be your pull request? #311

},
"gridPos": {
"h": 8,
"w": 12,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

consider making this a little smallee? Do we need it to take up half the page?

}
],
"title": "Resources Pending Reconciliation",
"description": "Live-query gauge — falls back to 0 when no resources are pending for that combination.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"description": "Live-query gauge — falls back to 0 when no resources are pending for that combination.",
"description": "Live-query gauge — displays 0 when no resources are pending.",

]
},
"unit": "short"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
},
"noValue" : "0"
},

"type": "prometheus",
"uid": "${datasource}"
},
"expr": "max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation) or on() vector(0)",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"expr": "max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation) or on() vector(0)",
"expr": "max by (resource_type, is_delete) (hyperfleet_api_resource_pending_reconciliation)",

In correspondence with:
https://github.com/openshift-hyperfleet/hyperfleet-api/pull/311/changes#r3691681058
https://github.com/openshift-hyperfleet/hyperfleet-api/pull/311/changes#r3691676826

@ma-hill

ma-hill commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

https://github.com/openshift-hyperfleet/hyperfleet-api/pull/311/changes#r3691682412

Added a note to change Panel 6 to use the default "noValue" instead of "or on() vector(0)"

Also should update Panel 7,8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants