Commits
Tarun Sukhani authored b28c1175774
feat: bind HikariCP pool + Caffeine cache metrics to Micrometer (PF-85, PF-86) Two related observability gaps closed against the PF-13 Micrometer integration. Both surfaced during a jclaw load-test investigation (2026-05-03) where pool exhaustion at concurrency 50 was visible only in Hibernate WARN logs, not in /@metrics output. PF-85 — HikariCP pool metrics HikariDataSourceFactory now attaches HikariCP's bundled MicrometerMetricsTrackerFactory against Metrics.registry() before returning the datasource. The tracker emits the standard hikaricp_* families: connections, connections_active, connections_idle, connections_pending (queue depth — the missing signal under exhaustion), connections_acquire_seconds, connections_creation_seconds, connections_usage_seconds, connections_timeout_total. No new dependency — HikariCP-5.1.0 ships com.zaxxer.hikari.metrics.micrometer.* in the main jar. Slot ordering makes this a direct call: DBPlugin (slot 300) runs after MetricsPlugin (slot 30), so by the time HikariDataSourceFactory's createDataSource is invoked, Metrics.install has already swapped the facade from SimpleMeterRegistry to PrometheusMeterRegistry. The tracker captures the live registry, not the default. PF-86 — Caffeine cache metrics CaffeineImpl gains a bindMetrics(MeterRegistry) method that calls CaffeineCacheMetrics.monitor(registry, cache, "play_cache"). The binding cannot happen in CaffeineImpl's constructor because Cache.init() runs in Play.start() at line 725, BEFORE the plugin lifecycle starts at line 731 — at that point Metrics.registry() still returns the SimpleMeterRegistry default, so a constructor-time bind would attach to a registry that never gets exposed at /@metrics. Resolution: MetricsPlugin.onApplicationStart() now calls bindFrameworkCacheMetrics(installed) right after Metrics.install. The plugin checks instanceof CaffeineImpl so apps running an alternate CacheImpl (Memcached, custom) don't fault. Errors are swallowed with a WARN — failed metrics binding shouldn't crash the app. Resulting per-cache metrics: cache_size (gauge), cache_gets_total (counter, hit/miss tag), cache_evictions_total, cache_eviction_weight_total, cache_load_duration_seconds (timer, success/failure tag). No new dependency — micrometer-core 1.13.6 already includes the Caffeine binder. Test Added CaffeineImplTest.bindMetricsRegistersCacheMetersOnRegistry — binds to a SimpleMeterRegistry, exercises the cache (one set, one hit, one miss), asserts cache.size gauge and cache.gets meters appear under the play_cache tag. Pure unit test, no Play boot required. Hikari-side verification is left to the integration testapp / runtime inspection — the unit-test path would need a real DB connection to exercise the tracker meaningfully, which is outside the existing test fixture's scope. The wiring itself is a one-line setMetricsTrackerFactory call against an existing well-tested HikariCP API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>