Repository navigation
feat(sentry): report active runs, actions and apps as gauges (umbrella) #8235
Description
Why
Flyte 2 reports anonymous usage to Sentry so we can see how OSS deployments are used (flytestdlib/sentryutils, opt out with FLYTE_DISABLE_SENTRY=true). Today that is counters only: create_run, deploy_task, deploy_trigger (#7672, #7855) and deploy_app (#7855). Counters tell us how often something was created, but not how much is live right now. We cannot answer "how many runs are executing across OSS clusters at this moment", "how many actions are in flight", or "how many apps are serving traffic".
This umbrella tracks adding gauges for the live state of a deployment. Each bullet is a self-contained change; file or pick up one at a time and link it here.
What to change
All three ride on the existing Sentry plumbing. sentry-go v0.49 already exposes Meter.Gauge(name, value, opts...) next to the Count we use, so the work is: add a sentryutils.Gauge(ctx, name, value) helper, then in each service register a background worker (SetupContext.AddWorker, same place the *-sentry-flush workers live) that samples the live count on an interval (60s is fine) and emits it.
-
flytestdlib/sentryutils/sentryutils.go— addGauge(ctx, name string, value float64)mirroringCount. Each gauge is its own metric name (flyte.active_runs,flyte.active_actions,flyte.active_apps), no attributes. Keep theDisabled()/Initgate so a disabled process is a no-op. - Actions repo count (
runs/repository/impl/action.go,runs/repository/interfaces/action.go) — add one method, e.g.CountActionsByPhase(ctx) (map[int32]int64, error)returningSELECT phase, parent_action_name IS NULL AS is_root, COUNT(*) ... GROUP BY 1, 2.idx_actions_phase(runs/migrations/sql/20260408110000_init_schema.sql) already exists, so this is an index-only aggregate, no scan. Both gauges below read from this one query so a single sampler tick costs one round trip. - Active runs (
runs/setup.go) — gaugeflyte.active_runs: rows from the count above whereis_rootand phase is not terminal. The terminal set is already spelled out inruns/repository/impl/action.go(terminalPhases, ~L541); reuse it rather than redefining. - Active actions (
runs/setup.go) — gaugeflyte.active_actions: same count, all rows with a non-terminal phase (root and child). The DB is the source of truth here: it covers every action the runs service knows about, including ones queued before the executor has created a TaskAction CRD. The executor'staskaction.active{phase}OTel observable (executor/pkg/controller/metrics.go) stays as the cluster-side view; do not report it to Sentry as well or the two numbers will disagree during queueing. - Apps running (
app/setup.go) — gaugeflyte.active_apps: count of apps whose status substate isRUNNING(flyteidl2.app.Status.Substate,app/internal/k8s). Sample from the app service's existing view of app status rather than a fresh K8s list per tick.
Design notes for whoever picks these up:
- No attributes. These are process-wide totals, one metric name each; the
operationattribute is only for theflyte.operationcounter. Do not attach project/domain/run names; the point of this telemetry is aggregate counts, not per-tenant data. - Sampling, not events: one gauge emission per interval per process. Do not emit on every state transition.
- Keep it off the request path. Workers only; no interceptor changes.
Outcome
- A fresh OSS deployment with Sentry enabled reports the
flyte.active_runs,flyte.active_actionsandflyte.active_appsgauges within one sampling interval of startup. - Setting
FLYTE_DISABLE_SENTRY=trueproduces no gauge traffic and no background worker. - Each sampler has a unit test covering the non-terminal filter (runs/actions) or the
RUNNINGsubstate filter (apps). - The sampler's cost is bounded: a
COUNT(*)with an indexed phase filter or an in-memory cache read, not a full table scan or K8s list per tick.
Getting started
- Read first:
flytestdlib/sentryutils/sentryutils.go(the whole package is ~100 lines), then howruns/setup.goandapp/setup.gowiresentryutils.Init+AddWorker. - Prior art for a phase-bucketed gauge:
executor/pkg/controller/metrics.go(taskaction.active). - Verify locally:
make devbox-run, run a workflow, and check the Sentry project for theflyte.active_*gauges. Or pointsentry.Initat a local DSN viasentry-cliif you do not have access to the shared project. - Tests:
go test ./flytestdlib/sentryutils/... ./runs/... ./app/... - Setup: CONTRIBUTING.md
Activity
runllm commentedon Oct 23, 2026
It could be possible to add periodic active-state reporting through the existing Sentry plumbing: the code currently records operation counters and honors
FLYTE_DISABLE_SENTRY=true(Sentry utilities). However, the provided sources do not confirmsentry-go’sMeter.GaugeAPI or the runs/actions/apps status queries and workers described in the issue, so I can’t verify those implementation details.Would you like a concise issue review or an implementation plan based only on the available sources?
Sources:
This is an AI-generated response and your feedback is appreciated! Please leave a 👍 if this is helpful and 👎 if it is not.
Mention @Herald to ask follow-up questions. See runllm.com for more!
Icewind52 commentedon Oct 23, 2026
#take