Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't normalize headers with "hyphen -> underscore" #3104

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST=".*"

The name of the added span attribute will follow the format ``http.request.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
list containing the header values.
is the normalized HTTP header name (lowercase). The value of the attribute will be a list containing the header values.

For example:
``http.request.header.custom_request_header = ["<value1>", "<value2>"]``
``http.request.header.custom-request-header = ["<value1>", "<value2>"]``

Response headers
****************
Expand Down Expand Up @@ -162,11 +161,10 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE=".*"

The name of the added span attribute will follow the format ``http.response.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
list containing the header values.
is the normalized HTTP header name (lowercase). The value of the attribute will be a list containing the header values.

For example:
``http.response.header.custom_response_header = ["<value1>", "<value2>"]``
``http.response.header.custom-response-header = ["<value1>", "<value2>"]``

Sanitizing headers
******************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,19 @@ async def test_http_custom_request_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
),
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
"http.request.header.regex_test_header_1": ("Regex Test Value 1",),
"http.request.header.regex_test_header_2": (
"http.request.header.regex-test-header-1": ("Regex Test Value 1",),
"http.request.header.regex-test-header-2": (
"RegexTestValue2,RegexTestValue3",
),
"http.request.header.non_utf8_header": ("Moto Z²",),
"http.request.header.moto_z²_non_utf8_header_key": ("Moto Z²",),
"http.request.header.my_secret_header": ("[REDACTED]",),
"http.request.header.non-utf8-header": ("Moto Z²",),
"http.request.header.moto-z²-non-utf8-header-key": ("Moto Z²",),
"http.request.header.my-secret-header": ("[REDACTED]",),
}
for span in span_list:
if span.kind == SpanKind.SERVER:
Expand All @@ -183,7 +183,7 @@ async def test_http_repeat_request_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
"test-header-value-2",
),
Expand All @@ -202,12 +202,12 @@ async def test_http_custom_request_headers_not_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
),
}
not_expected = {
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
}
Expand All @@ -228,21 +228,21 @@ async def test_http_custom_response_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.response.header.custom_test_header_1": (
"http.response.header.custom-test-header-1": (
"test-header-value-1",
),
"http.response.header.custom_test_header_2": (
"http.response.header.custom-test-header-2": (
"test-header-value-2",
),
"http.response.header.my_custom_regex_header_1": (
"http.response.header.my-custom-regex-header-1": (
"my-custom-regex-value-1,my-custom-regex-value-2",
),
"http.response.header.my_custom_regex_header_2": (
"http.response.header.my-custom-regex-header-2": (
"my-custom-regex-value-3,my-custom-regex-value-4",
),
"http.response.header.my_secret_header": ("[REDACTED]",),
"http.response.header.non_utf8_header": ("Moto Z²",),
"http.response.header.moto_z²_non_utf8_header_key": ("Moto Z²",),
"http.response.header.my-secret-header": ("[REDACTED]",),
"http.response.header.non-utf8-header": ("Moto Z²",),
"http.response.header.moto-z²-non-utf8-header-key": ("Moto Z²",),
}
for span in span_list:
if span.kind == SpanKind.SERVER:
Expand All @@ -259,7 +259,7 @@ async def test_http_repeat_response_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.response.header.custom_test_header_1": (
"http.response.header.custom-test-header-1": (
"test-header-value-1",
"test-header-value-2",
),
Expand All @@ -278,7 +278,7 @@ async def test_http_custom_response_headers_not_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
not_expected = {
"http.response.header.custom_test_header_3": (
"http.response.header.custom-test-header-3": (
"test-header-value-3",
),
}
Expand Down Expand Up @@ -312,17 +312,17 @@ async def test_websocket_custom_request_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
),
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
"http.request.header.regex_test_header_1": ("Regex Test Value 1",),
"http.request.header.regex_test_header_2": (
"http.request.header.regex-test-header-1": ("Regex Test Value 1",),
"http.request.header.regex-test-header-2": (
"RegexTestValue2,RegexTestValue3",
),
"http.request.header.my_secret_header": ("[REDACTED]",),
"http.request.header.my-secret-header": ("[REDACTED]",),
}
for span in span_list:
if span.kind == SpanKind.SERVER:
Expand Down Expand Up @@ -352,7 +352,7 @@ async def test_websocket_custom_request_headers_not_in_span_attributes(
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
not_expected = {
"http.request.header.custom_test_header_3": (
"http.request.header.custom-test-header-3": (
"test-header-value-3",
),
}
Expand Down Expand Up @@ -384,19 +384,19 @@ async def test_websocket_custom_response_headers_in_span_attributes(self):
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
expected = {
"http.response.header.custom_test_header_1": (
"http.response.header.custom-test-header-1": (
"test-header-value-1",
),
"http.response.header.custom_test_header_2": (
"http.response.header.custom-test-header-2": (
"test-header-value-2",
),
"http.response.header.my_custom_regex_header_1": (
"http.response.header.my-custom-regex-header-1": (
"my-custom-regex-value-1,my-custom-regex-value-2",
),
"http.response.header.my_custom_regex_header_2": (
"http.response.header.my-custom-regex-header-2": (
"my-custom-regex-value-3,my-custom-regex-value-4",
),
"http.response.header.my_secret_header": ("[REDACTED]",),
"http.response.header.my-secret-header": ("[REDACTED]",),
}
for span in span_list:
if span.kind == SpanKind.SERVER:
Expand Down Expand Up @@ -427,7 +427,7 @@ async def test_websocket_custom_response_headers_not_in_span_attributes(
await self.get_all_output()
span_list = self.exporter.get_finished_spans()
not_expected = {
"http.response.header.custom_test_header_3": (
"http.response.header.custom-test-header-3": (
"test-header-value-3",
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,10 @@ def response_hook(span, request, response):
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST=".*"

The name of the added span attribute will follow the format ``http.request.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
single item list containing all the header values.
is the normalized HTTP header name (lowercase). The value of the attribute will be a single item list containing all the header values.

For example:
``http.request.header.custom_request_header = ["<value1>,<value2>"]``
``http.request.header.custom-request-header = ["<value1>,<value2>"]``

Response headers
****************
Expand Down Expand Up @@ -207,11 +206,11 @@ def response_hook(span, request, response):
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE=".*"

The name of the added span attribute will follow the format ``http.response.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
is the normalized HTTP header name (lowercase). The value of the attribute will be a
single item list containing all the header values.

For example:
``http.response.header.custom_response_header = ["<value1>,<value2>"]``
``http.response.header.custom-response-header = ["<value1>,<value2>"]``

Sanitizing headers
******************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1007,17 +1007,17 @@ def tearDownClass(cls):

def test_http_custom_request_headers_in_span_attributes(self):
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
),
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
"http.request.header.regex_test_header_1": ("Regex Test Value 1",),
"http.request.header.regex_test_header_2": (
"http.request.header.regex-test-header-1": ("Regex Test Value 1",),
"http.request.header.regex-test-header-2": (
"RegexTestValue2,RegexTestValue3",
),
"http.request.header.my_secret_header": ("[REDACTED]",),
"http.request.header.my-secret-header": ("[REDACTED]",),
}
Client(
HTTP_CUSTOM_TEST_HEADER_1="test-header-value-1",
Expand All @@ -1036,7 +1036,7 @@ def test_http_custom_request_headers_in_span_attributes(self):

def test_http_custom_request_headers_not_in_span_attributes(self):
not_expected = {
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
}
Expand All @@ -1052,19 +1052,19 @@ def test_http_custom_request_headers_not_in_span_attributes(self):

def test_http_custom_response_headers_in_span_attributes(self):
expected = {
"http.response.header.custom_test_header_1": (
"http.response.header.custom-test-header-1": (
"test-header-value-1",
),
"http.response.header.custom_test_header_2": (
"http.response.header.custom-test-header-2": (
"test-header-value-2",
),
"http.response.header.my_custom_regex_header_1": (
"http.response.header.my-custom-regex-header-1": (
"my-custom-regex-value-1,my-custom-regex-value-2",
),
"http.response.header.my_custom_regex_header_2": (
"http.response.header.my-custom-regex-header-2": (
"my-custom-regex-value-3,my-custom-regex-value-4",
),
"http.response.header.my_secret_header": ("[REDACTED]",),
"http.response.header.my-secret-header": ("[REDACTED]",),
}
Client().get("/traced_custom_header/")
spans = self.exporter.get_finished_spans()
Expand All @@ -1077,7 +1077,7 @@ def test_http_custom_response_headers_in_span_attributes(self):

def test_http_custom_response_headers_not_in_span_attributes(self):
not_expected = {
"http.response.header.custom_test_header_3": (
"http.response.header.custom-test-header-3": (
"test-header-value-3",
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -735,17 +735,17 @@ def tearDownClass(cls):

async def test_http_custom_request_headers_in_span_attributes(self):
expected = {
"http.request.header.custom_test_header_1": (
"http.request.header.custom-test-header-1": (
"test-header-value-1",
),
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
"http.request.header.regex_test_header_1": ("Regex Test Value 1",),
"http.request.header.regex_test_header_2": (
"http.request.header.regex-test-header-1": ("Regex Test Value 1",),
"http.request.header.regex-test-header-2": (
"RegexTestValue2,RegexTestValue3",
),
"http.request.header.my_secret_header": ("[REDACTED]",),
"http.request.header.my-secret-header": ("[REDACTED]",),
}
await self.async_client.get(
"/traced/",
Expand All @@ -767,7 +767,7 @@ async def test_http_custom_request_headers_in_span_attributes(self):

async def test_http_custom_request_headers_not_in_span_attributes(self):
not_expected = {
"http.request.header.custom_test_header_2": (
"http.request.header.custom-test-header-2": (
"test-header-value-2",
),
}
Expand All @@ -788,19 +788,19 @@ async def test_http_custom_request_headers_not_in_span_attributes(self):

async def test_http_custom_response_headers_in_span_attributes(self):
expected = {
"http.response.header.custom_test_header_1": (
"http.response.header.custom-test-header-1": (
"test-header-value-1",
),
"http.response.header.custom_test_header_2": (
"http.response.header.custom-test-header-2": (
"test-header-value-2",
),
"http.response.header.my_custom_regex_header_1": (
"http.response.header.my-custom-regex-header-1": (
"my-custom-regex-value-1,my-custom-regex-value-2",
),
"http.response.header.my_custom_regex_header_2": (
"http.response.header.my-custom-regex-header-2": (
"my-custom-regex-value-3,my-custom-regex-value-4",
),
"http.response.header.my_secret_header": ("[REDACTED]",),
"http.response.header.my-secret-header": ("[REDACTED]",),
}
await self.async_client.get("/traced_custom_header/")
spans = self.exporter.get_finished_spans()
Expand All @@ -813,7 +813,7 @@ async def test_http_custom_response_headers_in_span_attributes(self):

async def test_http_custom_response_headers_not_in_span_attributes(self):
not_expected = {
"http.response.header.custom_test_header_3": (
"http.response.header.custom-test-header-3": (
"test-header-value-3",
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,10 @@ def response_hook(span, req, resp):
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST=".*"

The name of the added span attribute will follow the format ``http.request.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
single item list containing all the header values.
is the normalized HTTP header name (lowercase). The value of the attribute will be a single item list containing all the header values.

For example:
``http.request.header.custom_request_header = ["<value1>,<value2>"]``
``http.request.header.custom-request-header = ["<value1>,<value2>"]``

Response headers
****************
Expand Down Expand Up @@ -155,11 +154,10 @@ def response_hook(span, req, resp):
export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE=".*"

The name of the added span attribute will follow the format ``http.response.header.<header_name>`` where ``<header_name>``
is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a
single item list containing all the header values.
is the normalized HTTP header name (lowercase). The value of the attribute will be a single item list containing all the header values.

For example:
``http.response.header.custom_response_header = ["<value1>,<value2>"]``
``http.response.header.custom-response-header = ["<value1>,<value2>"]``

Sanitizing headers
******************
Expand Down
Loading
Loading