jerryshao opened a new issue, #12944:
URL: https://github.com/apache/gravitino/issues/12944

   ### Version
   
   main branch
   
   ### Describe what's wrong
   
   Request-duration timers — both the Jersey `@Timed` HTTP-duration timers 
(`gravitino-server`, `iceberg-rest-server`) and the AspectJ `@Monitored` method 
timers (`gravitino-relational-store`) — report `mean`/`p95`/`p99`/`max` as 
`0.0` for any endpoint that hasn't been called within the reservoir's sliding 
window (`gravitino.metrics.timeSlidingWindowSecs`, default 60s) at the moment 
`/metrics` is scraped, even though `count` keeps incrementing correctly. In 
practice, this affects nearly every real API endpoint, since most operations 
aren't called at least once every 60 seconds, making `/metrics` unusable for 
latency alerting or slow-operation investigation.
   
   ### Error message and/or stacktrace
   
   N/A — this is a silent data-correctness issue, not a crash. `/metrics` 
returns valid Prometheus output; the duration values within it are just wrong 
(zero) for low-frequency series.
   
   ### How to reproduce
   
   1. Start a Gravitino server with default metrics config.
   2. Call a REST endpoint that isn't hit frequently (e.g. `GET 
/api/metalakes/{metalake}/catalogs/{catalog}` to load a catalog) a few times.
   3. Wait longer than `gravitino.metrics.timeSlidingWindowSecs` (default 60s) 
without calling that endpoint again.
   4. Scrape `GET /metrics`.
   5. Observe: the corresponding timer (e.g. 
`gravitino-server.load-catalog.http-request-duration-seconds`) shows a nonzero 
`count` but `mean`/`p95`/`p99`/`max` all read `0.0`.
   
   ### Additional context
   
   Root cause: `MetricsSource.getTimer()`/`getHistogram()` 
(`core/src/main/java/org/apache/gravitino/metrics/source/MetricsSource.java`) 
and `HttpServerMetricsSource` 
(`server-common/src/main/java/org/apache/gravitino/server/web/HttpServerMetricsSource.java`)
 back every timer with `com.codahale.metrics.SlidingTimeWindowArrayReservoir`. 
Its `getSnapshot()` calls `trim()` first, discarding any sample older than the 
window; if nothing lands inside the window, the snapshot is built from an empty 
array, and dropwizard's `UniformSnapshot` hard-codes `0.0`/`0` for 
`getMean()`/`getMax()`/`getValue(quantile)` when there are no values. `count` 
comes from `Histogram`'s own separate, never-expiring `LongAdder`, so it's 
unaffected and stays accurate while every duration statistic reads zero — 
durations are captured correctly at write time and simply discarded before they 
can be read back.
   
   Options:
   - Short-term mitigation: increase `gravitino.metrics.timeSlidingWindowSecs` 
— reduces how often this triggers, but any endpoint called less often than the 
configured window will still eventually read zero, and a larger window 
increases reservoir memory for high-traffic endpoints.
   - Real fix: switch the reservoir type to one that doesn't hard-expire to 
empty on low-traffic endpoints, e.g. `ExponentiallyDecayingReservoir` 
(dropwizard's own default) or `SlidingWindowReservoir(N)` (fixed sample count, 
no time-based eviction). This changes the statistical semantics of exposed 
percentiles/mean/max (no longer a strict "last N seconds" window), so it should 
be called out as an intentional behavior change rather than a silent tweak.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to