feat: proxy: expose cache size and alive counts as Prometheus metrics 1870 - #1871
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e76f34ee33
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if err := db.QueryRow("PRAGMA page_size").Scan(&pageSize); err != nil { | ||
| return 0, fmt.Errorf("querying page_size: %w", err) | ||
| } | ||
| return pageCount * pageSize, nil |
There was a problem hiding this comment.
Include the WAL in reported disk usage
NewSQLiteDB enables WAL mode in db/sqlite.go, but page_count * page_size measures the database's logical page space rather than the current footprint of the database plus its -wal sidecar. During normal or update-heavy operation, the WAL can remain allocated or grow while page_count stays unchanged, so /health can substantially underreport the cache's actual disk usage. Retain the database path and include the WAL file size, or describe this field as logical database size instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Obsolete after moving to Prometheus: CacheStats now sums the main DB file plus its -wal/-shm sidecars (sqliteFileSize) and is exposed as the bridgetracker_cache_size_bytes gauge; /health is unchanged. Verified against a live instance: gauge == sum of the three files.
| if active, err := cmd.supervised.GetTrackerActives(nil); err != nil { | ||
| cmd.warnf("bridgetracker: health check counting active trackers: %v", err) | ||
| } else { | ||
| resp.AliveTrackers = len(active) |
There was a problem hiding this comment.
Avoid reporting zero when counting trackers fails
When a SQLite query fails—for example because the database is temporarily unavailable—this branch leaves the non-optional AliveTrackers field at its zero value and still returns 200. A consumer therefore cannot distinguish “no active trackers” from “the count could not be read,” potentially producing incorrect operational decisions. Make the field nullable/omittable on failure or expose an explicit unavailable/error state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Obsolete after moving to Prometheus: /health no longer carries alive_trackers. In the sampler a failed count logs a warning and the gauge keeps its previous value instead of reporting 0.
CacheStats now sums the main SQLite file plus its WAL/SHM sidecars (via os.Stat on the retained dbPath) instead of just PRAGMA page_count * page_size, since NewSQLiteDB opens every connection in WAL mode and a recent write can sit uncheckpointed in the -wal file. AliveTrackers is now an omitted-on-error *int, like AliveActivities, so a GetTrackerActives failure no longer reads as "zero active trackers". Addresses review comments on #1871 (#1870) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CacheStats now sums the main SQLite file plus its WAL/SHM sidecars (via os.Stat on the retained dbPath) instead of just PRAGMA page_count * page_size, since NewSQLiteDB opens every connection in WAL mode and a recent write can sit uncheckpointed in the -wal file. AliveTrackers is now an omitted-on-error *int, like AliveActivities, so a GetTrackerActives failure no longer reads as "zero active trackers". Addresses review comments on #1871 (#1870) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ec944d4 to
30053e5
Compare
GET /tracker/v1/health now reports whether the supervised-bridges/activity persistence backend is in-memory or SQLite-backed, its on-disk size when SQLite-backed, and how many trackers/activities are currently alive, so operators can monitor cache growth without querying the DB directly. Fixes #1870 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CacheStats now sums the main SQLite file plus its WAL/SHM sidecars (via os.Stat on the retained dbPath) instead of just PRAGMA page_count * page_size, since NewSQLiteDB opens every connection in WAL mode and a recent write can sit uncheckpointed in the -wal file. AliveTrackers is now an omitted-on-error *int, like AliveActivities, so a GetTrackerActives failure no longer reads as "zero active trackers". Addresses review comments on #1871 (#1870) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… metrics Replace the /health fields with bridgetracker_cache_size_bytes, bridgetracker_alive_trackers and bridgetracker_alive_activities gauges, refreshed by a sampler. The proxy gains an opt-in [Prometheus] section and the metrics HTTP server moves to a shared metrics package. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
30053e5 to
6871c2b
Compare
…gkit Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…igurable Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@claude review |
|
Claude finished @joanestebanr's task in 56s —— View job Review of PR #1871: bridgetracker cache size and alive counts as Prometheus metricsI reviewed the full diff against 🚀 What's New
🐛 Bug FixesNone. The shared server also switches 📋 Config Updates[Prometheus]
Enabled = true # set false to not open the metrics port
Host = "localhost"
Port = 9091
[Tracker]
MetricsSampleInterval = "15s" # <= 0 falls back to 15s
|
Drop the unused activity-store CacheStats, refresh stale comments, document the 9091 port clash with aggkit and stop tracking an unrelated generated mock. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks for the review. Addressed in 39266b0:
Not changed, on purpose:
|
🔄 Changes Summary
GET /tracker/v1/health:bridgetracker_cache_size_bytes(gauge): on-disk size of the SQLite cache (main file +-wal/-shm);0when the in-memory backend is usedbridgetracker_alive_trackers(gauge): supervised bridges not yet in a terminal statebridgetracker_alive_activities(gauge):from_addresses currently supervised by the activity subsystem (only registered/updated when the activity endpoint is configured)[Tracker] MetricsSampleInterval(default15s) (the repo'sprometheushelpers are push-style:GaugeSet)proxybinary gains a[Prometheus]section (Enabled/Host/Port), with the same defaults as aggkit's (enabled,localhost:9091);startPrometheusHTTPServermoved fromcmdto a new sharedmetricspackage (metrics.StartPrometheusHTTPServer) used by both binariesGET /tracker/v1/healthis left untouched: no new fields andHealthResponse.APIRevisionis not bumped/healthis unchanged. Behavior note: since[Prometheus]is enabled by default (like aggkit), the proxy now opens a metrics listener onlocalhost:9091unlessEnabled = false📋 Config Updates
[Prometheus]section in the proxy's config (proxy/config/default.go), same fields and defaults as aggkit's. SetEnabled = falseto not open the metrics port; new[Tracker] MetricsSampleIntervalsets the gauges' refresh period (<= 0 falls back to 15s); overrideHost(e.g.0.0.0.0) if Prometheus scrapes from outside the host/container🔌 API Updates
/metricsendpoint (unless[Prometheus] Enabled = false)Example (default config)
✅ Testing
CacheStats/count errors keep the previous value, activity disabled) and forCacheStatsagainst real SQLite files (bridgetracker/db/sqlite_registry_test.go)make lint,go test ./bridgetracker/... ./proxy/...; scrape/metricson a running proxy with a disk-backed and an in-memory tracker🐞 Issues
📝 Notes
/health: size and counts are time series meant for dashboards/alerting, not liveness data;/healthstays cheap and side-effect freeproxybinary, which had no Prometheus integration before, hence the new config sectiondomain.CacheStatsProvider(optional capability, mirroringTriggerable) already implemented by the SQLite adapters. When registry and activity store share one SQLite file, the size is read once from the registrydocs/bridgetracker.md