Conversation
a324275 to
a5e1429
Compare
|
Realized that the I think it's because the endpoint path is defined as a pattern, trying to see how I can add a custom label for |
|
Converting the PR to draft while I address the issue above, so no need for reviews in the meantime. |
1a795a4 to
da94518
Compare
| def _extract_project_name(request: Request): | ||
| project_name = None | ||
| prefix = "/api/project/" | ||
| if request.url.path.startswith(prefix): |
There was a problem hiding this comment.
Instead of manually parsing this out, I wonder if the parsing might already be done for us... anything interesting in the request object, e.g. in path_params?
There was a problem hiding this comment.
No path_params isn't available at the time the middleware is called. Middlewares are executed before FastAPI routes the request to an endpoint, so we only have access to the raw path.
A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it.
There was a problem hiding this comment.
This is the request object when it gets to the middleware:
request.__dict__ {'scope': {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 3000), 'client': ('127.0.0.1', 55612), 'scheme': 'http', 'method': 'POST', 'root_path': '', 'path': '/api/project/main/repos/get', 'raw_path': b'/api/project/main/repos/get', 'query_string': b'', 'headers': [(b'host', b'127.0.0.1:3000'), (b'user-agent', b'python-requests/2.32.3'), (b'accept-encoding', b'gzip, deflate, br'), (b'accept', b'*/*'), (b'connection', b'keep-alive'), (b'authorization', b'Bearer REDACTED'), (b'x-api-version', b'0.0.0'), (b'content-type', b'application/json'), (b'content-length', b'60')], 'state': {}, 'app': <fastapi.applications.FastAPI object at 0x1182e7680>}, '_receive': <function BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.receive_or_disconnect at 0x12b1494e0>, '_send': <function empty_send at 0x1186fbe20>, '_stream_consumed': False, '_is_disconnected': False, '_form': None, '_wrapped_rcv_disconnected': False, '_wrapped_rcv_consumed': False, '_wrapped_rc_stream': <async_generator object Request.stream at 0x12b151380>}
da94518 to
b2cc9b6
Compare
Part of #2736 - adding http metrics.
Chose to implement these metrics as custom rather than relying on standard fastapi metrics via instrumentation libraries. Reason being, we need to label
project_namein order to get metrics at endpoint and project level. Standard libraries likeprometheus-fastapi-instrumentatorandopentelemetry-instrumentation-fastapidon't allow adding custom dynamic labels to their default metrics.Note:
/metricsendpoint.metricsrouter endpoint, and combine them with the custom metrics./metricsendpoint, however the more standard Prometheus way is to register all the metrics usingprometheus_clientwhich uses a global registry to collect the metrics from all the app and takes care of emitting them on the/metricsendpoint.prometheus_clientin part 2 of this ticket for the additional custom metrics, if it makes adding new metrics easier, in which case it might require some refactoring of the existing prometheus metrics code.