You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a readiness gauge so a permanent, non-requeuing ephemeris-push failure is alertable. PR #215 fixed ntn_operators_ephemeris_push_errors_total to count every push failure (not once per episode), which restores the NTNEphemerisPushFailing alert for transient outages that tight-requeue every minute. But the four permanent reasons that deliberately do not requeue still increment the counter only once, and a rate/increase() alert cannot sustain on a one-shot sample.
Background
pushEphemerisUpdateIfNeeded classifies failures via ephemerisPushShouldRequeue(reason):
Requeuing (transient) — e.g. ProviderPushFailed, gNB unreachable, API GET error → RequeueAfter: 1m. The per-failure counter (shipped in feat(controller): WO-20 event & GitOps hygiene — emit after status, gate on transition #215) advances each minute, so increase(ntn_operators_ephemeris_push_errors_total[15m]) > 0for: 15m fires and stays firing through the outage. ✅ Covered.
Non-requeuing (permanent) — EphemerisRefNotFound, EphemerisPayloadMissing, EphemerisStale, ProviderPushRejected. These clear only on an external change (spec edit / ephemeris refresh), so the reconcile does not retry. The counter increments once; increase(...[15m]) is true for ~15m then resolves, so a persistent misconfiguration goes unalerted. ❌ Not covered by a rate alert.
The durable EphemerisPushed=False condition already records the permanent failure for kubectl inspection, but there is no alertable metric for it. A misconfiguration that silently prevents ephemeris push is arguably more important to alert on than a transient blip (which often self-heals).
A gauge value persists in the TSDB between scrapes, so == 0 for 15m fires even when the reconcile does not requeue — covering the permanent reasons that the counter alert cannot. It is complementary to, not a replacement for, the existing NTNEphemerisPushFailing counter-rate alert (which measures failure rate during a churning transient outage).
Scope decision (design, before code)
Do this holistically, not as a one-metric bolt-on:
Apply the same readiness pattern to ConfigApplyErrorsTotal (ntn_operators_config_apply_ready) so runtime push and config apply are consistent, rather than leaving an asymmetry (push has readiness, apply does not).
Keep the existing *_errors_total counters and their rate alerts (failure rate ≠ currently-broken); the gauges add the "currently broken" signal.
Update dist/chart/templates/monitoring/prometheusrule.yaml, the docs/runbooks/alerts.md runbook, and optionally the Grafana dashboard.
Tests: gauge → 0 on failure, → 1 on success/recovery/up-to-date, deleted on CR delete; and that the readiness alert expression behaves for a non-requeuing reason.
Origin
Surfaced in the PR #215 (WO-20) adversarial review. The minimal per-failure counter fix shipped in #215; this gauge is the tracked follow-up for the permanent-reason coverage the counter fundamentally cannot provide.
Summary
Add a readiness gauge so a permanent, non-requeuing ephemeris-push failure is alertable. PR #215 fixed
ntn_operators_ephemeris_push_errors_totalto count every push failure (not once per episode), which restores theNTNEphemerisPushFailingalert for transient outages that tight-requeue every minute. But the four permanent reasons that deliberately do not requeue still increment the counter only once, and a rate/increase()alert cannot sustain on a one-shot sample.Background
pushEphemerisUpdateIfNeededclassifies failures viaephemerisPushShouldRequeue(reason):ProviderPushFailed, gNB unreachable, API GET error →RequeueAfter: 1m. The per-failure counter (shipped in feat(controller): WO-20 event & GitOps hygiene — emit after status, gate on transition #215) advances each minute, soincrease(ntn_operators_ephemeris_push_errors_total[15m]) > 0for: 15mfires and stays firing through the outage. ✅ Covered.EphemerisRefNotFound,EphemerisPayloadMissing,EphemerisStale,ProviderPushRejected. These clear only on an external change (spec edit / ephemeris refresh), so the reconcile does not retry. The counter increments once;increase(...[15m])is true for ~15m then resolves, so a persistent misconfiguration goes unalerted. ❌ Not covered by a rate alert.The durable
EphemerisPushed=Falsecondition already records the permanent failure forkubectlinspection, but there is no alertable metric for it. A misconfiguration that silently prevents ephemeris push is arguably more important to alert on than a transient blip (which often self-heals).Proposal
Add a readiness gauge:
1on a successful push (or when the push is already up to date / not configured — "not currently failing").0on any push failure, regardless of reason.DeletePartialMatch{namespace, config}on finalizer cleanup (mirrors the counter, prevents cardinality leak on CR delete).Alert:
A gauge value persists in the TSDB between scrapes, so
== 0 for 15mfires even when the reconcile does not requeue — covering the permanent reasons that the counter alert cannot. It is complementary to, not a replacement for, the existingNTNEphemerisPushFailingcounter-rate alert (which measures failure rate during a churning transient outage).Scope decision (design, before code)
Do this holistically, not as a one-metric bolt-on:
ConfigApplyErrorsTotal(ntn_operators_config_apply_ready) so runtime push and config apply are consistent, rather than leaving an asymmetry (push has readiness, apply does not).*_errors_totalcounters and their rate alerts (failure rate ≠ currently-broken); the gauges add the "currently broken" signal.dist/chart/templates/monitoring/prometheusrule.yaml, thedocs/runbooks/alerts.mdrunbook, and optionally the Grafana dashboard.Origin
Surfaced in the PR #215 (WO-20) adversarial review. The minimal per-failure counter fix shipped in #215; this gauge is the tracked follow-up for the permanent-reason coverage the counter fundamentally cannot provide.