Skip to content

Multi-App Observability Setup

Services that run multiple FastAPI apps (e.g. an API service on port 8000 and an upload service on port 8001) need each app independently instrumented. configure_app_observability does both steps — middleware and metrics endpoint — in a single call.

Quick Start

Python
from fastapi import FastAPI
from obskit import configure_observability
from obskit.middleware.instrument import configure_app_observability

obs = configure_observability(service_name="upload-service")

upload_app = FastAPI(title="upload-service")
configure_app_observability(upload_app, exclude_paths=["/v2/_healthy"])

This is equivalent to:

Python
from obskit import instrument_fastapi
from obskit.metrics.registry import generate_latest
from starlette.requests import Request
from starlette.responses import Response

instrument_fastapi(upload_app, exclude_paths=["/v2/_healthy"])

@upload_app.get("/metrics", include_in_schema=False)
async def metrics(request: Request) -> Response:
    return Response(generate_latest(), media_type="text/plain; version=0.0.4")

Parameters

Parameter Default Description
app The FastAPI application.
exclude_paths middleware defaults Paths excluded from observability.
track_metrics True Enable RED metrics.
track_logging True Enable request/response logging.
track_tracing True Enable distributed tracing.
metrics_path "/metrics" URL path for the Prometheus scrape endpoint.

Custom Metrics Path

Python
configure_app_observability(upload_app, metrics_path="/internal/metrics")

API Reference

obskit.middleware.instrument.configure_app_observability

Python
configure_app_observability(
    app: Any,
    *,
    exclude_paths: list[str] | None = None,
    track_metrics: bool = True,
    track_logging: bool = True,
    track_tracing: bool = True,
    metrics_path: str = "/metrics",
    context_extractor: Any | None = None,
) -> None

Add :class:~obskit.middleware.fastapi.ObskitMiddleware and a Prometheus scrape endpoint to a FastAPI application in a single call.

Equivalent to calling :func:instrument_fastapi and manually registering a /metrics route — useful when running two or more FastAPI apps (e.g. an API service and an upload service) that each need full observability.

Parameters

app : FastAPI The FastAPI application to configure. exclude_paths : list[str], optional Paths excluded from middleware observability. Defaults to the :class:~obskit.middleware.core.MiddlewareCore defaults. track_metrics : bool Enable RED metrics collection. Default: True. track_logging : bool Enable structured request/response logging. Default: True. track_tracing : bool Enable distributed tracing. Default: True. metrics_path : str URL path for the Prometheus scrape endpoint. Default: "/metrics". context_extractor : callable, optional Forwarded to :class:~obskit.middleware.fastapi.ObskitMiddleware. Receives decoded request headers; returns extra log-context key/value pairs.

Example

::

Text Only
from obskit.middleware.instrument import configure_app_observability

upload_app = FastAPI(title="upload-service")
configure_app_observability(upload_app, exclude_paths=["/v2/_healthy"])
# ObskitMiddleware + GET /metrics are now registered on upload_app
Source code in src/obskit/middleware/instrument.py
Python
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def configure_app_observability(
    app: Any,
    *,
    exclude_paths: list[str] | None = None,
    track_metrics: bool = True,
    track_logging: bool = True,
    track_tracing: bool = True,
    metrics_path: str = "/metrics",
    context_extractor: Any | None = None,
) -> None:
    """Add :class:`~obskit.middleware.fastapi.ObskitMiddleware` and a Prometheus
    scrape endpoint to a FastAPI application in a single call.

    Equivalent to calling :func:`instrument_fastapi` and manually registering
    a ``/metrics`` route — useful when running two or more FastAPI apps (e.g.
    an API service and an upload service) that each need full observability.

    Parameters
    ----------
    app : FastAPI
        The FastAPI application to configure.
    exclude_paths : list[str], optional
        Paths excluded from middleware observability.  Defaults to the
        :class:`~obskit.middleware.core.MiddlewareCore` defaults.
    track_metrics : bool
        Enable RED metrics collection.  Default: ``True``.
    track_logging : bool
        Enable structured request/response logging.  Default: ``True``.
    track_tracing : bool
        Enable distributed tracing.  Default: ``True``.
    metrics_path : str
        URL path for the Prometheus scrape endpoint.  Default: ``"/metrics"``.
    context_extractor : callable, optional
        Forwarded to :class:`~obskit.middleware.fastapi.ObskitMiddleware`.
        Receives decoded request headers; returns extra log-context key/value pairs.

    Example
    -------
    ::

        from obskit.middleware.instrument import configure_app_observability

        upload_app = FastAPI(title="upload-service")
        configure_app_observability(upload_app, exclude_paths=["/v2/_healthy"])
        # ObskitMiddleware + GET /metrics are now registered on upload_app
    """
    instrument_fastapi(
        app,
        exclude_paths=exclude_paths,
        track_metrics=track_metrics,
        track_logging=track_logging,
        track_tracing=track_tracing,
        context_extractor=context_extractor,
    )

    from starlette.responses import Response  # noqa: PLC0415

    from obskit.metrics.registry import generate_latest  # noqa: PLC0415

    async def _metrics() -> Response:
        data = generate_latest()
        return Response(
            content=data,
            media_type="text/plain; version=0.0.4; charset=utf-8",
        )

    app.add_api_route(metrics_path, _metrics, include_in_schema=False)