@@ -227,7 +227,7 @@ def instrument_app(
227
227
app .add_middleware (
228
228
OpenTelemetryMiddleware ,
229
229
excluded_urls = excluded_urls ,
230
- default_span_details = _get_route_details ,
230
+ default_span_details = _get_default_span_details ,
231
231
server_request_hook = server_request_hook ,
232
232
client_request_hook = client_request_hook ,
233
233
client_response_hook = client_response_hook ,
@@ -300,7 +300,7 @@ def __init__(self, *args, **kwargs):
300
300
self .add_middleware (
301
301
OpenTelemetryMiddleware ,
302
302
excluded_urls = _InstrumentedFastAPI ._excluded_urls ,
303
- default_span_details = _get_route_details ,
303
+ default_span_details = _get_default_span_details ,
304
304
server_request_hook = _InstrumentedFastAPI ._server_request_hook ,
305
305
client_request_hook = _InstrumentedFastAPI ._client_request_hook ,
306
306
client_response_hook = _InstrumentedFastAPI ._client_response_hook ,
@@ -315,27 +315,51 @@ def __del__(self):
315
315
_InstrumentedFastAPI ._instrumented_fastapi_apps .remove (self )
316
316
317
317
318
- def _get_route_details (scope ):
319
- """Callback to retrieve the fastapi route being served.
318
+ def _get_default_span_details (scope ):
319
+ """
320
+ Callback to retrieve span name and attributes from scope.
321
+
322
+ Args:
323
+ scope: A Starlette scope
324
+ Returns:
325
+ A tuple of span name and attributes
326
+ """
327
+ route = _get_route_details (scope )
328
+ method = scope .get ("method" , "" )
329
+ attributes = {}
330
+ if route :
331
+ attributes [SpanAttributes .HTTP_ROUTE ] = route
332
+ if method and route : # http
333
+ span_name = f"{ method } { route } "
334
+ elif route : # websocket
335
+ span_name = route
336
+ else : # fallback
337
+ span_name = method
338
+ return span_name , attributes
339
+
320
340
341
+ def _get_route_details (scope ):
342
+ """
343
+ Function to retrieve Starlette route from scope.
344
+
321
345
TODO: there is currently no way to retrieve http.route from
322
346
a starlette application from scope.
323
-
324
347
See: https://github.com/encode/starlette/pull/804
348
+
349
+ Args:
350
+ scope: A Starlette scope
351
+ Returns:
352
+ A string containing the route or None
325
353
"""
326
354
app = scope ["app" ]
327
355
route = None
356
+
328
357
for starlette_route in app .routes :
329
358
match , _ = starlette_route .matches (scope )
330
359
if match == Match .FULL :
331
360
route = starlette_route .path
332
361
break
333
362
if match == Match .PARTIAL :
334
363
route = starlette_route .path
335
- # method only exists for http, if websocket
336
- # leave it blank.
337
- span_name = route or scope .get ("method" , "" )
338
- attributes = {}
339
- if route :
340
- attributes [SpanAttributes .HTTP_ROUTE ] = route
341
- return span_name , attributes
364
+ return route
365
+
0 commit comments