trallnag / prometheus-fastapi-instrumentator

Instrument your FastAPI with Prometheus metrics.
ISC License
948 stars 84 forks source link

fix: Remove unnecessary body aggregation #233

Closed bbeattie-phxlabs closed 1 year ago

bbeattie-phxlabs commented 1 year ago

Collection of body content doesn't matter much when the response size is under a few megs, but when a response is a FileResponse beyond a couple hundred megs, it really starts to matter.

Considering response.body isn't used in any metrics in metrics.py, I'd suggest removing its collection altogether.

bbeattie-phxlabs commented 1 year ago

Hmm... I see this was added in for https://github.com/trallnag/prometheus-fastapi-instrumentator/pull/203. I wonder if the better approach here would be to customize the send_wrapper based on a PrometheusInstrumentatorMiddleware instance variable, allowing this body aggregation for those that choose to enable it, or disabled for those that choose to disable it, depending on the approach.

trallnag commented 1 year ago

I prefer adding another feature flag instead of removing it altogether. Not sure yet if to go with opt-in or opt-out. The former implies a breaking change.

Also note to myself: Document this performance impact in a disclaimer in the main readme.

codecov[bot] commented 1 year ago

Codecov Report

Merging #233 (42201fb) into master (241229b) will increase coverage by 0.25%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #233      +/-   ##
==========================================
+ Coverage   95.29%   95.54%   +0.25%     
==========================================
  Files           5        5              
  Lines         340      337       -3     
==========================================
- Hits          324      322       -2     
+ Misses         16       15       -1     
Impacted Files Coverage Δ
...rc/prometheus_fastapi_instrumentator/middleware.py 97.67% <ø> (+1.04%) :arrow_up:
src/prometheus_fastapi_instrumentator/__init__.py 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

bbeattie-phxlabs commented 1 year ago

Yep, an understandable approach! https://github.com/trallnag/prometheus-fastapi-instrumentator/compare/master...bbeattie-phxlabs:bbeattie-phxlabs-patch-2?expand=1 is a second branch I've just created. It feature-flags body aggregation behind a body_metric_handlers feature flag, defaulting to off.

I'd argue that default behaviour shouldn't include response body aggregation as it unnecessarily impacts performance in the default use case (unless you've included some custom metrics that make use of response body content).

Anywho, it lead to an interesting "why is my multigigabyte download slowing down to a crawl?" Just happy to have found the source!

trallnag commented 1 year ago

Interesting, the info.response.body wasn't even working properly.

from fastapi import FastAPI
from prometheus_fastapi_instrumentator import Instrumentator, metrics

app = FastAPI()

@app.get("/ping")
def get_ping():
    return "pong" * 10000000

def instrumentation(info: metrics.Info) -> None:
    print("Length of response body: " + str(len(info.response.body)))

Instrumentator().instrument(app).add(instrumentation)

Will always show a body size of 0. Probably it currently only works for responses where data is streamed. I will first fix that and then come back to this issue here.

trallnag commented 1 year ago

Closing because moving it behind feature flag is preferred.

trallnag commented 1 year ago

@bbeattie-phxlabs, see https://github.com/trallnag/prometheus-fastapi-instrumentator/releases/tag/v6.0.0