skip to content

How do the datasource/HikariCP pool metrics and logback.events meter get registered, and what do they tell you?

level: seniorimportance: should knowfreq 40%

answer

  1. DataSource present => jdbc.connections.active/idle/max/min
  2. Hikari => hikaricp.connections.pending/active/idle + acquire/usage/creation + timeout
  3. pending>0 or timeout climbing = pool exhaustion
  4. logback.events Counter tagged level
  5. conditional: needs DataSource / Logback backend

basics

~20 s

When a DataSource bean exists Boot registers jdbc.connections.* pool metrics; if the pool is HikariCP it also exposes hikaricp.connections.active/idle/pending/max plus timing metrics. logback.events counts log lines per level via LogbackMetrics, so you can alert on error-log rate.

solid answer

~30 s

Both are conditional MeterBinders. **DataSource**: Boot's `DataSourcePoolMetricsAutoConfiguration` wraps each `DataSource` bean with `DataSourcePoolMetadataProvider` and registers `jdbc.connections.active/idle/max/min`. If the concrete pool is **HikariCP**, Hikari's own metrics tracker is wired via `HikariDataSource.setMetricsTrackerFactory`, giving `hikaricp.connections`, `hikaricp.connections.active/idle/pending`, `hikaricp.connections.max/min`, and timers `hikaricp.connections.acquire` (wait to get a connection), `hikaricp.connections.usage` (checkout duration), `hikaricp.connections.creation`, plus `hikaricp.connections.timeout` counter. `hikaricp.connections.pending` > 0 sustained means pool exhaustion. **Logging**: `LogbackMetrics` attaches a turbo-filter/appender to the Logback context and increments `logback.events` (a Counter) tagged `level`=error|warn|info|debug|trace — the cheapest way to alert on a spike in ERROR logs. Both register only when their dependency is present (a DataSource; Logback as the logging backend).

code

java · 14 lines
java
// Both are conditional & automatic. Example alert-worthy PromQL:
//   hikaricp_connections_pending{pool="HikariPool-1"} > 0     // waiters
//   rate(hikaricp_connections_timeout_total[5m]) > 0          // acquisition timeouts
//   histogram_quantile(0.99, rate(hikaricp_connections_acquire_seconds_bucket[5m]))
//   rate(logback_events_total{level="error"}[5m])             // error-log spike

// If you build the DataSource manually, keep it a HikariDataSource bean
// so Boot can attach the Micrometer metrics tracker:
@Bean
HikariDataSource dataSource(DataSourceProperties props) {
    return props.initializeDataSourceBuilder()
                .type(HikariDataSource.class)
                .build();
}

go deeper

for a junior

Know a DataSource yields pool metrics and Logback yields logback.events per level.

for a middle

Name the specific hikaricp.* meters and the logback.events level tag.

for a senior

Explain conditional registration, the acquire/usage/pending semantics, and diagnose pool exhaustion.

for a principal

Design capacity/leak alerting from pool timers and combine logback error-rate with 5xx as an SLO signal.

## DataSource / connection-pool metrics ### Generic JDBC `org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration` binds every `DataSource` bean (that has a `DataSourcePoolMetadataProvider`) and registers: - `jdbc.connections.active` (in use), `jdbc.connections.idle`, `jdbc.connections.max`, `jdbc.connections.min`. Tagged by `name` = the datasource bean name (e.g. `dataSource`). This layer works for Hikari, Tomcat JDBC, DBCP2 etc. via metadata providers. ### HikariCP-specific When the pool is **HikariCP** (the Boot default), Boot registers `MicrometerMetricsTrackerFactory` on the `HikariDataSource`, exposing richer, Hikari-native meters (prefix `hikaricp.connections`): - Gauges: `hikaricp.connections` (total), `.active`, `.idle`, `.pending` (threads waiting for a connection), `.max`, `.min`. - Timers/summaries: `hikaricp.connections.acquire` (time a caller waited to obtain a connection), `hikaricp.connections.usage` (how long a connection was held/checked out), `hikaricp.connections.creation` (time to physically open a new connection). - Counter: `hikaricp.connections.timeout` (acquisitions that timed out). Tagged by `pool` = Hikari pool name. **What they tell you**: `pending` and `acquire` timer rising = the pool is a bottleneck (too small, or connections held too long / leaked). `usage` p99 high = slow queries or connections not returned promptly. `timeout` counter climbing = requests failing to get a connection within `connectionTimeout`. `active` near `max` sustained = under-provisioned pool. **Gotcha**: you can get BOTH `jdbc.connections.*` and `hikaricp.connections.*` for the same pool — pick the Hikari ones for depth. Also, if you build the DataSource in an unusual way (not the auto-configured Hikari bean, or wrap it so Boot can't unwrap the `HikariDataSource`), the Hikari metrics may not attach. ## logback.events `io.micrometer.core.instrument.binder.logging.LogbackMetrics` is auto-registered when Logback is the logging backend (the Boot default). It programmatically adds a `TurboFilter` to the `LoggerContext` that increments a **Counter** named `logback.events` on every logging event, tagged `level` = `error|warn|info|debug|trace`. - Use: `rate(logback_events_total{level="error"}[5m])` is an instant, backend-agnostic 'error spike' alert without parsing logs. - Gotcha: it counts events that pass the logger's effective level — DEBUG lines suppressed by config aren't counted. If you swap Logback for Log4j2, this binder is absent (there isn't a drop-in equivalent auto-registered the same way). If you build a custom `LoggerContext`, the filter may need manual attachment. ## Enabling/seeing them Expose the endpoints and browse: `GET /actuator/metrics/hikaricp.connections.pending`, `GET /actuator/metrics/logback.events?tag=level:error`. In Prometheus: `hikaricp_connections_pending`, `logback_events_total{level="error"}`. ## When to use - Pool metrics: capacity planning + detecting connection leaks / slow queries; alert on pending>0 and timeout rate. - logback.events: a lightweight ERROR-rate SLO signal complementing http.server.requests 5xx.

  • hikaricp.connections.pending is consistently above zero under load. What does it indicate and what do you check?
    Threads are waiting to borrow a connection — the pool is a bottleneck. Check hikaricp.connections.active near max (pool too small), hikaricp.connections.usage/acquire timers (connections held too long or leaked), and slow queries. Fixes: enlarge maximumPoolSize, shorten transactions, find leaks (leakDetectionThreshold).
  • You switched logging to Log4j2 and logback.events disappeared. Why, and what now?
    LogbackMetrics binds specifically to the Logback LoggerContext; it isn't registered when Logback isn't the backend, and there's no auto-registered Log4j2 equivalent. You'd add a custom appender/binder or rely on log-pipeline-side error counting instead.

saying these in an interview costs you the question

  • Claiming hikaricp metrics appear even without HikariCP on the classpath
  • Thinking logback.events is a Gauge of current log level rather than a per-level Counter of events
  • Assuming pool metrics register unconditionally with no DataSource bean
  • Confusing hikaricp.connections.usage (checkout duration) with query execution time

context