Skip to content

Add automatically attributed historical workload metrics dashboards - #1734

Merged
nadaverell merged 8 commits into
mainfrom
feat/workload-metrics
Sep 15, 2026
Merged

nadaverell merged 8 commits into
mainfrom
feat/workload-metrics

Conversation

@nadaverell

@nadaverell nadaverell commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #1722.

Summary

Add curated request and resource dashboards to the existing Metrics tab for Deployments, StatefulSets and DaemonSets. Radar reads existing Prometheus-compatible data; it does not install collectors or require application changes.

The main charts describe the workload over the selected time range, including previous replicas where metrics and ownership were retained. CPU and memory show workload totals alongside the maximum Pod; throttling shows period-weighted workload percentage and the worst Pod. HTTP charts show request rate, 5xx percentage, p50/p95 latency and reporting Pods. A separate current-Pod table supports comparison without defining historical membership.

The shared range control persists a validated metricsRange in the URL, preserving unrelated workload, Applications and tab parameters. Range changes replace history; opening the full dashboard from a resource drawer preserves the drawer’s time range. Request-source selection stays local to the workload. The container-aware layout uses three columns at 1200px of content, two at 760px and one below. The app-shell minimum width still limits phone layouts; chart expansion and laptop-density refinement are follow-ups. Non-HTTP workers keep resource charts without an empty RED grid. Missing, idle, partial, stale, ambiguous and failed observations remain distinct. Workload chart lines break at omitted evaluation intervals, and tooltips do not borrow values from across those gaps; existing sparse charts retain their sampling behavior.

Disconnected standalone views offer discovery retry and the existing Metrics settings; embedded views direct users to their operator. The connected dashboard leads with charts: per-family historical scope, reporting counts, and concise request/error/latency/throttling definitions remain contextual. About these metrics opens a keyboard-accessible Metrics sources & coverage dialog with grouped current-Pod matching evidence, separate historical-ownership and operator-assertion context, a short interpretation guide, and optional troubleshooting. Matching progress/failure remains distinct from usable historical data. When no HTTP source can be selected, contextual details retain the source-specific matching reasons. The bounded dialog preserves dashboard position and keeps its header/footer accessible while the body scrolls. Actual partial, stale, failed and identity-unverified states remain visible beside charts; identical coverage warnings are shared only across matching populated chart groups. Current-template request/limit values align with the CPU and memory comparison columns and are explicitly qualified as template settings, not actual post-injection allocations or utilization percentages.

Membership, attribution and query design

  • Authorize workload read and namespaced Pod list before metrics access. Historical queries join metrics to retained Kubernetes ownership at each evaluation timestamp, not to a list of current Pod names. Deployment ownership follows Pod → ReplicaSet → Deployment; StatefulSet and DaemonSet ownership is direct.
  • Support raw kube-state-metrics ownership and the standard Kubernetes-mixin workload ownership recording rule. Compare their retained coverage over the requested range, select one strategy, and preserve gaps. A recording rule installed halfway through a range does not take precedence over longer retained raw history.
  • Establish historical cluster scope independently through bounded KSM name/UID anchors, even when current sources already match by UID. Reuse a verified partition for five minutes within the same connection configuration and logical backend. Automatic discovery of a different service, service port or backend path discards old identity evidence; in-flight proofs and dashboard responses cannot carry trust across that switch. Reconnecting to the same service through a new local port-forward retains valid assertions. Cold zero-replica workloads can use other Pods in the already-authorized namespace; an empty namespace without cached proof needs an explicit scope assertion.
  • Current-Pod comparison/fallback uses exact Beyla Pod UID pairs, cAdvisor UID-bearing cgroup segments, or a verified KSM-backed partition. Its 100-Pod cap is visible and does not limit historical totals. Per-family scope notices distinguish historical membership from current-only observations.
  • Keep Beyla HTTP-server and Istio destination-sidecar observations separate and selectable, never summed. Multiple ports aggregate within a source. Istio also uses historical ownership to disambiguate workload kind; waypoints are not mapped to application Pods.
  • Validate status coverage, histogram populations/counts/buckets and known duplicate observation populations. Histogram quantiles remain backend-calculated; throttling is weighted by CFS periods, not an average of Pod percentages. Partial backend responses are rejected, and raw route/peer labels are not returned.
  • Bound POST queries to 16,000 decoded bytes, about 360 evaluations, three concurrent chart queries and a 25-second request deadline. Historical query text and result cardinality do not grow with replica count, though backend join cost remains.
  • Preserve independent current-Pod comparison and current-only HTTP data if historical ownership lookup fails. Existing basic CPU/memory charts remain accessible in a collapsed Basic CPU / memory · identity unverified section, without template overlays or limit-percentage badges; they warn about shared-backend name collisions. Network/storage remain visible under their separate name-matched contract.
  • Manual endpoints may answer with an empty up vector; automatic endpoint discovery skips empty candidates. Safe diagnostics distinguish authorization, invalid API responses, Prometheus query/storage errors, HTTP proxy errors and transport failures.
  • Automatic identity matching is the default. Two optional, mutually exclusive scope assertions are available through the standalone CLI and agent Helm values; supplying one replaces probing for workload requests/resources/history/comparison only, not rightsizing or other legacy metrics. They are process-local, discarded on cluster/backend/credential changes, and do not bypass tenant isolation or duplicate-population guards. Desktop supports automatic matching but does not expose these overrides. The Beyla job filter is applied to workload charts only with an explicit verified scope and accepts one job equality/regex matcher; wider Live Traffic fragments are not supported there.

See chart prerequisites, discovery, semantics and coverage.

Documentation and local configuration

The canonical workload metrics guide starts with chart usage, prerequisites and source semantics, followed by troubleshooting and the detailed compatibility reference. It documents the workload HTTP endpoint's inputs, independent panel states, historical versus current-Pod membership, transitional responses and authorization errors. Operator guidance distinguishes standalone CLI, Desktop, in-cluster OSS and Radar Cloud; shared-installation viewers are directed to their operator's Helm/GitOps configuration. Three content-only screenshots show the six-chart overview, current-Pod comparison and sources/coverage dialog. Screenshots replay a recorded real demo response with deliberate errors; they illustrate the UI rather than certify another backend run.

Companion radar-docs PR #100 maps the OSS guide and its referenced images into a dedicated Metrics page, adds navigation and contextual Applications/Traffic/Prometheus links, and keeps the importer authoritative. It must remain draft until this source is merged and the importer is rerun against OSS main.

Local Prometheus URL, headers and tenant settings are Radar-wide, not per-cluster connection profiles. Switching Kubernetes context retains the manually configured endpoint/headers while the new workload charts recheck identity and discard scope assertions. Changing only the URL also retains saved headers. Configuration docs explain these limits and distinguish them from the existing Argo CD/Kubecost credential bindings. Per-cluster profiles and their credential migration are a separate follow-up; older name-matched charts do not gain the new attribution guarantees.

Live compatibility evidence

These are tested versions/configurations, not a blanket stock-default or percentage-of-users claim.

Combination Verified result Qualification
EKS Prometheus 3.14 + Beyla 3.32 Resource and full HTTP charts Current-UID attribution; historical path not separately recertified
GKE OpenCost Prometheus 2.54; older EKS Prometheus 2.47 Resource charts Current-UID path; throttling absent from the older EKS store
Existing three-cluster Mimir CPU/memory Explicit URL, current-UID path; no single-cluster assertion
EKS Mimir 3.2 + Alloy Prometheus remote-write + Beyla Historical CPU/memory/throttling and full HTTP charts on two workloads Explicit URL, Basic auth and tenant header; automatic cluster proof, no scope assertion
GKE VictoriaMetrics 1.151 + KSM/cAdvisor + Istio 1.30 Historical resource and full HTTP charts, positive requests, injected ~25% 5xx, defined p50/p95 Identity labels preserved; automatic cluster proof; worker, Redis and existing application also have resource history without fabricated HTTP data
Repeatable kind: Prometheus 3.5 + Beyla 3.25 and Istio 1.30 Both observers pass all eight core panels; worker, Redis StatefulSet and DaemonSet pass resources Exact historical CPU/memory/throttling/request/error/latency values survive old-Pod deletion and scale-to-zero; fixtures restored

Cloud workloads were not rolled or scaled for history validation. The tested VictoriaMetrics chart drops cAdvisor id and KSM uid by default; successful automatic attribution preserves those labels. The unlabeled official Istio sample still requires an explicit scope assertion. Default OTLP-to-Alloy conversion without application Pod attributes is not supported by the HTTP adapter. Gateway-level Mimir checks verify rejection of missing/wrong credentials and a missing tenant.

Repeatable lab and verification

The isolated kind demo reuses the existing Beyla fixture, adds cAdvisor/KSM and isolated Istio sidecars, and generates finite traffic without changing the global current context.

bash scripts/workload-metrics-demo.sh up
bash scripts/workload-metrics-demo.sh traffic
make build
bash scripts/workload-metrics-demo.sh check
bash scripts/workload-metrics-demo.sh history

The history check rotates only its HTTP fixtures, verifies old Pods disappear, scales to zero, compares fixed historical timestamps numerically and restores original replicas. The checker cleans up its own Radar and port-forward processes. Operational evidence and credentials remain private.

  • Documentation verification: all five affected MDX pages compile with GFM, Mintlify reports no broken links, and repeat sync is a no-op against the prepared source. Local Mintlify preview loads all three screenshots at desktop/laptop widths with no horizontal overflow and working image expansion.
  • Full root Go suite, the separate Prometheus module suite, targeted race tests, complete build and typecheck pass. Backend lifecycle regressions drive real discovery A→B→A against local HTTP fixtures, reject an old in-flight history proof, and verify initial binding, same-service reconnects, changed ports/paths and reinitialization. These are controlled failover tests, not cloud failover certification.
  • Frontend verification: 106 files / 1,230 tests pass, including 55 workload renderer/help cases for scope, coverage, evidence grouping, loading and failure states. Nine Playwright E2E regressions pass for workload/Applications range continuity, Metrics settings, visible history/withheld errors, unattributable HTTP observations, modal keyboard focus, dismissal, drag-selection and dashboard-position preservation, drawer-range continuity, and missing-evaluation hover behavior. Focused workload/help/value tests (59) and chart/sampling/axis tests (22) pass on the final source. Shared UI: 3,688 passed, one skipped in the earlier full-PR verification.
  • Real Prometheus evaluation tests run in CI: 128-Pod aggregate values, weighted throttling, ownership rollover, raw/recorded membership, kind/cluster collisions, duplicate jobs/HA, resets, idle ratios and histogram consistency.
  • Five live kind baseline cases and both observers’ rollout/zero history checks pass. Mimir/Beyla and VictoriaMetrics/Istio historical charts are also API-verified.
  • Playwright checked real history at 1920px and 1280px with no horizontal page overflow. An injected history error exercised the separate fallback with real basic charts; a recorded live zero-Pod response exercised retained history with an empty current comparison. These UI scenarios are not additional backend certification.
  • UI captures cover live DaemonSet resource history and idle Istio observations, desktop/light and laptop/dark layouts, and an ultrawide check with no horizontal page overflow. Recorded successful live responses are replayed for populated RED and template comparison; controlled UI fixtures exercise shared stale/partial warnings and identity failures. The help dialog is visually checked at 1280/1920/2560px in both themes, with a narrow-viewport overflow check, expanded troubleshooting, and aligned contextual chart footnotes. These distinguish presentation checks from fresh backend certification. The non-HTTP laptop view reaches resource charts about 124px earlier without shrinking charts or text.
  • An earlier session reproduced intermittent port-forward/query failures after initially rendering service history; the DaemonSet returned mixed success/error panels. A separate Kubernetes service-proxy query also timed out. Workstation load was high, but the root cause is not established. The successful final recheck is not a durability/root-cause certification; no cluster reset or transport redesign is included.
  • After automatic discovery is exhausted, recovery can require Discover Prometheus even after cluster connectivity returns. The existing automatic-connect hook attempts once per context/mount; durable reconnect behavior remains a follow-up.

Boundaries and risk

History describes the logical cluster/namespace/kind/name workload, not immutable Kubernetes object lifetime. Retention gaps, missing ownership and staleness around deletion/rate windows remain visible; Radar cannot reconstruct samples never collected. Raw ownership is live-tested; recorded ownership and 128-Pod totals are engine-tested, not a large live deployment.

Ingress observers, native-only histograms, ambient waypoints, gRPC and queue semantics remain follow-ups. Legacy network/filesystem/restart/basic resource charts remain name-based. Unknown HA conventions need upstream deduplication. Large-scale query cost, real HA, Radar Cloud transport and managed-service authentication are not live-certified.

Primary risks are incorrect membership, duplicate totals and expensive joins. Scoped ownership, population guards, fixed-timestamp rollout tests and query bounds mitigate them. No production deployment or distribution publication is included.


Note

High Risk
Large new metrics surface with PromQL joins, cross-cluster attribution, and scope overrides—incorrect membership or totals would mislead operators during incidents.

Overview
Adds Workload Metrics for Deployments, StatefulSets, and DaemonSets: a new GET /prometheus/workload/{kind}/{namespace}/{name} API and Metrics-tab experience combining HTTP request rate, 5xx, latency (Beyla or Istio), CPU, memory, throttling, workload history across rollouts, and current-Pod comparison.

The backend introduces pkg/prom workload query builders plus Prometheus client logic for automatic Pod/cluster attribution (UID, KSM partition, bounded evidence probes) and historical membership via kube-state-metrics ownership joins. Operators can override scope with --prometheus-single-cluster, repeatable --prometheus-cluster-label, and a narrowed --beyla-job-selector (CLI, Helm traffic.*, not persisted in local config); assertions clear on connection or endpoint changes. Discovery now tracks logical backend identity, uses safer manual-endpoint probes, and improves failure messaging.

Docs, docs/workload-metrics.md, Makefile/CI demo hooks, Helm schema/tests, and extensive unit/live tests accompany the change; test cleanup waits for the auth recovery worker during ResetTestState.

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

@nadaverell
nadaverell requested a review from hisco as a code owner September 12, 2026 22:48
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add workload request and resource pressure dashboards

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Adds request, latency, error, throttling, and per-Pod resource pressure dashboards.
• Supports independent Istio and Beyla observers with explicit coverage and freshness states.
• Requires confirmed cluster scope and bounds Pod selection, concurrency, and query duration.
Diagram

sequenceDiagram
    actor Operator
    participant CLI as Radar CLI
    actor User
    participant UI as Metrics UI
    participant API as Workload API
    participant K8s as Pod Resolver
    participant Query as PromQL Builder
    participant Prom as Prometheus
    Operator->>CLI: Assert cluster scope
    CLI->>API: Bind trusted scope
    User->>UI: Open Metrics tab
    UI->>API: Request workload range
    API->>K8s: Resolve owned Pods
    K8s-->>API: Current Pods max 100
    API->>Query: Build scoped queries
    Query-->>API: Observer and pressure queries
    API->>Prom: Query with bounded concurrency
    Prom-->>API: Time series results
    API-->>UI: Panels and coverage states
    UI-->>User: Charts and Pod links
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Prometheus recording rules
  • ➕ Reduces runtime query complexity and repeated histogram calculations
  • ➕ Can improve latency for large or frequently viewed workloads
  • ➖ Requires operators to install and maintain backend-specific rules
  • ➖ Introduces deployment coupling and rule-version compatibility
  • ➖ Still requires trustworthy cluster and Pod attribution
2. Generic dashboard builder
  • ➕ Could support arbitrary metrics and future observers without dedicated UI code
  • ➕ Offers greater customization for advanced users
  • ➖ Substantially expands product scope and configuration complexity
  • ➖ Makes attribution, coverage, and missing-data semantics user-defined
  • ➖ Provides weaker defaults for safe workload-level interpretation

Recommendation: Keep the PR's bounded, read-only adapter approach. Dedicated Beyla, Istio, and cAdvisor queries provide controlled attribution and explicit missing-data semantics without installing instrumentation or backend rules; recording rules can be considered later if production query cost demonstrates a need.

Files changed (26) +1865 / -28

Enhancement (16) +1097 / -26
main.goAdd workload metrics scope CLI flags +23/-0

Add workload metrics scope CLI flags

• Adds mutually exclusive single-cluster and exact cluster-label assertions for workload metrics. Validated scope configuration is passed into application startup.

cmd/explorer/main.go

bootstrap.goBind workload scope during application bootstrap +7/-0

Bind workload scope during application bootstrap

• Extends application configuration with workload metrics scope and installs the validated assertion on the active Prometheus client.

internal/app/bootstrap.go

client.goTie workload trust to the active connection +39/-9

Tie workload trust to the active connection

• Stores workload scope and Beyla selection on the Prometheus client. Clears trust when the Kubernetes connection, metrics endpoint, or headers change while preserving it across equivalent startup reinitialization.

internal/prometheus/client.go

handlers.goRegister the workload metrics endpoint +1/-0

Register the workload metrics endpoint

• Adds the workload-scoped Prometheus HTTP route for supported Kubernetes controllers.

internal/prometheus/handlers.go

workload_config.goManage connection-local workload metrics scope +38/-0

Manage connection-local workload metrics scope

• Adds validated, defensive-copying helpers to bind and retrieve workload metrics configuration from the current non-retired client.

internal/prometheus/workload_config.go

workload_metrics.goCollect coverage-aware workload metric panels +311/-0

Collect coverage-aware workload metric panels

• Implements the authorized workload metrics endpoint, bounded Pod resolution, query concurrency, observer selection, and response states. It withholds derived values when histogram, status, or reporting-Pod coverage is incomplete.

internal/prometheus/workload_metrics.go

AreaChart.tsxAdd responsive dashboard chart layout +9/-8

Add responsive dashboard chart layout

• Introduces a dashboard layout optimized for medium-width panels with responsive compact fallback, readable margins, and edge-aware time labels.

packages/k8s-ui/src/components/charts/AreaChart.tsx

axis.tsDefine medium-width dashboard axes +2/-1

Define medium-width dashboard axes

• Adds a 600-by-240 chart layout with larger text and reduced tick density for dashboard cards.

packages/k8s-ui/src/components/charts/axis.ts

format.tsFormat request rates and percentages +4/-0

Format request rates and percentages

• Adds precision-aware display formatting for percent and requests-per-second chart values.

packages/k8s-ui/src/components/charts/format.ts

workload_requests.goBuild Beyla and Istio request queries +100/-0

Build Beyla and Istio request queries

• Builds source-specific request rate, HTTP 5xx, latency quantile, metric coverage, and reporting-Pod queries. It validates Beyla job selectors and keeps observers independently attributed.

pkg/prom/workload_requests.go

workload_scope.goDefine safe workload scope and pressure queries +90/-0

Define safe workload scope and pressure queries

• Validates process-local cluster assertions and builds deduplicated CPU, memory, and throttling queries for exact current Pod selections. Rate windows are at least five minutes and twice the evaluation step.

pkg/prom/workload_scope.go

workloadMetrics.tsAdd the workload metrics query client +71/-0

Add the workload metrics query client

• Defines workload panel, source, and response types and adds a cached polling hook. It stops polling for setup-required responses and retries once when the backend connection changes mid-request.

web/src/api/workloadMetrics.ts

PrometheusChartsGrid.tsxIntegrate workload panels into expanded metrics +11/-0

Integrate workload panels into expanded metrics

• Places request and pressure observations before existing resource charts for supported workloads. Rightsizing remains available at the end of the shared expanded dashboard.

web/src/components/resource/PrometheusChartsGrid.tsx

WorkloadMetricsSection.tsxRender request and resource pressure dashboards +352/-0

Render request and resource pressure dashboards

• Adds request rate, HTTP 5xx, p50/p95 latency, CPU throttling, and sortable per-Pod resource comparisons. The UI distinguishes setup, absent, partial, stale, and failed observations while preserving gaps and Pod drill-down links.

web/src/components/resource/WorkloadMetricsSection.tsx

workloadMetricValues.tsExtract fresh workload and Pod values +30/-0

Extract fresh workload and Pod values

• Adds helpers that return only finite, recent terminal samples and retain Pods whose latest metric is unavailable.

web/src/components/resource/workloadMetricValues.ts

WorkloadView.tsxLink workload drawers to the expanded dashboard +9/-8

Link workload drawers to the expanded dashboard

• Moves rightsizing placement into the expanded chart grid and adds a drawer action that opens the full request and resource dashboard.

web/src/components/workload/WorkloadView.tsx

Bug fix (1) +1 / -1
beyla-demo.shBound the Beyla demo Redis probe +1/-1

Bound the Beyla demo Redis probe

• Wraps the Redis connectivity probe with a hard timeout so it cannot block later HTTP traffic generation.

scripts/beyla-demo.sh

Refactor (1) +1 / -1
beyla.goShare the default Beyla job selector +1/-1

Share the default Beyla job selector

• Reuses the common Prometheus package constant so traffic and workload metrics apply the same default Beyla and Alloy job matching.

internal/traffic/beyla.go

Tests (7) +649 / -0
workload_metrics_test.goTest workload endpoint states and trust invalidation +204/-0

Test workload endpoint states and trust invalidation

• Covers unavailable, stale, partial, and error states; coverage gating; observer separation; authorization; setup responses; and connection-bound scope lifecycle.

internal/prometheus/workload_metrics_test.go

axis.test.tsTest dashboard axis dimensions +7/-0

Test dashboard axis dimensions

• Verifies dashboard sizing and confirms compact and existing full layouts remain unchanged.

packages/k8s-ui/src/components/charts/axis.test.ts

workload_promql_test.goEvaluate workload PromQL with real Prometheus +203/-0

Evaluate workload PromQL with real Prometheus

• Adds an opt-in promtool suite covering observer and cluster isolation, duplicate scrapes, resets, long windows, idle ratios, incomplete labels, histogram populations, and resource pressure calculations.

pkg/prom/workload_promql_test.go

workload_requests_test.goTest request query safety and consistency +63/-0

Test request query safety and consistency

• Verifies exact cluster and Pod scoping, source-specific constraints, latency units, rolling windows, and rejection of ambiguous scopes or injected job fragments.

pkg/prom/workload_requests_test.go

workload_scope_test.goTest scope validation and throttling queries +47/-0

Test scope validation and throttling queries

• Covers unsafe scope rejection, deterministic exact matchers, isolated endpoints, Pod constraints, and preservation of missing throttling counters.

pkg/prom/workload_scope_test.go

WorkloadMetricsSection.render.test.tsxTest workload dashboard interpretation states +60/-0

Test workload dashboard interpretation states

• Verifies reporting-Pod counts, measured zeroes, Pod links, setup guidance, load errors, and explicit source selection when multiple observers report.

web/src/components/resource/WorkloadMetricsSection.render.test.tsx

workloadMetricValues.test.tsTest current workload sample selection +65/-0

Test current workload sample selection

• Ensures zero values remain valid while gaps, stale samples, and unavailable Pod values are not replaced or silently discarded.

web/src/components/resource/workloadMetricValues.test.ts

Documentation (1) +117 / -0
workload-metrics.mdDocument workload metrics setup and interpretation +117/-0

Document workload metrics setup and interpretation

• Documents cluster-scope requirements, panel semantics, supported Beyla and Istio observations, query bounds, coverage behavior, and verification procedures. It also records why Traefik attribution is not yet supported.

docs/workload-metrics.md

@qodo-code-review

qodo-code-review Bot commented Sep 12, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Helm users cannot enable dashboards ✓ Resolved 🔗 Cross-repo conflict ≡ Correctness
Description
WorkloadMetricsScope.Matchers rejects requests unless the process receives either
--prometheus-single-cluster or at least one --prometheus-cluster-label, but the Helm interface
exposes neither setting. When the new image is installed through the published chart or the
deployment repository’s staging chart, the workload endpoint therefore remains in setup-required
state with no chart-supported way to activate it.
Code

cmd/explorer/main.go[R131-133]

+	workloadSingleCluster := flag.Bool("prometheus-single-cluster", false, "Trust the connected metrics endpoint as containing only this cluster (enables workload request/pressure panels; invalidated on context, URL or header changes)")
+	workloadClusterLabels := map[string]string{}
+	flag.Func("prometheus-cluster-label", "Exact cluster label for workload request/pressure queries, e.g. cluster=production (repeatable; alternative to --prometheus-single-cluster)", func(raw string) error {
Relevance

●●● Strong

Required feature configuration is absent from published Helm interfaces, blocking the PR’s stated
dashboard functionality for chart users.

PR-#732

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR makes one of the new flags mandatory for workload queries, while both downstream chart copies
render only the existing Prometheus URL and header arguments and provide no generic extra-arguments
escape hatch.

cmd/explorer/main.go[131-146]
pkg/prom/workload_scope.go[21-27]
External repo: skyhook-io/helm-charts, charts/radar/templates/deployment.yaml [98-110]
External repo: skyhook-io/helm-charts, charts/radar/values.yaml [516-539]
External repo: skyhook-dev/deployment, argocd/addons/radar-staging/radar-staging/skh-nonprod/charts/radar/templates/deployment.yaml [62-70]
External repo: skyhook-dev/deployment, argocd/addons/radar-staging/radar-staging/skh-nonprod/charts/radar/values.schema.json [292-305]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workload dashboards require a process-local Prometheus scope assertion, but Helm-managed installations cannot supply either newly introduced flag.
## Fix Focus Areas
- deploy/helm/radar/templates/deployment.yaml[99-110]
- deploy/helm/radar/values.yaml[526-549]
- deploy/helm/radar/values.schema.json[352-365]
- deploy/helm/radar/README.md[205-215]
## Recommended Fix
Add mutually exclusive Helm values for single-cluster trust and repeatable exact cluster labels, validate them in the schema, and render the corresponding CLI arguments in the Deployment template. Document the values and coordinate propagation to the published helm-charts copy and the staging deployment chart; configure staging with the assertion appropriate for its dedicated Prometheus endpoint.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Disconnected metrics requests still run ✓ Resolved 📘 Rule violation ☼ Reliability
Description
handleWorkloadMetrics reads the cluster-backed resource cache and resolves owned Pods without
first enforcing a connectivity guard. When Kubernetes disconnects while the Prometheus client and
cache remain allocated, the request can reach cached Pod resolution and range queries instead of
stopping with the standard 503 response.
Code

internal/prometheus/workload_metrics.go[75]

+	cache := k8s.GetResourceCache()
Relevance

●●● Strong

Recent precedent accepts fixes ensuring Prometheus handlers guard cluster-backed operations and
return correct connectivity or availability errors.

PR-#1694

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 3036634 requires cluster-touching handlers to enforce connectivity before their
first cluster operation. The new handler reaches k8s.GetResourceCache() and ResolvePodScope()
without such a guard, while the server's existing requireConnected implementation provides the
standardized disconnected response.

Rule 3036634: Cluster-touching HTTP handlers must enforce connectivity with requireConnected
internal/prometheus/workload_metrics.go[45-80]
internal/server/server.go[4845-4852]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new workload metrics handler accesses cluster-backed state without invoking the server connectivity guard, allowing processing to continue after the Kubernetes connection is lost.
## Fix Focus Areas
- internal/prometheus/workload_metrics.go[45-80]
- internal/server/server.go[718-723]
## Recommended Fix
Wrap the registered Prometheus routes with a middleware or injected gate that calls `s.requireConnected(w)` before dispatching to any handler. Return immediately when it reports disconnection so `handleWorkloadMetrics` cannot access authorization, cache, or query state first.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Istio metrics are labelled as server data ✓ Resolved 🐞 Bug ≡ Correctness
Description
WorkloadMetricsSection hard-codes the request footer as HTTP server regardless of data.source.
When the user selects Istio, the backend supplies destination-sidecar observations, so the
dashboard's interpretation text misidentifies the telemetry being displayed.
Code

web/src/components/resource/WorkloadMetricsSection.tsx[127]

+              <p>HTTP server · {Math.round(data.rateWindowSeconds / 60)}-minute rates · {reportingPods == null ? "Reporting Pod count unavailable" : `${reportingPods} of ${data.podsTotal} current Pods reporting`}</p>
Relevance

●●● Strong

The footer is a deterministic UI correctness bug: its telemetry description must follow the selected
Istio or Beyla source.

PR-#1680

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The frontend offers a source selector and renders its chosen source, but its explanatory copy
remains unconditional. The backend defines the two observers as distinct Beyla HTTP-server and Istio
destination-sidecar sources.

web/src/components/resource/WorkloadMetricsSection.tsx[65-103]
web/src/components/resource/WorkloadMetricsSection.tsx[127-134]
internal/prometheus/workload_metrics.go[123-125]
pkg/prom/workload_requests.go[63-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workload metrics footer always calls the selected request telemetry `HTTP server`, including when the user selected Istio. Istio data is explicitly collected as destination-sidecar telemetry, so the displayed interpretation is inaccurate.
## Fix Focus Areas
- web/src/components/resource/WorkloadMetricsSection.tsx[127-134]
- internal/prometheus/workload_metrics.go[123-125]
## Recommended Fix
Derive the footer and interpretation wording from `data.source` (or the matching entry in `data.sources`). Keep the HTTP-server wording for Beyla and use destination-sidecar wording for Istio; use neutral wording if no source is selected.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread internal/prometheus/workload_metrics.go
Comment thread web/src/components/resource/WorkloadMetricsSection.tsx Outdated
Comment thread cmd/explorer/main.go Outdated
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from 479a73c to 30faff4 Compare September 12, 2026 22:54

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread internal/prometheus/workload_metrics.go
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch 3 times, most recently from 70b6f94 to 43d2448 Compare September 13, 2026 10:27
@nadaverell nadaverell changed the title Add workload request and resource pressure dashboards Add automatically attributed workload request and pressure dashboards Sep 13, 2026
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from 43d2448 to f1a8e50 Compare September 13, 2026 11:10

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread pkg/prom/workload_requests.go Outdated
Comment thread internal/prometheus/client.go
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from f1a8e50 to 8d76e2c Compare September 13, 2026 12:18

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread pkg/prom/client.go Outdated
Comment thread internal/prometheus/workload_attribution.go
Comment thread internal/prometheus/workload_attribution.go
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from 8d76e2c to ecfbe20 Compare September 13, 2026 12:30

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread web/src/components/resource/WorkloadMetricsSection.tsx
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch 3 times, most recently from 85225b7 to 633a691 Compare September 13, 2026 15:31

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread internal/prometheus/workload_attribution.go
Comment thread internal/prometheus/workload_attribution.go
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from 633a691 to bb71926 Compare September 13, 2026 20:54
Comment thread scripts/workload-metrics-demo/check.mjs
@nadaverell nadaverell changed the title Add automatically attributed workload request and pressure dashboards Add automatically attributed historical workload metrics dashboards Sep 14, 2026
@qodo-code-review

Copy link
Copy Markdown

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread internal/prometheus/workload_metrics.go
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch 5 times, most recently from b955dd2 to cf9141a Compare September 15, 2026 09:37

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cf9141a. Configure here.

Comment thread internal/prometheus/workload_history.go
Comment thread internal/prometheus/workload_history.go Outdated
@nadaverell
nadaverell force-pushed the feat/workload-metrics branch from cf9141a to 49c45c3 Compare September 15, 2026 11:55
@nadaverell
nadaverell merged commit 71817cd into main Sep 15, 2026
9 checks passed
@nadaverell
nadaverell deleted the feat/workload-metrics branch September 15, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chart workload metrics from kube-state-metrics ownership history

2 participants