diff --git a/instana/instrumentation/aiohttp/client.py b/instana/instrumentation/aiohttp/client.py index 35e4d98a..a09c5b7d 100644 --- a/instana/instrumentation/aiohttp/client.py +++ b/instana/instrumentation/aiohttp/client.py @@ -44,7 +44,7 @@ async def stan_request_end(session, trace_config_ctx, params): if agent.options.extra_http_headers is not None: for custom_header in agent.options.extra_http_headers: if custom_header in params.response.headers: - scope.span.set_tag("http.%s" % custom_header, params.response.headers[custom_header]) + scope.span.set_tag("http.header.%s" % custom_header, params.response.headers[custom_header]) if 500 <= params.response.status <= 599: scope.span.mark_as_errored({"http.error": params.response.reason}) diff --git a/instana/instrumentation/aiohttp/server.py b/instana/instrumentation/aiohttp/server.py index 1a0da309..fa6ba857 100644 --- a/instana/instrumentation/aiohttp/server.py +++ b/instana/instrumentation/aiohttp/server.py @@ -37,7 +37,7 @@ async def stan_middleware(request, handler): if agent.options.extra_http_headers is not None: for custom_header in agent.options.extra_http_headers: if custom_header in request.headers: - scope.span.set_tag("http.%s" % custom_header, request.headers[custom_header]) + scope.span.set_tag("http.header.%s" % custom_header, request.headers[custom_header]) response = None try: diff --git a/instana/instrumentation/asgi.py b/instana/instrumentation/asgi.py index 4e7b5bb5..1c4d0981 100644 --- a/instana/instrumentation/asgi.py +++ b/instana/instrumentation/asgi.py @@ -20,7 +20,7 @@ def _extract_custom_headers(self, span, headers): # Headers are in the following format: b'x-header-1' for header_pair in headers: if header_pair[0].decode('utf-8').lower() == custom_header.lower(): - span.set_tag("http.%s" % custom_header, header_pair[1].decode('utf-8')) + span.set_tag("http.header.%s" % custom_header, header_pair[1].decode('utf-8')) except Exception: logger.debug("extract_custom_headers: ", exc_info=True) diff --git a/instana/instrumentation/aws/triggers.py b/instana/instrumentation/aws/triggers.py index f8c6774a..e352fe28 100644 --- a/instana/instrumentation/aws/triggers.py +++ b/instana/instrumentation/aws/triggers.py @@ -125,7 +125,7 @@ def capture_extra_headers(event, span, extra_headers): for custom_header in extra_headers: for key in event_headers: if key.lower() == custom_header.lower(): - span.set_tag("http.%s" % custom_header, event_headers[key]) + span.set_tag("http.header.%s" % custom_header, event_headers[key]) except Exception: logger.debug("capture_extra_headers: ", exc_info=True) diff --git a/instana/instrumentation/django/middleware.py b/instana/instrumentation/django/middleware.py index 5b05b86b..ca1a88ef 100644 --- a/instana/instrumentation/django/middleware.py +++ b/instana/instrumentation/django/middleware.py @@ -37,7 +37,7 @@ def process_request(self, request): # Headers are available in this format: HTTP_X_CAPTURE_THIS django_header = ('HTTP_' + custom_header.upper()).replace('-', '_') if django_header in env: - request.iscope.span.set_tag("http.%s" % custom_header, env[django_header]) + request.iscope.span.set_tag("http.header.%s" % custom_header, env[django_header]) request.iscope.span.set_tag(ext.HTTP_METHOD, request.method) if 'PATH_INFO' in env: diff --git a/instana/instrumentation/flask/vanilla.py b/instana/instrumentation/flask/vanilla.py index 8a8b2439..2b63c229 100644 --- a/instana/instrumentation/flask/vanilla.py +++ b/instana/instrumentation/flask/vanilla.py @@ -30,7 +30,7 @@ def before_request_with_instana(*argv, **kwargs): # Headers are available in this format: HTTP_X_CAPTURE_THIS header = ('HTTP_' + custom_header.upper()).replace('-', '_') if header in env: - span.set_tag("http.%s" % custom_header, env[header]) + span.set_tag("http.header.%s" % custom_header, env[header]) span.set_tag(ext.HTTP_METHOD, flask.request.method) if 'PATH_INFO' in env: diff --git a/instana/instrumentation/flask/with_blinker.py b/instana/instrumentation/flask/with_blinker.py index b3653a4e..e646301e 100644 --- a/instana/instrumentation/flask/with_blinker.py +++ b/instana/instrumentation/flask/with_blinker.py @@ -31,7 +31,7 @@ def request_started_with_instana(sender, **extra): # Headers are available in this format: HTTP_X_CAPTURE_THIS header = ('HTTP_' + custom_header.upper()).replace('-', '_') if header in env: - span.set_tag("http.%s" % custom_header, env[header]) + span.set_tag("http.header.%s" % custom_header, env[header]) span.set_tag(ext.HTTP_METHOD, flask.request.method) if 'PATH_INFO' in env: diff --git a/instana/instrumentation/pyramid/tweens.py b/instana/instrumentation/pyramid/tweens.py index 12b9adb2..399c38cc 100644 --- a/instana/instrumentation/pyramid/tweens.py +++ b/instana/instrumentation/pyramid/tweens.py @@ -33,7 +33,7 @@ def __call__(self, request): # Headers are available in this format: HTTP_X_CAPTURE_THIS h = ('HTTP_' + custom_header.upper()).replace('-', '_') if h in request.headers: - scope.span.set_tag("http.%s" % custom_header, request.headers[h]) + scope.span.set_tag("http.header.%s" % custom_header, request.headers[h]) if len(request.query_string): scrubbed_params = strip_secrets_from_query(request.query_string, agent.options.secrets_matcher, agent.options.secrets_list) diff --git a/instana/instrumentation/tornado/server.py b/instana/instrumentation/tornado/server.py index b5241e46..ab176b9c 100644 --- a/instana/instrumentation/tornado/server.py +++ b/instana/instrumentation/tornado/server.py @@ -44,7 +44,7 @@ def execute_with_instana(wrapped, instance, argv, kwargs): if agent.options.extra_http_headers is not None: for custom_header in agent.options.extra_http_headers: if custom_header in instance.request.headers: - scope.span.set_tag("http.%s" % custom_header, instance.request.headers[custom_header]) + scope.span.set_tag("http.header.%s" % custom_header, instance.request.headers[custom_header]) setattr(instance.request, "_instana", scope) diff --git a/instana/instrumentation/urllib3.py b/instana/instrumentation/urllib3.py index 0998239e..1b25774c 100644 --- a/instana/instrumentation/urllib3.py +++ b/instana/instrumentation/urllib3.py @@ -51,7 +51,7 @@ def collect_response(scope, response): if agent.options.extra_http_headers is not None: for custom_header in agent.options.extra_http_headers: if custom_header in response.headers: - scope.span.set_tag("http.%s" % custom_header, response.headers[custom_header]) + scope.span.set_tag("http.header.%s" % custom_header, response.headers[custom_header]) if 500 <= response.status <= 599: scope.span.mark_as_errored() diff --git a/instana/instrumentation/webapp2_inst.py b/instana/instrumentation/webapp2_inst.py index b2ee88ce..47823a1c 100644 --- a/instana/instrumentation/webapp2_inst.py +++ b/instana/instrumentation/webapp2_inst.py @@ -46,7 +46,7 @@ def new_start_response(status, headers, exc_info=None): # Headers are available in this format: HTTP_X_CAPTURE_THIS wsgi_header = ('HTTP_' + custom_header.upper()).replace('-', '_') if wsgi_header in env: - scope.span.set_tag("http.%s" % custom_header, env[wsgi_header]) + scope.span.set_tag("http.header.%s" % custom_header, env[wsgi_header]) if 'PATH_INFO' in env: scope.span.set_tag('http.path', env['PATH_INFO']) diff --git a/instana/instrumentation/wsgi.py b/instana/instrumentation/wsgi.py index 27f030fa..0f3cd627 100644 --- a/instana/instrumentation/wsgi.py +++ b/instana/instrumentation/wsgi.py @@ -40,7 +40,7 @@ def new_start_response(status, headers, exc_info=None): # Headers are available in this format: HTTP_X_CAPTURE_THIS wsgi_header = ('HTTP_' + custom_header.upper()).replace('-', '_') if wsgi_header in env: - self.scope.span.set_tag("http.%s" % custom_header, env[wsgi_header]) + self.scope.span.set_tag("http.header.%s" % custom_header, env[wsgi_header]) if 'PATH_INFO' in env: self.scope.span.set_tag('http.path', env['PATH_INFO']) diff --git a/instana/span.py b/instana/span.py index 8c7f78e4..b01c9c54 100644 --- a/instana/span.py +++ b/instana/span.py @@ -467,5 +467,15 @@ def _collect_http_tags(self, span): self.data["http"]["path_tpl"] = span.tags.pop("http.path_tpl", None) self.data["http"]["error"] = span.tags.pop('http.error', None) - if span.operation_name == "soap": - self.data["soap"]["action"] = span.tags.pop('soap.action', None) + if len(span.tags) > 0: + if span.operation_name == "soap": + self.data["soap"]["action"] = span.tags.pop('soap.action', None) + + custom_headers = [] + for key in span.tags: + if key[0:12] == "http.header.": + custom_headers.append(key) + + for key in custom_headers: + trimmed_key = key[12:] + self.data["http"]["header"][trimmed_key] = span.tags.pop(key) diff --git a/tests/clients/test_urllib3.py b/tests/clients/test_urllib3.py index b4922a4c..2b763bb5 100644 --- a/tests/clients/test_urllib3.py +++ b/tests/clients/test_urllib3.py @@ -510,7 +510,7 @@ def test_client_error(self): def test_requestspkg_get(self): self.recorder.clear_spans() - + with tracer.start_active_span('test'): r = requests.get(testenv["wsgi_server"] + '/', timeout=2) @@ -706,7 +706,9 @@ def test_response_header_capture(self): self.assertIsNotNone(urllib3_span.stack) self.assertTrue(type(urllib3_span.stack) is list) self.assertTrue(len(urllib3_span.stack) > 1) - self.assertTrue('http.X-Capture-This' in urllib3_span.data["custom"]["tags"]) + + assert "X-Capture-This" in urllib3_span.data["http"]["header"] + self.assertEqual("Ok", urllib3_span.data["http"]["header"]["X-Capture-This"]) agent.options.extra_http_headers = original_extra_http_headers diff --git a/tests/frameworks/test_aiohttp_client.py b/tests/frameworks/test_aiohttp_client.py index e4d99204..370a2948 100644 --- a/tests/frameworks/test_aiohttp_client.py +++ b/tests/frameworks/test_aiohttp_client.py @@ -377,14 +377,14 @@ async def test(): self.assertEqual("aiohttp-client", aiohttp_span.n) self.assertEqual(200, aiohttp_span.data["http"]["status"]) - self.assertEqual( - testenv["wsgi_server"] + "/response_headers", aiohttp_span.data["http"]["url"]) + self.assertEqual(testenv["wsgi_server"] + "/response_headers", aiohttp_span.data["http"]["url"]) self.assertEqual("GET", aiohttp_span.data["http"]["method"]) self.assertIsNotNone(aiohttp_span.stack) self.assertTrue(type(aiohttp_span.stack) is list) self.assertTrue(len(aiohttp_span.stack) > 1) - self.assertTrue( - 'http.X-Capture-This' in aiohttp_span.data["custom"]["tags"]) + + assert "X-Capture-This" in aiohttp_span.data["http"]["header"] + self.assertEqual("Ok", aiohttp_span.data["http"]["header"]["X-Capture-This"]) assert "X-Instana-T" in response.headers self.assertEqual(response.headers["X-Instana-T"], traceId) @@ -393,8 +393,7 @@ async def test(): assert "X-Instana-L" in response.headers self.assertEqual(response.headers["X-Instana-L"], '1') assert "Server-Timing" in response.headers - self.assertEqual( - response.headers["Server-Timing"], "intid;desc=%s" % traceId) + self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) agent.options.extra_http_headers = original_extra_http_headers diff --git a/tests/frameworks/test_aiohttp_server.py b/tests/frameworks/test_aiohttp_server.py index 3f636960..9071c391 100644 --- a/tests/frameworks/test_aiohttp_server.py +++ b/tests/frameworks/test_aiohttp_server.py @@ -316,12 +316,10 @@ async def test(): self.assertEqual( response.headers["Server-Timing"], "intid;desc=%s" % traceId) - assert("http.X-Capture-This" in aioserver_span.data["custom"]["tags"]) - self.assertEqual( - 'this', aioserver_span.data["custom"]["tags"]['http.X-Capture-This']) - assert("http.X-Capture-That" in aioserver_span.data["custom"]["tags"]) - self.assertEqual( - 'that', aioserver_span.data["custom"]["tags"]['http.X-Capture-That']) + assert "X-Capture-This" in aioserver_span.data["http"]["header"] + self.assertEqual("this", aioserver_span.data["http"]["header"]["X-Capture-This"]) + assert "X-Capture-That" in aioserver_span.data["http"]["header"] + self.assertEqual("that", aioserver_span.data["http"]["header"]["X-Capture-That"]) def test_server_get_401(self): async def test(): diff --git a/tests/frameworks/test_django.py b/tests/frameworks/test_django.py index f1c4c331..eec217ac 100644 --- a/tests/frameworks/test_django.py +++ b/tests/frameworks/test_django.py @@ -251,10 +251,10 @@ def test_custom_header_capture(self): self.assertEqual('GET', django_span.data["http"]["method"]) self.assertEqual(200, django_span.data["http"]["status"]) - self.assertEqual(True, "http.X-Capture-This" in django_span.data["custom"]['tags']) - self.assertEqual("this", django_span.data["custom"]['tags']["http.X-Capture-This"]) - self.assertEqual(True, "http.X-Capture-That" in django_span.data["custom"]['tags']) - self.assertEqual("that", django_span.data["custom"]['tags']["http.X-Capture-That"]) + assert "X-Capture-This" in django_span.data["http"]["header"] + self.assertEqual("this", django_span.data["http"]["header"]["X-Capture-This"]) + assert "X-Capture-That" in django_span.data["http"]["header"] + self.assertEqual("that", django_span.data["http"]["header"]["X-Capture-That"]) def test_with_incoming_context(self): request_headers = dict() diff --git a/tests/frameworks/test_fastapi.py b/tests/frameworks/test_fastapi.py index 3f3e5e04..32002c5e 100644 --- a/tests/frameworks/test_fastapi.py +++ b/tests/frameworks/test_fastapi.py @@ -355,7 +355,7 @@ def test_custom_header_capture(server): assert('http.error' not in asgi_span.data['sdk']['custom']['tags']) assert('http.params' not in asgi_span.data['sdk']['custom']['tags']) - assert("http.X-Capture-This" in asgi_span.data["sdk"]["custom"]['tags']) - assert("this" == asgi_span.data["sdk"]["custom"]['tags']["http.X-Capture-This"]) - assert("http.X-Capture-That" in asgi_span.data["sdk"]["custom"]['tags']) - assert("that" == asgi_span.data["sdk"]["custom"]['tags']["http.X-Capture-That"]) + assert("http.header.X-Capture-This" in asgi_span.data["sdk"]["custom"]['tags']) + assert("this" == asgi_span.data["sdk"]["custom"]['tags']["http.header.X-Capture-This"]) + assert("http.header.X-Capture-That" in asgi_span.data["sdk"]["custom"]['tags']) + assert("that" == asgi_span.data["sdk"]["custom"]['tags']["http.header.X-Capture-That"]) diff --git a/tests/frameworks/test_starlette.py b/tests/frameworks/test_starlette.py index b2a90308..ca8176c1 100644 --- a/tests/frameworks/test_starlette.py +++ b/tests/frameworks/test_starlette.py @@ -264,7 +264,7 @@ def test_custom_header_capture(server): assert('http.error' not in asgi_span.data['sdk']['custom']['tags']) assert('http.params' not in asgi_span.data['sdk']['custom']['tags']) - assert("http.X-Capture-This" in asgi_span.data["sdk"]["custom"]['tags']) - assert("this" == asgi_span.data["sdk"]["custom"]['tags']["http.X-Capture-This"]) - assert("http.X-Capture-That" in asgi_span.data["sdk"]["custom"]['tags']) - assert("that" == asgi_span.data["sdk"]["custom"]['tags']["http.X-Capture-That"]) + assert("http.header.X-Capture-This" in asgi_span.data["sdk"]["custom"]['tags']) + assert("this" == asgi_span.data["sdk"]["custom"]['tags']["http.header.X-Capture-This"]) + assert("http.header.X-Capture-That" in asgi_span.data["sdk"]["custom"]['tags']) + assert("that" == asgi_span.data["sdk"]["custom"]['tags']["http.header.X-Capture-That"]) diff --git a/tests/frameworks/test_tornado_server.py b/tests/frameworks/test_tornado_server.py index 4d9e5bd2..155924de 100644 --- a/tests/frameworks/test_tornado_server.py +++ b/tests/frameworks/test_tornado_server.py @@ -115,7 +115,7 @@ async def test(): return await self.post(session, testenv["tornado_server"] + "/") response = tornado.ioloop.IOLoop.current().run_sync(test) - + spans = self.recorder.queued_spans() self.assertEqual(3, len(spans)) @@ -176,7 +176,7 @@ async def test(): headers = { 'X-Instana-Synthetic': '1' } - + with async_tracer.start_active_span('test'): async with aiohttp.ClientSession() as session: return await self.fetch(session, testenv["tornado_server"] + "/", headers=headers) @@ -598,7 +598,7 @@ async def test(): self.assertTrue("Server-Timing" in response.headers) self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId) - self.assertTrue("http.X-Capture-This" in tornado_span.data["custom"]["tags"]) - self.assertEqual('this', tornado_span.data["custom"]["tags"]['http.X-Capture-This']) - self.assertTrue("http.X-Capture-That" in tornado_span.data["custom"]["tags"]) - self.assertEqual('that', tornado_span.data["custom"]["tags"]['http.X-Capture-That']) + assert "X-Capture-This" in tornado_span.data["http"]["header"] + self.assertEqual("this", tornado_span.data["http"]["header"]["X-Capture-This"]) + assert "X-Capture-That" in tornado_span.data["http"]["header"] + self.assertEqual("that", tornado_span.data["http"]["header"]["X-Capture-That"]) \ No newline at end of file diff --git a/tests/frameworks/test_wsgi.py b/tests/frameworks/test_wsgi.py index 582e04b4..9db3012b 100644 --- a/tests/frameworks/test_wsgi.py +++ b/tests/frameworks/test_wsgi.py @@ -230,10 +230,10 @@ def test_custom_header_capture(self): self.assertIsNotNone(wsgi_span.stack) self.assertEqual(2, len(wsgi_span.stack)) - self.assertEqual(True, "http.X-Capture-This" in wsgi_span.data["custom"]['tags']) - self.assertEqual("this", wsgi_span.data["custom"]['tags']["http.X-Capture-This"]) - self.assertEqual(True, "http.X-Capture-That" in wsgi_span.data["custom"]['tags']) - self.assertEqual("that", wsgi_span.data["custom"]['tags']["http.X-Capture-That"]) + assert "X-Capture-This" in wsgi_span.data["http"]["header"] + self.assertEqual("this", wsgi_span.data["http"]["header"]["X-Capture-This"]) + assert "X-Capture-That" in wsgi_span.data["http"]["header"] + self.assertEqual("that", wsgi_span.data["http"]["header"]["X-Capture-That"]) def test_secret_scrubbing(self): with tracer.start_active_span('test'):