Repository: open-telemetry/opentelemetry-python-contrib

Issue:
NonRecordingSpan causes errors in wsgi
The following error arises from the `tracecontext` integration tests in the core repo:

```
Traceback (most recent call last):
  File "/Users/alex.ianchici/workspace/opentelemetry-python/.tox/tracecontext/lib/python3.9/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/alex.ianchici/workspace/opentelemetry-python/.tox/tracecontext/src/opentelemetry-instrumentation-wsgi/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py", line 339, in __call__
    if span.kind == trace.SpanKind.SERVER:
AttributeError: 'NonRecordingSpan' object has no attribute 'kind'
```

It appears the problem came from this change: https://github.com/open-telemetry/opentelemetry-python-contrib/commit/2f5bbc416ab33f4856e1990a5e5682fcedc90f5f


Discussion:

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py
@@ -313,7 +313,7 @@ def _create_start_response(span, start_response, response_hook):
         @functools.wraps(start_response)
         def _start_response(status, response_headers, *args, **kwargs):
             add_response_attributes(span, status, response_headers)
-            if span.kind == trace.SpanKind.SERVER:
+            if span.is_recording() and span.kind == trace.SpanKind.SERVER:
                 add_custom_response_headers(span, response_headers)
             if response_hook:
                 response_hook(status, response_headers)
@@ -336,7 +336,7 @@ def __call__(self, environ, start_response):
             context_getter=wsgi_getter,
             attributes=collect_request_attributes(environ),
         )
-        if span.kind == trace.SpanKind.SERVER:
+        if span.is_recording() and span.kind == trace.SpanKind.SERVER:
             add_custom_request_headers(span, environ)
 
         if self.request_hook:


Test patch:
diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py
--- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py
+++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py
@@ -475,6 +475,29 @@ def iterate_response(self, response):
             except StopIteration:
                 break
 
+    @mock.patch.dict(
+        "os.environ",
+        {
+            OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3",
+        },
+    )
+    def test_custom_request_headers_non_recording_span(self):
+        try:
+            tracer_provider = trace_api.NoOpTracerProvider()
+            self.environ.update(
+                {
+                    "HTTP_CUSTOM_TEST_HEADER_1": "Test Value 2",
+                    "HTTP_CUSTOM_TEST_HEADER_2": "TestValue2,TestValue3",
+                }
+            )
+            app = otel_wsgi.OpenTelemetryMiddleware(
+                simple_wsgi, tracer_provider=tracer_provider
+            )
+            response = app(self.environ, self.start_response)
+            self.iterate_response(response)
+        except Exception as exc:  # pylint: disable=W0703
+            self.fail(f"Exception raised with NonRecordingSpan {exc}")
+
     @mock.patch.dict(
         "os.environ",
         {