Skip to content

Commit

Permalink
Merge 03ca1f0 into dbf81d1
Browse files Browse the repository at this point in the history
  • Loading branch information
hkethi002 committed Aug 17, 2021
2 parents dbf81d1 + 03ca1f0 commit 2240aa0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
22 changes: 21 additions & 1 deletion starlette_opentracing/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@
from opentracing import InvalidCarrierException, SpanContextCorruptedException
from opentracing.ext import tags
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request


class StarletteTracingMiddleWare(BaseHTTPMiddleware):
def __init__(self, app, tracer):
def __init__(self, app, tracer, use_template: bool = False):
# Todo: add choice between global tracer and tracer that is already configured
super().__init__(app)
self._tracer = tracer
self.use_template = use_template

def get_template(self, request: Request) -> str:
"""Get the template for the route endpoint."""
method = request.method
urls = [
route
for route in request.scope["router"].routes
if hasattr(route, "endpoint") and
"endpoint" in request.scope and
route.endpoint == request.scope["endpoint"]
]
template = urls[0].path if len(urls) > 0 else "UNKNOWN"
method_path = method + " " + template
return method_path

async def dispatch(self, request, call_next):
span_ctx = None
Expand Down Expand Up @@ -38,4 +54,8 @@ async def dispatch(self, request, call_next):
span.set_tag(tags.HTTP_URL, url)

response = await call_next(request)

if self.use_template:
operation_name = self.get_template(request)
span.set_operation_name(operation_name)
return response
18 changes: 18 additions & 0 deletions tests/test_tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,21 @@ def foo(request):
# Todo: more asserts; still not sure if we should have 3 finished spans in the external tracer
spans = external_tracer.finished_spans()
assert len(spans) == 1


def test_tracer_uses_path_templates_for_operation_names():
app = Starlette()
mocked_tracer = MockTracer(scope_manager=ContextVarsScopeManager())
app.add_middleware(
StarletteTracingMiddleWare, tracer=mocked_tracer, use_template=True
)

@app.route("/foo/{foo_id}")
def foo(foo_id: str):
return PlainTextResponse(f"Foo: {foo_id}")

client = TestClient(app)
client.get("/foo/MyFoo")
spans = mocked_tracer.finished_spans()
assert len(spans) == 1
assert spans[0].operation_name == "GET /foo/{foo_id}"

0 comments on commit 2240aa0

Please sign in to comment.