|
36 | 36 | from opentelemetry.semconv._incubating.attributes.http_attributes import ( |
37 | 37 | HTTP_HOST, |
38 | 38 | HTTP_METHOD, |
| 39 | + HTTP_RESPONSE_BODY_SIZE, |
39 | 40 | HTTP_STATUS_CODE, |
40 | 41 | HTTP_URL, |
41 | 42 | ) |
|
57 | 58 | from opentelemetry.test.test_base import TestBase |
58 | 59 | from opentelemetry.trace import Span, StatusCode |
59 | 60 | from opentelemetry.util._importlib_metadata import entry_points |
| 61 | +from opentelemetry.util.http import ( |
| 62 | + OTEL_PYTHON_INSTRUMENTATION_HTTP_RESPONSE_BODY_SIZE, |
| 63 | +) |
60 | 64 |
|
61 | 65 |
|
62 | 66 | def run_with_test_server( |
@@ -1617,6 +1621,80 @@ def test_ignores_excluded_urls(self): |
1617 | 1621 | self._assert_spans(0) |
1618 | 1622 | self._assert_metrics(0) |
1619 | 1623 |
|
| 1624 | + @mock.patch.dict( |
| 1625 | + os.environ, {OTEL_SEMCONV_STABILITY_OPT_IN: "http"} |
| 1626 | + ) |
| 1627 | + def test_response_body_size_not_set_by_default(self): |
| 1628 | + AioHttpClientInstrumentor().uninstrument() |
| 1629 | + AioHttpClientInstrumentor().instrument() |
| 1630 | + |
| 1631 | + run_with_test_server( |
| 1632 | + self.get_default_request(), self.URL, self.default_handler |
| 1633 | + ) |
| 1634 | + span = self._assert_spans(1) |
| 1635 | + self.assertNotIn(HTTP_RESPONSE_BODY_SIZE, span.attributes) |
| 1636 | + |
| 1637 | + @mock.patch.dict( |
| 1638 | + os.environ, |
| 1639 | + { |
| 1640 | + OTEL_SEMCONV_STABILITY_OPT_IN: "http", |
| 1641 | + OTEL_PYTHON_INSTRUMENTATION_HTTP_RESPONSE_BODY_SIZE: "true", |
| 1642 | + }, |
| 1643 | + ) |
| 1644 | + def test_response_body_size_set_on_span(self): |
| 1645 | + AioHttpClientInstrumentor().uninstrument() |
| 1646 | + AioHttpClientInstrumentor().instrument() |
| 1647 | + run_with_test_server( |
| 1648 | + self.get_default_request(), self.URL, self.default_handler |
| 1649 | + ) |
| 1650 | + span = self._assert_spans(1) |
| 1651 | + self.assertIn(HTTP_RESPONSE_BODY_SIZE, span.attributes) |
| 1652 | + self.assertIsInstance( |
| 1653 | + span.attributes[HTTP_RESPONSE_BODY_SIZE], int |
| 1654 | + ) |
| 1655 | + |
| 1656 | + @mock.patch.dict( |
| 1657 | + "os.environ", |
| 1658 | + { |
| 1659 | + OTEL_SEMCONV_STABILITY_OPT_IN: "http", |
| 1660 | + OTEL_PYTHON_INSTRUMENTATION_HTTP_RESPONSE_BODY_SIZE: "true", |
| 1661 | + }, |
| 1662 | + ) |
| 1663 | + def test_response_body_size_metric_recorded(self): |
| 1664 | + AioHttpClientInstrumentor().uninstrument() |
| 1665 | + AioHttpClientInstrumentor().instrument() |
| 1666 | + run_with_test_server( |
| 1667 | + self.get_default_request(), self.URL, self.default_handler |
| 1668 | + ) |
| 1669 | + metrics = self._assert_metrics(2) |
| 1670 | + metric_names = {m.name for m in metrics} |
| 1671 | + self.assertIn( |
| 1672 | + "http.client.response.body.size", metric_names |
| 1673 | + ) |
| 1674 | + body_size_metric = next( |
| 1675 | + m |
| 1676 | + for m in metrics |
| 1677 | + if m.name == "http.client.response.body.size" |
| 1678 | + ) |
| 1679 | + data_point = body_size_metric.data.data_points[0] |
| 1680 | + self.assertEqual(data_point.count, 1) |
| 1681 | + self.assertTrue(data_point.sum > 0) |
| 1682 | + |
| 1683 | + @mock.patch.dict( |
| 1684 | + "os.environ", |
| 1685 | + { |
| 1686 | + OTEL_PYTHON_INSTRUMENTATION_HTTP_RESPONSE_BODY_SIZE: "true", |
| 1687 | + }, |
| 1688 | + ) |
| 1689 | + def test_response_body_size_not_set_without_new_semconv(self): |
| 1690 | + AioHttpClientInstrumentor().uninstrument() |
| 1691 | + AioHttpClientInstrumentor().instrument() |
| 1692 | + run_with_test_server( |
| 1693 | + self.get_default_request(), self.URL, self.default_handler |
| 1694 | + ) |
| 1695 | + span = self._assert_spans(1) |
| 1696 | + self.assertNotIn(HTTP_RESPONSE_BODY_SIZE, span.attributes) |
| 1697 | + |
1620 | 1698 |
|
1621 | 1699 | class TestLoadingAioHttpInstrumentor(unittest.TestCase): |
1622 | 1700 | def test_loading_instrumentor(self): |
|
0 commit comments