diff --git a/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py b/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py index 37a3a0e9e0d..e0786a92e5a 100644 --- a/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py +++ b/ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/__init__.py @@ -142,12 +142,8 @@ def add_response_attributes( def get_default_span_name(environ): - """Calculates a (generic) span name for an incoming HTTP request based on the PEP3333 conforming WSGI environ.""" - - # TODO: Update once - # https://github.com/open-telemetry/opentelemetry-specification/issues/270 - # is resolved - return environ.get("PATH_INFO", "/") + """Default implementation for name_callback, returns HTTP {METHOD_NAME}.""" + return "HTTP " + environ.get("REQUEST_METHOD") class OpenTelemetryMiddleware: @@ -158,11 +154,15 @@ class OpenTelemetryMiddleware: Args: wsgi: The WSGI application callable to forward requests to. + name_callback: Callback which calculates a generic span name for an + incoming HTTP request based on the PEP3333 WSGI environ. + Optional: Defaults to get_default_span_name. """ - def __init__(self, wsgi): + def __init__(self, wsgi, name_callback=None): self.wsgi = wsgi self.tracer = trace.get_tracer(__name__, __version__) + self.name_callback = name_callback or get_default_span_name @staticmethod def _create_start_response(span, start_response): @@ -182,7 +182,7 @@ def __call__(self, environ, start_response): """ parent_span = propagators.extract(get_header_from_environ, environ) - span_name = get_default_span_name(environ) + span_name = self.name_callback(environ) span = self.tracer.start_span( span_name, diff --git a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py index 1912dd0079f..1a0a5e7ddfe 100644 --- a/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py +++ b/ext/opentelemetry-ext-wsgi/tests/test_wsgi_middleware.py @@ -74,7 +74,7 @@ def error_wsgi(environ, start_response): class TestWsgiApplication(WsgiTestBase): - def validate_response(self, response, error=None): + def validate_response(self, response, error=None, span_name="HTTP GET"): while True: try: value = next(response) @@ -95,7 +95,7 @@ def validate_response(self, response, error=None): span_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(span_list), 1) - self.assertEqual(span_list[0].name, "/") + self.assertEqual(span_list[0].name, span_name) self.assertEqual(span_list[0].kind, trace_api.SpanKind.SERVER) self.assertEqual( span_list[0].attributes, @@ -147,6 +147,17 @@ def test_wsgi_exc_info(self): response = app(self.environ, self.start_response) self.validate_response(response, error=ValueError) + def test_override_span_name(self): + """Test that span_names can be overwritten by our callback function.""" + span_name = "Dymaxion" + def get_predefined_span_name(scope): + return span_name + app = otel_wsgi.OpenTelemetryMiddleware( + simple_wsgi, name_callback=get_predefined_span_name + ) + response = app(self.environ, self.start_response) + self.validate_response(response, span_name=span_name) + class TestWsgiAttributes(unittest.TestCase): def setUp(self):