spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
55.27k stars 37.62k forks source link

Observation in ServerHttpObservationFilter is never stopped for asynchronous requests #32730

Open wojtassi opened 2 weeks ago

wojtassi commented 2 weeks ago

Spring Framework 6.0.19 CometD 7.0.10 Micrometer 1.12.5

I'm not exactly sure which component is responsible for this issue but since spring-web contains ServerHttpObservationFilter, I am submitting this bug here. We have recently run into a memory leak of DefaultLongTaskTimer$SampleImpl. This was introduced with micrometer introducing histograms for http.server.requests.active.

The leak happens only for requests to CometD and it happens because those requests are asynchronous. In https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/filter/ServerHttpObservationFilter.java:

  1. Observation is created at the start of doFilterInternal.
  2. In synchronous requests, Observation is closed at the end of that function.
  3. For asynchronous requests, Observation is never closed, by design, which was fine until histograms were introduced that use Observation.stop to stop DefaultLongTaskTimer$SampleImpl.
  4. Since Observation is never stopped, we end up with DefaultLongTaskTimer$SampleImpl leak

The problem is that there is no corresponding callback that would close the Observation once asynchronous requests completes.

Thanks,