28
28
from opentelemetry .instrumentation .requests import RequestsInstrumentor
29
29
from opentelemetry .instrumentation .utils import _SUPPRESS_INSTRUMENTATION_KEY
30
30
from opentelemetry .instrumentation ._semconv import (
31
+ _SPAN_ATTRIBUTES_ERROR_TYPE ,
32
+ _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS ,
31
33
_OTEL_SEMCONV_STABILITY_OPT_IN_KEY ,
32
34
_OpenTelemetrySemanticConventionStability ,
33
35
)
@@ -68,7 +70,7 @@ class RequestsIntegrationTestBase(abc.ABC):
68
70
# pylint: disable=too-many-public-methods
69
71
70
72
URL = "http://mock/status/200"
71
- HOST = "mock/status "
73
+ HOST = "mock"
72
74
73
75
# pylint: disable=invalid-name
74
76
def setUp (self ):
@@ -150,33 +152,62 @@ def test_basic(self):
150
152
span , opentelemetry .instrumentation .requests
151
153
)
152
154
155
+ def test_basic_new_semconv (self ):
156
+ result = self .perform_request (self .URL )
157
+ self .assertEqual (result .text , "Hello!" )
158
+ span = self .assert_span ()
153
159
154
- # def test_basic_new_semconv(self):
155
- # print("here2")
156
- # result = self.perform_request(self.URL)
157
- # self.assertEqual(result.text, "Hello!")
158
- # span = self.assert_span()
160
+ self .assertIs (span .kind , trace .SpanKind .CLIENT )
161
+ self .assertEqual (span .name , "GET" )
159
162
160
- # self.assertIs(span.kind, trace.SpanKind.CLIENT)
161
- # self.assertEqual(span.name, "GET")
163
+ self .assertEqual (
164
+ span .attributes ,
165
+ {
166
+ SpanAttributes .HTTP_REQUEST_METHOD : "GET" ,
167
+ SpanAttributes .URL_FULL : self .URL ,
168
+ SpanAttributes .SERVER_ADDRESS : self .HOST ,
169
+ _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS : "mock" ,
170
+ SpanAttributes .HTTP_RESPONSE_STATUS_CODE : 200 ,
171
+ SpanAttributes .NET_PROTOCOL_VERSION : "1.1" ,
172
+ },
173
+ )
174
+
175
+ self .assertIs (span .status .status_code , trace .StatusCode .UNSET )
176
+
177
+ self .assertEqualSpanInstrumentationScope (
178
+ span , opentelemetry .instrumentation .requests
179
+ )
180
+
181
+ def test_basic_both_semconv (self ):
182
+ result = self .perform_request (self .URL )
183
+ self .assertEqual (result .text , "Hello!" )
184
+ span = self .assert_span ()
162
185
163
- # self.assertEqual(
164
- # span.attributes,
165
- # {
166
- # SpanAttributes.HTTP_REQUEST_METHOD: "GET",
167
- # SpanAttributes.HTTP_REQUEST_METHOD_ORIGINAL: "GET",
168
- # SpanAttributes.URL_FULL: self.URL,
169
- # SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200,
170
- # SpanAttributes.SERVER_ADDRESS: self.HOST,
171
- # },
172
- # )
186
+ self .assertIs (span .kind , trace .SpanKind .CLIENT )
187
+ self .assertEqual (span .name , "GET" )
173
188
174
- # self.assertIs(span.status.status_code, trace.StatusCode.UNSET)
189
+ self .assertEqual (
190
+ span .attributes ,
191
+ {
192
+ SpanAttributes .HTTP_METHOD : "GET" ,
193
+ SpanAttributes .HTTP_REQUEST_METHOD : "GET" ,
194
+ SpanAttributes .HTTP_URL : self .URL ,
195
+ SpanAttributes .URL_FULL : self .URL ,
196
+ SpanAttributes .HTTP_HOST : self .HOST ,
197
+ SpanAttributes .SERVER_ADDRESS : self .HOST ,
198
+ _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS : "mock" ,
199
+ SpanAttributes .HTTP_STATUS_CODE : 200 ,
200
+ SpanAttributes .HTTP_RESPONSE_STATUS_CODE : 200 ,
201
+ SpanAttributes .HTTP_FLAVOR : "1.1" ,
202
+ SpanAttributes .NET_PROTOCOL_VERSION : "1.1" ,
203
+ },
204
+ )
175
205
176
- # self.assertEqualSpanInstrumentationInfo(
177
- # span, opentelemetry.instrumentation.requests
178
- # )
206
+ self .assertIs (span .status .status_code , trace .StatusCode .UNSET )
179
207
208
+ self .assertEqualSpanInstrumentationScope (
209
+ span , opentelemetry .instrumentation .requests
210
+ )
180
211
181
212
def test_hooks (self ):
182
213
def request_hook (span , request_obj ):
@@ -259,6 +290,51 @@ def test_not_foundbasic(self):
259
290
trace .StatusCode .ERROR ,
260
291
)
261
292
293
+ def test_not_foundbasic_new_semconv (self ):
294
+ url_404 = "http://mock/status/404"
295
+ httpretty .register_uri (
296
+ httpretty .GET ,
297
+ url_404 ,
298
+ status = 404 ,
299
+ )
300
+ result = self .perform_request (url_404 )
301
+ self .assertEqual (result .status_code , 404 )
302
+
303
+ span = self .assert_span ()
304
+
305
+ self .assertEqual (
306
+ span .attributes .get (SpanAttributes .HTTP_RESPONSE_STATUS_CODE ), 404
307
+ )
308
+
309
+ self .assertIs (
310
+ span .status .status_code ,
311
+ trace .StatusCode .ERROR ,
312
+ )
313
+
314
+ def test_not_foundbasic_both_semconv (self ):
315
+ url_404 = "http://mock/status/404"
316
+ httpretty .register_uri (
317
+ httpretty .GET ,
318
+ url_404 ,
319
+ status = 404 ,
320
+ )
321
+ result = self .perform_request (url_404 )
322
+ self .assertEqual (result .status_code , 404 )
323
+
324
+ span = self .assert_span ()
325
+
326
+ self .assertEqual (
327
+ span .attributes .get (SpanAttributes .HTTP_STATUS_CODE ), 404
328
+ )
329
+ self .assertEqual (
330
+ span .attributes .get (SpanAttributes .HTTP_RESPONSE_STATUS_CODE ), 404
331
+ )
332
+
333
+ self .assertIs (
334
+ span .status .status_code ,
335
+ trace .StatusCode .ERROR ,
336
+ )
337
+
262
338
def test_uninstrument (self ):
263
339
RequestsInstrumentor ().uninstrument ()
264
340
result = self .perform_request (self .URL )
@@ -413,6 +489,27 @@ def test_requests_exception_without_response(self, *_, **__):
413
489
)
414
490
self .assertEqual (span .status .status_code , StatusCode .ERROR )
415
491
492
+ @mock .patch (
493
+ "requests.adapters.HTTPAdapter.send" ,
494
+ side_effect = requests .RequestException ,
495
+ )
496
+ def test_requests_exception_new_semconv (self , * _ , ** __ ):
497
+ with self .assertRaises (requests .RequestException ):
498
+ self .perform_request (self .URL )
499
+
500
+ span = self .assert_span ()
501
+ self .assertEqual (
502
+ span .attributes ,
503
+ {
504
+ SpanAttributes .HTTP_REQUEST_METHOD : "GET" ,
505
+ SpanAttributes .URL_FULL : self .URL ,
506
+ SpanAttributes .SERVER_ADDRESS : self .HOST ,
507
+ _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS : "mock" ,
508
+ _SPAN_ATTRIBUTES_ERROR_TYPE : "RequestException" ,
509
+ },
510
+ )
511
+ self .assertEqual (span .status .status_code , StatusCode .ERROR )
512
+
416
513
mocked_response = requests .Response ()
417
514
mocked_response .status_code = 500
418
515
mocked_response .reason = "Internal Server Error"
@@ -534,13 +631,30 @@ class TestRequestsIntergrationMetric(TestBase):
534
631
535
632
def setUp (self ):
536
633
super ().setUp ()
634
+ test_name = ""
635
+ if hasattr (self , "_testMethodName" ):
636
+ test_name = self ._testMethodName
637
+ sem_conv_mode = "default"
638
+ if "new_semconv" in test_name :
639
+ sem_conv_mode = "http"
640
+ elif "both_semconv" in test_name :
641
+ sem_conv_mode = "http/dup"
642
+ self .env_patch = mock .patch .dict (
643
+ "os.environ" ,
644
+ {
645
+ _OTEL_SEMCONV_STABILITY_OPT_IN_KEY : sem_conv_mode ,
646
+ },
647
+ )
648
+ self .env_patch .start ()
649
+ _OpenTelemetrySemanticConventionStability ._initialized = False
537
650
RequestsInstrumentor ().instrument (meter_provider = self .meter_provider )
538
651
539
652
httpretty .enable ()
540
653
httpretty .register_uri (httpretty .GET , self .URL , body = "Hello!" )
541
654
542
655
def tearDown (self ):
543
656
super ().tearDown ()
657
+ self .env_patch .stop ()
544
658
RequestsInstrumentor ().uninstrument ()
545
659
httpretty .disable ()
546
660
@@ -552,22 +666,90 @@ def test_basic_metric_success(self):
552
666
self .perform_request (self .URL )
553
667
554
668
expected_attributes = {
555
- "http.status_code" : 200 ,
556
- "http.host" : "examplehost" ,
557
- "net.peer.port" : 8000 ,
558
- "net.peer.name" : "examplehost" ,
559
- "http.method" : "GET" ,
560
- "http.flavor" : "1.1" ,
561
- "http.scheme" : "http" ,
669
+ SpanAttributes . HTTP_STATUS_CODE : 200 ,
670
+ SpanAttributes . HTTP_HOST : "examplehost" ,
671
+ SpanAttributes . NET_PEER_PORT : 8000 ,
672
+ SpanAttributes . NET_PEER_NAME : "examplehost" ,
673
+ SpanAttributes . HTTP_METHOD : "GET" ,
674
+ SpanAttributes . HTTP_FLAVOR : "1.1" ,
675
+ SpanAttributes . HTTP_SCHEME : "http" ,
562
676
}
563
677
564
678
for (
565
679
resource_metrics
566
680
) in self .memory_metrics_reader .get_metrics_data ().resource_metrics :
567
681
for scope_metrics in resource_metrics .scope_metrics :
682
+ self .assertEqual (len (scope_metrics .metrics ), 1 )
568
683
for metric in scope_metrics .metrics :
684
+ self .assertEqual (metric .unit , "ms" )
685
+ self .assertEqual (metric .description , "measures the duration of the outbound HTTP request" )
569
686
for data_point in metric .data .data_points :
570
687
self .assertDictEqual (
571
688
expected_attributes , dict (data_point .attributes )
572
689
)
573
690
self .assertEqual (data_point .count , 1 )
691
+
692
+ def test_basic_metric_new_semconv (self ):
693
+ self .perform_request (self .URL )
694
+
695
+ expected_attributes = {
696
+ SpanAttributes .HTTP_RESPONSE_STATUS_CODE : 200 ,
697
+ SpanAttributes .SERVER_ADDRESS : "examplehost" ,
698
+ SpanAttributes .SERVER_PORT : 8000 ,
699
+ SpanAttributes .SERVER_ADDRESS : "examplehost" ,
700
+ SpanAttributes .HTTP_REQUEST_METHOD : "GET" ,
701
+ SpanAttributes .NET_PROTOCOL_VERSION : "1.1" ,
702
+ }
703
+
704
+ for (
705
+ resource_metrics
706
+ ) in self .memory_metrics_reader .get_metrics_data ().resource_metrics :
707
+ for scope_metrics in resource_metrics .scope_metrics :
708
+ self .assertEqual (len (scope_metrics .metrics ), 1 )
709
+ for metric in scope_metrics .metrics :
710
+ self .assertEqual (metric .unit , "s" )
711
+ self .assertEqual (metric .description , "Duration of HTTP client requests." )
712
+ for data_point in metric .data .data_points :
713
+ self .assertDictEqual (
714
+ expected_attributes , dict (data_point .attributes )
715
+ )
716
+ self .assertEqual (data_point .count , 1 )
717
+
718
+ def test_basic_metric_both_semconv (self ):
719
+ self .perform_request (self .URL )
720
+
721
+ expected_attributes_old = {
722
+ SpanAttributes .HTTP_STATUS_CODE : 200 ,
723
+ SpanAttributes .HTTP_HOST : "examplehost" ,
724
+ SpanAttributes .NET_PEER_PORT : 8000 ,
725
+ SpanAttributes .NET_PEER_NAME : "examplehost" ,
726
+ SpanAttributes .HTTP_METHOD : "GET" ,
727
+ SpanAttributes .HTTP_FLAVOR : "1.1" ,
728
+ SpanAttributes .HTTP_SCHEME : "http" ,
729
+ }
730
+
731
+ expected_attributes_new = {
732
+ SpanAttributes .HTTP_RESPONSE_STATUS_CODE : 200 ,
733
+ SpanAttributes .SERVER_ADDRESS : "examplehost" ,
734
+ SpanAttributes .SERVER_PORT : 8000 ,
735
+ SpanAttributes .SERVER_ADDRESS : "examplehost" ,
736
+ SpanAttributes .HTTP_REQUEST_METHOD : "GET" ,
737
+ SpanAttributes .NET_PROTOCOL_VERSION : "1.1" ,
738
+ }
739
+
740
+ for (
741
+ resource_metrics
742
+ ) in self .memory_metrics_reader .get_metrics_data ().resource_metrics :
743
+ for scope_metrics in resource_metrics .scope_metrics :
744
+ self .assertEqual (len (scope_metrics .metrics ), 2 )
745
+ for metric in scope_metrics .metrics :
746
+ for data_point in metric .data .data_points :
747
+ if metric .unit == "ms" :
748
+ self .assertDictEqual (
749
+ expected_attributes_old , dict (data_point .attributes )
750
+ )
751
+ else :
752
+ self .assertDictEqual (
753
+ expected_attributes_new , dict (data_point .attributes )
754
+ )
755
+ self .assertEqual (data_point .count , 1 )
0 commit comments