Metrics: Added prometheus Observability metrics for syncer - #1577
Metrics: Added prometheus Observability metrics for syncer#1577richochetclementine1315 wants to merge 2 commits into
Conversation
Signed-off-by: Mrinmoy Matilal <mrinmoymatilal1315@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR adds Prometheus observability metrics for the backend syncer so operators can detect stalled/failed sync checks, monitor request latency, and confirm package creation activity.
Changes:
- Defines and registers four new syncer metrics (last success timestamp, check failures, check duration, packages created) and exposes small helper functions to update them.
- Wires metric updates into the syncer’s update-check loop and package-creation path.
- Adds unit tests validating metric updates, and updates Go module dependencies accordingly.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
backend/pkg/syncer/syncer.go |
Records sync-check duration/failures/last-success and increments package-created counter. |
backend/pkg/metrics/metrics.go |
Adds new metric collectors, helper functions, and registers them. |
backend/pkg/metrics/syncer_metrics_test.go |
Adds isolated unit tests for the new syncer metrics. |
backend/go.mod |
Adds an indirect dependency pulled in by the new/updated test dependencies. |
Suppressed comments (1)
backend/pkg/syncer/syncer.go:497
- There is a whitespace-only blank line here (visible in the diff). Please remove it (or run gofmt) so the file stays cleanly formatted.
return nil, err
}
metrics.SyncerPackageCreated(descriptor.name, descriptor.arch.String())
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| l.Debug().Str("channel", descriptor.name).Str("arch", descriptor.arch.String()).Str("currentVersion", currentVersion).Msg("checking for updates") | ||
|
|
||
| channel := descriptor.name | ||
| arch := descriptor.arch.String() |
| syncerPackagesCreatedTotal.WithLabelValues(channel, arch).Inc() | ||
| } | ||
|
|
||
| // registerNebraskaMetrics registers the application metrics collector with the DefaultRegistrer. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (4)
backend/pkg/metrics/syncer_metrics_test.go:36
- This test doesn't currently verify that an observation was recorded (only that the collector yields at least one metric). Checking the histogram's sample count/sum makes the test actually detect a broken
SyncerCheckDurationimplementation.
func TestSyncerCheckDuration(t *testing.T) {
SyncerCheckDuration("alpha", "amd64", 1.5)
count := testutil.CollectAndCount(syncerCheckDurationSeconds)
if count == 0 {
t.Fatal("expected histogram to have at least one observation registered")
}
}
backend/pkg/syncer/syncer.go:229
- Line contains whitespace-only indentation (spaces on an otherwise blank line), which will fail gofmt/golines-style checks and adds noisy diffs. Make the blank line truly blank (or remove it) to keep formatting stable.
l.Debug().Str("channel", descriptor.name).Str("arch", descriptor.arch.String()).Str("currentVersion", currentVersion).Msg("checking for updates")
channel := descriptor.name
arch := descriptor.arch.String()
backend/pkg/syncer/syncer.go:498
- There is a whitespace-only blank line before the new metrics call. This is likely to fail formatting/lint checks; replace it with a real blank line to keep gofmt output clean.
}
metrics.SyncerPackageCreated(descriptor.name, descriptor.arch.String())
return pkg, nil
backend/pkg/metrics/syncer_metrics_test.go:7
- To validate the histogram helper, the test needs to assert the histogram's sample count/sum changes.
CollectAndCount(syncerCheckDurationSeconds)can be non-zero even if the helper forgets to callObserve, because simply creating a labeled child metric makes the vec collectable.
This issue also appears on line 29 of the same file.
import (
"testing"
"github.com/prometheus/client_golang/prometheus/testutil"
)
Closes Issue #1576
What this PR does
The syncer (
backend/pkg/syncer/syncer.go) currently has no Prometheus metrics, sothere's no way to tell from the outside whether it's actually working — whether it's
successfully checking for updates, how long those checks take, or whether it's actually
creating new packages when it finds them.
This PR adds 4 new metrics and wires them into the syncer's existing code paths. No
existing behavior, function signature, or return value is changed — this is purely
additive.
Changes
backend/pkg/metrics/metrics.goGaugeVec, 2CounterVecs, 1HistogramVec.SyncerLastSuccessTimestamp,SyncerCheckFailure,SyncerCheckDuration,SyncerPackageCreated) so thesyncerpackage can update these metrics without reaching into
metrics-package-privatevariables.
registerNebraskaMetrics().calculateMetrics()is untouched — these new metrics are event-driven (updated liveas the syncer runs), not pull-based like the existing DB-stats metrics, so there was
nothing to add there.
backend/pkg/syncer/syncer.gometricspackage import.checkForUpdates(): time the existingdoOmahaRequest()call, record theduration, increment the failure counter on error, and set the last-success timestamp
on success. The existing control flow (what returns, what loops) is unchanged.
createPackage(): increment the packages-created counter right before theexisting final
return pkg, nil— i.e. only after package creation has actuallysucceeded in the database.
How I tested this
1. Unit tests (isolated, no DB/network needed)
Added
backend/pkg/metrics/syncer_metrics_test.go, usinggithub.com/prometheus/client_golang/prometheus/testutilto verify each metric updatescorrectly in isolation:
2. Live end-to-end test — success path
Ran the backend locally with the syncer enabled against the real Flatcar update
servers, then checked
/metrics:3. Live end-to-end test — failure path
Restarted the backend pointing
-sync-update-urlat an unreachable host to force afailure:
4. Regression check
Confirmed the existing syncer test suite still passes unmodified: