feat(metrics): expose pgx pool connection churn counters

What

Adds the remaining pgxpool.Stat lifecycle counters to the scrape-time pool collector, next to the acquisition totals from !2403 (merged):

Metric pgxpool.Stat source
gitlab_artifact_registry_database_connection_pool_opens_total NewConnsCount
gitlab_artifact_registry_database_connection_pool_max_lifetime_destroys_total MaxLifetimeDestroyCount
gitlab_artifact_registry_database_connection_pool_max_idle_destroys_total MaxIdleDestroyCount

All three are cumulative unlabeled counters, read live on each Collect like the existing pool series, so none needs a background updater.

Why

The size gauge and the acquisition counters cannot show churn. A pool that opens and destroys a connection per request reads the same on ..._size{state} as a warm pool holding its connections, and the acquisition totals keep climbing either way. These three separate the two.

Notes

One counter per destroy cause rather than a destroys_total{cause} family: pgxpool.Stat publishes no counter for its other closure causes, so a summable family would read as every closure and undercount. That also keeps state closed at its three values and adds no label to the cardinality tables.

acquireCounters/acquireSample and the test tables become lifetimeCounters/counterSample/lifetimeCounterNames: the list no longer holds only acquisitions, and one table over all seven counters keeps Describe and Collect from drifting apart without a second copy of the suite. Distinct fixture values mean a descriptor paired with the wrong PoolStats field fails the subtest for that counter.

Tests

  • internal/metrics/database_test.go: the three churn counters join the lifetimeCounterNames table, so each gets its own t.Run subtest under the cumulative-value, publishes-without-a-pool, and Describe-declares-everything cases.
  • cmd/artifact-registry/main_integration_test.go: the live-pool scrape assertion covers all seven counters. opens_total must be positive, since the readiness ping acquired over a connection the pool had to open; the two destroy counters only have to publish, because a healthy boot need not age a connection out.

Injection check: pairing newConnsDesc with s.MaxIdleDestroys fails TestRegisterPoolCollector_LifetimeCountersAreCumulative/database_connection_pool_opens_total (Max difference between 23 and 5).

e2e

Metrics-only. No request path, handler, or query changes, so no docs/testing/ scenario is added or affected.

Closes #1206 (closed)

Merge request reports

Loading
Loading