[Python] How to add metrics to external services using aioprometheus and FastAPI?

Discussão em 'Python' iniciado por Stack, Dezembro 21, 2024.

  1. Stack

    Stack Membro Participativo

    I'm trying to add metrics to external services with aioprometheus in a FastAPI app. Here is a simplified example of what I'm trying to achieve.

    Let's say, I have a wrapper App class as such:

    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)


    Basically, I have Registry, Counter, and Histogram initiated. In _metrics, I have Counter and Histogram specific logics that are later added to Registry. This will do its magic and catch the metrics when an endpoint in some_router is called (I would want to keep this, as well as have the external service metrics).

    However, let's say, I call an external service from some_router as such:

    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


    In this case, how would I add metrics specifically to external_service, i.e., Latency of this specific external service?

    Continue reading...

Compartilhe esta Página