opentelemetry-instrumentation-requests 0.53b0__tar.gz → 0.54b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (12) hide show
  1. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/PKG-INFO +4 -4
  2. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/pyproject.toml +3 -3
  3. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/src/opentelemetry/instrumentation/requests/__init__.py +27 -2
  4. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/src/opentelemetry/instrumentation/requests/version.py +1 -1
  5. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/tests/test_requests_integration.py +44 -0
  6. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/.gitignore +0 -0
  7. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/LICENSE +0 -0
  8. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/README.rst +0 -0
  9. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/src/opentelemetry/instrumentation/requests/package.py +0 -0
  10. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/src/opentelemetry/instrumentation/requests/py.typed +0 -0
  11. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/tests/__init__.py +0 -0
  12. {opentelemetry_instrumentation_requests-0.53b0 → opentelemetry_instrumentation_requests-0.54b0}/tests/test_requests_ip_support.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opentelemetry-instrumentation-requests
3
- Version: 0.53b0
3
+ Version: 0.54b0
4
4
  Summary: OpenTelemetry requests instrumentation
5
5
  Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests
6
6
  Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib
@@ -20,9 +20,9 @@ Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Programming Language :: Python :: 3.13
21
21
  Requires-Python: >=3.8
22
22
  Requires-Dist: opentelemetry-api~=1.12
23
- Requires-Dist: opentelemetry-instrumentation==0.53b0
24
- Requires-Dist: opentelemetry-semantic-conventions==0.53b0
25
- Requires-Dist: opentelemetry-util-http==0.53b0
23
+ Requires-Dist: opentelemetry-instrumentation==0.54b0
24
+ Requires-Dist: opentelemetry-semantic-conventions==0.54b0
25
+ Requires-Dist: opentelemetry-util-http==0.54b0
26
26
  Provides-Extra: instruments
27
27
  Requires-Dist: requests~=2.0; extra == 'instruments'
28
28
  Description-Content-Type: text/x-rst
@@ -27,9 +27,9 @@ classifiers = [
27
27
  ]
28
28
  dependencies = [
29
29
  "opentelemetry-api ~= 1.12",
30
- "opentelemetry-instrumentation == 0.53b0",
31
- "opentelemetry-semantic-conventions == 0.53b0",
32
- "opentelemetry-util-http == 0.53b0",
30
+ "opentelemetry-instrumentation == 0.54b0",
31
+ "opentelemetry-semantic-conventions == 0.54b0",
32
+ "opentelemetry-util-http == 0.54b0",
33
33
  ]
34
34
 
35
35
  [project.optional-dependencies]
@@ -57,6 +57,22 @@ The hooks can be configured as follows:
57
57
  request_hook=request_hook, response_hook=response_hook
58
58
  )
59
59
 
60
+ Custom Duration Histogram Boundaries
61
+ ************************************
62
+ To customize the duration histogram bucket boundaries used for HTTP client request duration metrics,
63
+ you can provide a list of values when instrumenting:
64
+
65
+ .. code:: python
66
+
67
+ import requests
68
+ from opentelemetry.instrumentation.requests import RequestsInstrumentor
69
+
70
+ custom_boundaries = [0.0, 5.0, 10.0, 25.0, 50.0, 100.0]
71
+
72
+ RequestsInstrumentor().instrument(
73
+ duration_histogram_boundaries=custom_boundaries
74
+ )
75
+
60
76
  Exclude lists
61
77
  *************
62
78
  To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_REQUESTS_EXCLUDED_URLS``
@@ -87,6 +103,8 @@ from requests.sessions import Session
87
103
  from requests.structures import CaseInsensitiveDict
88
104
 
89
105
  from opentelemetry.instrumentation._semconv import (
106
+ HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
107
+ HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
90
108
  _client_duration_attrs_new,
91
109
  _client_duration_attrs_old,
92
110
  _filter_semconv_duration_attrs,
@@ -410,8 +428,8 @@ class RequestsInstrumentor(BaseInstrumentor):
410
428
  ``tracer_provider``: a TracerProvider, defaults to global
411
429
  ``request_hook``: An optional callback that is invoked right after a span is created.
412
430
  ``response_hook``: An optional callback which is invoked right before the span is finished processing a response.
413
- ``excluded_urls``: A string containing a comma-delimited
414
- list of regexes used to exclude URLs from tracking
431
+ ``excluded_urls``: A string containing a comma-delimited list of regexes used to exclude URLs from tracking
432
+ ``duration_histogram_boundaries``: A list of float values representing the explicit bucket boundaries for the duration histogram.
415
433
  """
416
434
  semconv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
417
435
  _OpenTelemetryStabilitySignalType.HTTP,
@@ -426,6 +444,9 @@ class RequestsInstrumentor(BaseInstrumentor):
426
444
  )
427
445
  excluded_urls = kwargs.get("excluded_urls")
428
446
  meter_provider = kwargs.get("meter_provider")
447
+ duration_histogram_boundaries = kwargs.get(
448
+ "duration_histogram_boundaries"
449
+ )
429
450
  meter = get_meter(
430
451
  __name__,
431
452
  __version__,
@@ -438,6 +459,8 @@ class RequestsInstrumentor(BaseInstrumentor):
438
459
  name=MetricInstruments.HTTP_CLIENT_DURATION,
439
460
  unit="ms",
440
461
  description="measures the duration of the outbound HTTP request",
462
+ explicit_bucket_boundaries_advisory=duration_histogram_boundaries
463
+ or HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
441
464
  )
442
465
  duration_histogram_new = None
443
466
  if _report_new(semconv_opt_in_mode):
@@ -445,6 +468,8 @@ class RequestsInstrumentor(BaseInstrumentor):
445
468
  name=HTTP_CLIENT_REQUEST_DURATION,
446
469
  unit="s",
447
470
  description="Duration of HTTP client requests.",
471
+ explicit_bucket_boundaries_advisory=duration_histogram_boundaries
472
+ or HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
448
473
  )
449
474
  _instrument(
450
475
  tracer,
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "0.53b0"
15
+ __version__ = "0.54b0"
@@ -23,6 +23,8 @@ from requests.models import Response
23
23
  import opentelemetry.instrumentation.requests
24
24
  from opentelemetry import trace
25
25
  from opentelemetry.instrumentation._semconv import (
26
+ HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
27
+ HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
26
28
  OTEL_SEMCONV_STABILITY_OPT_IN,
27
29
  _OpenTelemetrySemanticConventionStability,
28
30
  )
@@ -123,6 +125,7 @@ class RequestsIntegrationTestBase(abc.ABC):
123
125
  def tearDown(self):
124
126
  super().tearDown()
125
127
  self.env_patch.stop()
128
+ _OpenTelemetrySemanticConventionStability._initialized = False
126
129
  RequestsInstrumentor().uninstrument()
127
130
  httpretty.disable()
128
131
 
@@ -730,6 +733,7 @@ class TestRequestsIntergrationMetric(TestBase):
730
733
  def tearDown(self):
731
734
  super().tearDown()
732
735
  self.env_patch.stop()
736
+ _OpenTelemetrySemanticConventionStability._initialized = False
733
737
  RequestsInstrumentor().uninstrument()
734
738
  httpretty.disable()
735
739
 
@@ -762,6 +766,10 @@ class TestRequestsIntergrationMetric(TestBase):
762
766
  "measures the duration of the outbound HTTP request",
763
767
  )
764
768
  for data_point in metric.data.data_points:
769
+ self.assertEqual(
770
+ data_point.explicit_bounds,
771
+ HTTP_DURATION_HISTOGRAM_BUCKETS_OLD,
772
+ )
765
773
  self.assertDictEqual(
766
774
  expected_attributes, dict(data_point.attributes)
767
775
  )
@@ -788,6 +796,10 @@ class TestRequestsIntergrationMetric(TestBase):
788
796
  metric.description, "Duration of HTTP client requests."
789
797
  )
790
798
  for data_point in metric.data.data_points:
799
+ self.assertEqual(
800
+ data_point.explicit_bounds,
801
+ HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
802
+ )
791
803
  self.assertDictEqual(
792
804
  expected_attributes, dict(data_point.attributes)
793
805
  )
@@ -833,6 +845,38 @@ class TestRequestsIntergrationMetric(TestBase):
833
845
  )
834
846
  self.assertEqual(data_point.count, 1)
835
847
 
848
+ def test_custom_histogram_boundaries(self):
849
+ RequestsInstrumentor().uninstrument()
850
+ custom_boundaries = (0.0, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0)
851
+ meter_provider, memory_reader = self.create_meter_provider()
852
+ RequestsInstrumentor().instrument(
853
+ meter_provider=meter_provider,
854
+ duration_histogram_boundaries=custom_boundaries,
855
+ )
856
+
857
+ self.perform_request(self.URL)
858
+ metrics = memory_reader.get_metrics_data().resource_metrics[0]
859
+ self.assertEqual(len(metrics.scope_metrics), 1)
860
+ data_point = metrics.scope_metrics[0].metrics[0].data.data_points[0]
861
+ self.assertEqual(data_point.explicit_bounds, custom_boundaries)
862
+ self.assertEqual(data_point.count, 1)
863
+
864
+ def test_custom_histogram_boundaries_new_semconv(self):
865
+ RequestsInstrumentor().uninstrument()
866
+ custom_boundaries = (0.0, 5.0, 10.0, 25.0, 50.0, 100.0)
867
+ meter_provider, memory_reader = self.create_meter_provider()
868
+ RequestsInstrumentor().instrument(
869
+ meter_provider=meter_provider,
870
+ duration_histogram_boundaries=custom_boundaries,
871
+ )
872
+
873
+ self.perform_request(self.URL)
874
+ metrics = memory_reader.get_metrics_data().resource_metrics[0]
875
+ self.assertEqual(len(metrics.scope_metrics), 1)
876
+ data_point = metrics.scope_metrics[0].metrics[0].data.data_points[0]
877
+ self.assertEqual(data_point.explicit_bounds, custom_boundaries)
878
+ self.assertEqual(data_point.count, 1)
879
+
836
880
  def test_basic_metric_non_recording_span(self):
837
881
  expected_attributes = {
838
882
  SpanAttributes.HTTP_STATUS_CODE: 200,