Skip to content

Commit

Permalink
HH-217466 monkey patch otel find route
Browse files Browse the repository at this point in the history
  • Loading branch information
712u3 committed May 28, 2024
1 parent 5f215f8 commit 0fc7e6f
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 6 deletions.
13 changes: 13 additions & 0 deletions frontik/integrations/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import TYPE_CHECKING, Optional
from urllib.parse import urlparse

import opentelemetry.instrumentation.fastapi
from http_client import client_request_context, response_status_code_context
from http_client.options import options as http_client_options
from opentelemetry import trace
Expand All @@ -19,6 +20,7 @@
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import SpanKind
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from starlette.types import Scope

from frontik import request_context
from frontik.integrations import Integration, integrations_logger
Expand Down Expand Up @@ -51,6 +53,15 @@ def on_end(self, span: ReadableSpan) -> None:
super().on_end(span=span)


def monkey_patch_route_details(scope: Scope) -> tuple:
route = scope['path']
span_name = route or scope.get('method', '')
attributes = {}
if route:
attributes[SpanAttributes.HTTP_ROUTE] = route
return span_name, attributes


class TelemetryIntegration(Integration):
def __init__(self):
self.aiohttp_instrumentor = aiohttp_client.AioHttpClientInstrumentor()
Expand All @@ -59,6 +70,8 @@ def initialize_app(self, app: FrontikApplication) -> Optional[Future]:
if not options.opentelemetry_enabled:
return None

opentelemetry.instrumentation.fastapi._get_route_details = monkey_patch_route_details

integrations_logger.info('start telemetry')

resource = Resource(
Expand Down
5 changes: 2 additions & 3 deletions frontik/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def make_not_found_response(frontik_app, path):


class RoutingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, _call_next: Callable) -> Response:
async def dispatch(self, request: Request, _ignored_call_next: Callable) -> Response:
request.state.start_time = time.time()

routing_logger.info('requested url: %s', request.url.path)
Expand All @@ -201,8 +201,6 @@ async def dispatch(self, request: Request, _call_next: Callable) -> Response:
check_request_id(request_id)

with request_context.request_context(request, request_id):
request.state.body_bytes = await request.body()

route: APIRoute
route, page_cls = _plain_routes.get((request.url.path, request.method), (None, None))
request.state.path_params = {}
Expand All @@ -215,6 +213,7 @@ async def dispatch(self, request: Request, _call_next: Callable) -> Response:
routing_logger.error('match for request url %s "%s" not found', request.method, request.url.path)
return make_not_found_response(request.app.frontik_app, request.url.path)

request.state.body_bytes = await request.body()
_setup_page_handler(request, page_cls)

response = await process_request(request, route.get_route_handler(), route)
Expand Down
3 changes: 2 additions & 1 deletion frontik/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ def run_server(frontik_app: FrontikApplication, sock: Optional[socket.socket] =
for router in routers:
fastapi_app.include_router(router)

fastapi_app.user_middleware.insert(1, Middleware(RoutingMiddleware))
# because on idx=0 we have OpenTelemetryMiddleware
fastapi_app.user_middleware.insert(1, Middleware(RequestCancelledMiddleware))
fastapi_app.user_middleware.insert(1, Middleware(RoutingMiddleware)) # should be last, because it ignores call_next

config = uvicorn.Config(
fastapi_app,
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ python-consul2-hh = {git = 'https://github.com/hhru/python-consul2', tag = 'v0.2
opentelemetry-sdk = '1.17.0'
opentelemetry-api = '1.17.0'
opentelemetry-exporter-otlp-proto-grpc = '1.17.0'
opentelemetry-instrumentation-fastapi = '0.38b0'
opentelemetry-instrumentation-fastapi = '0.38b0' # check monkey patches on update
opentelemetry-instrumentation-aiohttp-client = '0.38b0'
fastapi = '0.105.0'
aiokafka = '0.8.1'
sentry-sdk = '2.1.1'
aioresponses = '0.7.4'
tornado-httpclient-mock = '0.2.3'
uvicorn = '0.29.0'
uvicorn = '0.29.0' # check server_run on update

[tool.poetry.group.test.dependencies]
pytest = '8.1.1'
Expand Down

0 comments on commit 0fc7e6f

Please sign in to comment.