69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
from time import perf_counter
|
|
|
|
from adapter.http.fastapi.dependencies import get_container
|
|
from fastapi import FastAPI, Request, Response
|
|
|
|
REQUEST_COUNT = 'http.server.request.count'
|
|
REQUEST_DURATION = 'http.server.request.duration'
|
|
|
|
|
|
def register_middleware(app: FastAPI) -> None:
|
|
@app.middleware('http')
|
|
async def request_logging_middleware(
|
|
request: Request,
|
|
call_next,
|
|
) -> Response:
|
|
start = perf_counter()
|
|
status_code = 500
|
|
|
|
try:
|
|
response = await call_next(request)
|
|
status_code = response.status_code
|
|
return response
|
|
finally:
|
|
duration_ms = (perf_counter() - start) * 1000
|
|
container = get_container(request)
|
|
container.observability.logger.info(
|
|
'http_request',
|
|
attrs={
|
|
'http.method': request.method,
|
|
'http.path': request.url.path,
|
|
'http.status_code': status_code,
|
|
'http.duration_ms': duration_ms,
|
|
},
|
|
)
|
|
|
|
@app.middleware('http')
|
|
async def metrics_middleware(
|
|
request: Request,
|
|
call_next,
|
|
) -> Response:
|
|
start = perf_counter()
|
|
status_code = 500
|
|
|
|
try:
|
|
response = await call_next(request)
|
|
status_code = response.status_code
|
|
return response
|
|
finally:
|
|
duration_ms = (perf_counter() - start) * 1000
|
|
container = get_container(request)
|
|
attrs: dict[str, str | int] = {
|
|
'http.method': request.method,
|
|
'http.path': _metric_path(request),
|
|
'http.status_code': status_code,
|
|
}
|
|
container.observability.metrics.increment(REQUEST_COUNT, attrs=attrs)
|
|
container.observability.metrics.record(
|
|
REQUEST_DURATION,
|
|
duration_ms,
|
|
attrs=attrs,
|
|
)
|
|
|
|
|
|
def _metric_path(request: Request) -> str:
|
|
route = request.scope.get('route')
|
|
path = getattr(route, 'path', None)
|
|
if isinstance(path, str) and path:
|
|
return path
|
|
return 'unmatched'
|