Estoy tratando de agregar métricas en servicios externos con aioprometheus en una aplicación creada con FastAPI . Aquí hay un ejemplo simplificado de lo que estoy tratando de lograr.
Digamos que tengo una clase de aplicación contenedora como tal:
from aioprometheus import Registry, Counter, Histogram from fastapi import FastAPI class App: def __init__(self, ...): self.registry = Registry() self.counter = Counter( name="counts", doc="request counts" ) self.latency = Histogram( name="latency", doc="request latency", buckets=[0.1, 0.5, 1, 1.5, 2] ) self.app = FastAPI() self._metrics() def _metrics(self): # Counter metrics @self.app.middleware("http") async def counter_metrics(request, call_next): response = await call_next(request) self.counter.inc( {"path": str(request.url.path), "status": response.status_code} ) return response # Latency metrics @self.app.middleware("http") async def latency_metrics(request, call_next): start = time.time() response = await call_next(request) total_duration = time.time() - start self.latency.observe( {"path": str(request.url.path)}, total_duration ) return response @self.app.on_event("startup") async def startup(): self.app.include_router(some_router(...)) self.registry.register(self.counter) self.registry.register(self.latency) Básicamente, tengo Registry , Counter e Histogram iniciados. En _metrics , tengo lógicas específicas de Counter e Histogram que luego se agregan al Registry . Esto hará su magia y capturará las métricas cuando se llame a un punto final en some_router (¡esto es bueno! Me gustaría mantener esto además de tener las métricas de servicios externos).
Sin embargo, supongamos que llamo a un servicio externo desde some_router como tal:
from fastapi import APIRouter def some_router(): router = APIRouter() @router.get("/some_router") async def some_router(): response = await external_service() return response return router En este caso, ¿cómo agregaría métricas específicamente a external_service ? es decir, ¿Latencia de este servicio externo específico?
De acuerdo con la documentación , deberá adjuntar sus métricas a la instancia de la aplicación ( app.state ), para que se pueda acceder fácilmente a ellas en el controlador de ruta, ya que las métricas a menudo se crean en un módulo diferente de donde se usan (como en Tu caso). Por lo tanto, podría tener lo siguiente en su clase de App , después de instanciar las métricas:
self.app.state.registry = registry self.app.state.counter = counter self.app.state.latency = latency En su módulo de enrutadores, puede obtener la instancia de la app utilizando el objeto Request , como se describe aquí y aquí , y luego usarlo para obtener las instancias de métricas (como se muestra a continuación), lo que le permitirá agregar métricas a su external_service :
from fastapi import Request ... @router.get("/some_router") async def some_router(request: Request): registry = request.app.state.registry counter = request.app.state.counter latency = request.app.state.latency response = await external_service() return response