Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Breaking Changes

- `opentelemetry-util-http` Don't normalize headers with "hyphen -> underscore"
([#3104](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3104))

### Added

- `opentelemetry-instrumentation-confluent-kafka` Add support for confluent-kafka <=2.7.0
Expand All @@ -23,7 +28,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints
([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105))


## Version 1.29.0/0.50b0 (2024-12-11)

### Added
Expand Down
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