-
Notifications
You must be signed in to change notification settings - Fork 685
Warning triggered by asgi.OpenTelemetryMiddleware #1335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What command do you run to execute the code? |
@sanketmehta28 we use the command Both commands produce one warning at startup for each of the |
@sk- |
Thanks @TheAnshul756 that pointed me to the right direction. I managed to create a small reproduction case import fastapi
from fastapi.exception_handlers import http_exception_handler
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
from opentelemetry.metrics import set_meter_provider
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
app = fastapi.FastAPI()
# OTEL Middleware
app.add_middleware(OpenTelemetryMiddleware)
# OTEL Setup
reader = PeriodicExportingMetricReader(ConsoleMetricExporter(), 3000)
provider = MeterProvider(
metric_readers=[reader],
)
set_meter_provider(provider)
# Exception handler
@app.exception_handler(fastapi.HTTPException)
async def custom_http_exception_handler(
request: fastapi.Request, e: fastapi.HTTPException
) -> fastapi.responses.JSONResponse:
return await http_exception_handler(request, e) The culprit seems to be the order in which things are being done. If I move the Below are all the combinations and whether it works:
The problem is that calling I think it's not ideal that the |
Yes, the warning is from the creation of metric data models, and there is nothing wrong with initialising the middleware again and again. The model creation method throws a warning if there is already an existing data model with the same name, unit and detail and does not create another, which is the expected behaviour. @srikanthccv what do you think? |
Documenting this behavior would be ideal for this issue. We don't want to introduce additional things to API interface unless necessary. |
After seeing this warning myself I did my own investigation and the only thing I will add is that this is happening because of how Starlette (the core of FastAPI) manages middleware. It looks like it'll probably be fixed in a future release. If you're curious, the old def add_middleware(
self, middleware_class: type, **options: typing.Any
) -> None: # pragma: no cover
self.user_middleware.insert(0, Middleware(middleware_class, **options))
self.middleware_stack = self.build_middleware_stack() As a result, each time middleware is added def add_middleware(self, middleware_class: type, **options: typing.Any) -> None:
if self.middleware_stack is not None: # pragma: no cover
raise RuntimeError("Cannot add middleware after an application has started")
self.user_middleware.insert(0, Middleware(middleware_class, **options)) |
Describe your environment
Python: 3.10.7
opentelemetry-instrumentation-asgi: 0.33b0
opentelemetry-api 1.12.0
Fastapi: 0.79.0
Steps to reproduce
Setup the asgi middleware with fastapi as following:
What is the expected behavior?
We should not see any warnings.
What is the actual behavior?
The following warning is raised multiple times.
Additional context
Seems to be related to open-telemetry/opentelemetry-python#2558. This is the code triggering the issue
https://github.com/open-telemetry/opentelemetry-python/blob/75313b6c6d58945c1401622b6683ccdd28657984/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py#L195-L202
I imagine that somehow FastAPI is creating multiple instances of the middleware, and hence the instruments are created multiple times.
Labels: asgi, warning, fastapi
The text was updated successfully, but these errors were encountered: