Summary
Hello,
I'm interested into improving the prometheus metrics system of litestar and work on a PR.
Let me explain the problem I'm trying to solve.
So I want to use the /metrics endpoint, but the issue I have is that it's registering every requests even the one I don't need to have, it clutter my time series
For exemple, when quering a route with random or bad params in the URL with 404 responses, it register the calls which is useless and clutter the monitoring data.
It can be a problem because it increase the active time series number in my prometheus server and create high cardinality labels.
So we need to implement some way to control the potential cardinality explosion.
Currently there is a exclude_unhandled_paths setting in litestar.contrib.prometheus.PrometheusConfig which should not register metrics when a the server respond a 404.
But, apparently it does nothing currently, it's unimplemented.
So my proposal is to work on these issues:
Have a way to ignore 404 calls,
For that we can implement the exclude_unhandled_paths setting, to not register metrics when a call return 404. All others status code can be interesting.
May be we can replace this setting by exclude_status_code so it can be more configurable and we allow the user to exclude others status codes like 400 for example.
Have a way to specify which params in a URL are worth registering
We can implement a route_keep_params setting for each route, there is 2 way that I see to do that:
Add a MetricParameter in Annotated with a include option. We can make the default value configurable.
So what are your thoughts on this? Feedback and critics appreciated.
Basic Example
Example of endpoint config, adding a meta data in the Annotated type to tell the metrics handler to include or ignore a param:
from typing_extensions import Annotated
from litestar.params import Parameter
THINGS = …
@get(path="/thing/{category:str}/{uuid:int}", sync_to_thread=False)
def get_product_version(
category: Annotated[
str,
Parameter(
title="Category slug",
),
MetricParameter(include = True),
],
uuid: Annotated[
str,
Parameter(
title="Thing UUID",
),
MetricParameter(ignore = True),
],
) -> thing:
return THINGS[category][uuid]
So if I'm making a request GET /thing/bike/1
then a request GET /thing/bike/2, then a request GET /thing/house/1
before this feature I'm getting in the /metrics:
requests_total{method="GET", path="/thing/bike/1"}
requests_total{method="GET", path="/thing/bike/2"}
requests_total{method="GET", path="/thing/house/1"}
```...