|
12 | 12 | # See the License for the specific language governing permissions and
|
13 | 13 | # limitations under the License.
|
14 | 14 |
|
| 15 | +import io |
15 | 16 | from timeit import default_timer
|
16 | 17 |
|
| 18 | +import httpretty |
17 | 19 | import urllib3
|
18 | 20 | import urllib3.exceptions
|
19 | 21 | from urllib3.request import encode_multipart_formdata
|
|
23 | 25 | from opentelemetry.test.test_base import TestBase
|
24 | 26 |
|
25 | 27 |
|
26 |
| -class TestUrllib3MetricsInstrumentation(HttpTestBase, TestBase): |
| 28 | +class TestURLLib3InstrumentorMetric(HttpTestBase, TestBase): |
| 29 | + HTTP_URL = "http://httpbin.org/status/200" |
| 30 | + |
27 | 31 | def setUp(self):
|
28 | 32 | super().setUp()
|
29 |
| - self.assert_ip = self.server.server_address[0] |
30 |
| - self.assert_port = self.server.server_address[1] |
31 |
| - self.http_host = ":".join(map(str, self.server.server_address[:2])) |
32 |
| - self.http_url_base = "http://" + self.http_host |
33 |
| - self.http_url = self.http_url_base + "/status/200" |
34 |
| - URLLib3Instrumentor().instrument(meter_provider=self.meter_provider) |
| 33 | + URLLib3Instrumentor().instrument() |
| 34 | + httpretty.enable(allow_net_connect=False) |
| 35 | + httpretty.register_uri(httpretty.GET, self.HTTP_URL, body="Hello!") |
| 36 | + httpretty.register_uri(httpretty.POST, self.HTTP_URL, body="Hello!") |
| 37 | + self.pool = urllib3.PoolManager() |
35 | 38 |
|
36 | 39 | def tearDown(self):
|
37 | 40 | super().tearDown()
|
| 41 | + self.pool.clear() |
38 | 42 | URLLib3Instrumentor().uninstrument()
|
39 | 43 |
|
40 |
| - # Return Sequence with one histogram |
41 |
| - def create_histogram_data_points(self, sum_data_point, attributes): |
42 |
| - return [ |
43 |
| - self.create_histogram_data_point( |
44 |
| - sum_data_point, 1, sum_data_point, sum_data_point, attributes |
45 |
| - ) |
46 |
| - ] |
47 |
| - |
48 |
| - def test_basic_metric_check_client_size_get(self): |
49 |
| - with urllib3.PoolManager() as pool: |
50 |
| - start_time = default_timer() |
51 |
| - response = pool.request("GET", self.http_url) |
52 |
| - client_duration_estimated = (default_timer() - start_time) * 1000 |
53 |
| - |
54 |
| - metrics = self.get_sorted_metrics() |
55 |
| - |
56 |
| - ( |
57 |
| - client_duration, |
58 |
| - client_request_size, |
59 |
| - client_response_size, |
60 |
| - ) = metrics |
61 |
| - |
62 |
| - self.assertEqual(client_duration.name, "http.client.duration") |
63 |
| - self.assert_metric_expected( |
64 |
| - client_duration, |
65 |
| - self.create_histogram_data_points( |
66 |
| - client_duration_estimated, |
| 44 | + httpretty.disable() |
| 45 | + httpretty.reset() |
| 46 | + |
| 47 | + def test_basic_metrics(self): |
| 48 | + start_time = default_timer() |
| 49 | + response = self.pool.request("GET", self.HTTP_URL) |
| 50 | + client_duration_estimated = (default_timer() - start_time) * 1000 |
| 51 | + |
| 52 | + metrics = self.get_sorted_metrics() |
| 53 | + |
| 54 | + ( |
| 55 | + client_duration, |
| 56 | + client_request_size, |
| 57 | + client_response_size, |
| 58 | + ) = metrics |
| 59 | + |
| 60 | + self.assertEqual(client_duration.name, "http.client.duration") |
| 61 | + self.assert_metric_expected( |
| 62 | + client_duration, |
| 63 | + [ |
| 64 | + self.create_histogram_data_point( |
| 65 | + count=1, |
| 66 | + sum_data_point=client_duration_estimated, |
| 67 | + max_data_point=client_duration_estimated, |
| 68 | + min_data_point=client_duration_estimated, |
67 | 69 | attributes={
|
68 |
| - "http.status_code": 200, |
69 |
| - "http.host": self.assert_ip, |
70 |
| - "http.method": "GET", |
71 | 70 | "http.flavor": "1.1",
|
| 71 | + "http.host": "httpbin.org", |
| 72 | + "http.method": "GET", |
72 | 73 | "http.scheme": "http",
|
73 |
| - "net.peer.name": self.assert_ip, |
74 |
| - "net.peer.port": self.assert_port, |
| 74 | + "http.status_code": 200, |
| 75 | + "net.peer.name": "httpbin.org", |
| 76 | + "net.peer.port": 80, |
75 | 77 | },
|
76 |
| - ), |
77 |
| - est_value_delta=200, |
78 |
| - ) |
79 |
| - |
80 |
| - self.assertEqual( |
81 |
| - client_request_size.name, "http.client.request.size" |
82 |
| - ) |
83 |
| - self.assert_metric_expected( |
84 |
| - client_request_size, |
85 |
| - self.create_histogram_data_points( |
86 |
| - 0, |
| 78 | + ) |
| 79 | + ], |
| 80 | + est_value_delta=200, |
| 81 | + ) |
| 82 | + |
| 83 | + self.assertEqual(client_request_size.name, "http.client.request.size") |
| 84 | + self.assert_metric_expected( |
| 85 | + client_request_size, |
| 86 | + [ |
| 87 | + self.create_histogram_data_point( |
| 88 | + count=1, |
| 89 | + sum_data_point=0, |
| 90 | + max_data_point=0, |
| 91 | + min_data_point=0, |
87 | 92 | attributes={
|
88 |
| - "http.status_code": 200, |
89 |
| - "http.host": self.assert_ip, |
90 |
| - "http.method": "GET", |
91 | 93 | "http.flavor": "1.1",
|
| 94 | + "http.host": "httpbin.org", |
| 95 | + "http.method": "GET", |
92 | 96 | "http.scheme": "http",
|
93 |
| - "net.peer.name": self.assert_ip, |
94 |
| - "net.peer.port": self.assert_port, |
| 97 | + "http.status_code": 200, |
| 98 | + "net.peer.name": "httpbin.org", |
| 99 | + "net.peer.port": 80, |
95 | 100 | },
|
96 |
| - ), |
97 |
| - ) |
98 |
| - |
99 |
| - self.assertEqual( |
100 |
| - client_response_size.name, "http.client.response.size" |
101 |
| - ) |
102 |
| - self.assert_metric_expected( |
103 |
| - client_response_size, |
104 |
| - self.create_histogram_data_points( |
105 |
| - len(response.data), |
| 101 | + ) |
| 102 | + ], |
| 103 | + ) |
| 104 | + |
| 105 | + expected_size = len(response.data) |
| 106 | + self.assertEqual( |
| 107 | + client_response_size.name, "http.client.response.size" |
| 108 | + ) |
| 109 | + self.assert_metric_expected( |
| 110 | + client_response_size, |
| 111 | + [ |
| 112 | + self.create_histogram_data_point( |
| 113 | + count=1, |
| 114 | + sum_data_point=expected_size, |
| 115 | + max_data_point=expected_size, |
| 116 | + min_data_point=expected_size, |
106 | 117 | attributes={
|
107 |
| - "http.status_code": 200, |
108 |
| - "http.host": self.assert_ip, |
109 |
| - "http.method": "GET", |
110 | 118 | "http.flavor": "1.1",
|
| 119 | + "http.host": "httpbin.org", |
| 120 | + "http.method": "GET", |
111 | 121 | "http.scheme": "http",
|
112 |
| - "net.peer.name": self.assert_ip, |
113 |
| - "net.peer.port": self.assert_port, |
| 122 | + "http.status_code": 200, |
| 123 | + "net.peer.name": "httpbin.org", |
| 124 | + "net.peer.port": 80, |
114 | 125 | },
|
115 |
| - ), |
116 |
| - ) |
117 |
| - |
118 |
| - def test_basic_metric_check_client_size_post(self): |
119 |
| - with urllib3.PoolManager() as pool: |
120 |
| - start_time = default_timer() |
121 |
| - data_fields = {"data": "test"} |
122 |
| - response = pool.request("POST", self.http_url, fields=data_fields) |
123 |
| - client_duration_estimated = (default_timer() - start_time) * 1000 |
124 |
| - body = encode_multipart_formdata(data_fields)[0] |
125 |
| - |
126 |
| - metrics = self.get_sorted_metrics() |
127 |
| - |
128 |
| - ( |
129 |
| - client_duration, |
130 |
| - client_request_size, |
131 |
| - client_response_size, |
132 |
| - ) = metrics |
133 |
| - |
134 |
| - self.assertEqual(client_duration.name, "http.client.duration") |
135 |
| - self.assert_metric_expected( |
136 |
| - client_duration, |
137 |
| - self.create_histogram_data_points( |
138 |
| - client_duration_estimated, |
| 126 | + ) |
| 127 | + ], |
| 128 | + ) |
| 129 | + |
| 130 | + def test_str_request_body_size_metrics(self): |
| 131 | + self.pool.request("POST", self.HTTP_URL, body="foobar") |
| 132 | + |
| 133 | + metrics = self.get_sorted_metrics() |
| 134 | + (_, client_request_size, _) = metrics |
| 135 | + |
| 136 | + self.assertEqual(client_request_size.name, "http.client.request.size") |
| 137 | + self.assert_metric_expected( |
| 138 | + client_request_size, |
| 139 | + [ |
| 140 | + self.create_histogram_data_point( |
| 141 | + count=1, |
| 142 | + sum_data_point=6, |
| 143 | + max_data_point=6, |
| 144 | + min_data_point=6, |
139 | 145 | attributes={
|
140 |
| - "http.status_code": 501, |
141 |
| - "http.host": self.assert_ip, |
142 |
| - "http.method": "POST", |
143 | 146 | "http.flavor": "1.1",
|
| 147 | + "http.host": "httpbin.org", |
| 148 | + "http.method": "POST", |
144 | 149 | "http.scheme": "http",
|
145 |
| - "net.peer.name": self.assert_ip, |
146 |
| - "net.peer.port": self.assert_port, |
| 150 | + "http.status_code": 200, |
| 151 | + "net.peer.name": "httpbin.org", |
| 152 | + "net.peer.port": 80, |
147 | 153 | },
|
148 |
| - ), |
149 |
| - est_value_delta=200, |
150 |
| - ) |
151 |
| - |
152 |
| - self.assertEqual( |
153 |
| - client_request_size.name, "http.client.request.size" |
154 |
| - ) |
155 |
| - client_request_size_expected = len(body) |
156 |
| - self.assert_metric_expected( |
157 |
| - client_request_size, |
158 |
| - self.create_histogram_data_points( |
159 |
| - client_request_size_expected, |
| 154 | + ) |
| 155 | + ], |
| 156 | + ) |
| 157 | + |
| 158 | + def test_bytes_request_body_size_metrics(self): |
| 159 | + self.pool.request("POST", self.HTTP_URL, body=b"foobar") |
| 160 | + |
| 161 | + metrics = self.get_sorted_metrics() |
| 162 | + (_, client_request_size, _) = metrics |
| 163 | + |
| 164 | + self.assertEqual(client_request_size.name, "http.client.request.size") |
| 165 | + self.assert_metric_expected( |
| 166 | + client_request_size, |
| 167 | + [ |
| 168 | + self.create_histogram_data_point( |
| 169 | + count=1, |
| 170 | + sum_data_point=6, |
| 171 | + max_data_point=6, |
| 172 | + min_data_point=6, |
160 | 173 | attributes={
|
161 |
| - "http.status_code": 501, |
162 |
| - "http.host": self.assert_ip, |
163 |
| - "http.method": "POST", |
164 | 174 | "http.flavor": "1.1",
|
| 175 | + "http.host": "httpbin.org", |
| 176 | + "http.method": "POST", |
165 | 177 | "http.scheme": "http",
|
166 |
| - "net.peer.name": self.assert_ip, |
167 |
| - "net.peer.port": self.assert_port, |
| 178 | + "http.status_code": 200, |
| 179 | + "net.peer.name": "httpbin.org", |
| 180 | + "net.peer.port": 80, |
168 | 181 | },
|
169 |
| - ), |
170 |
| - ) |
171 |
| - |
172 |
| - self.assertEqual( |
173 |
| - client_response_size.name, "http.client.response.size" |
174 |
| - ) |
175 |
| - client_response_size_expected = len(response.data) |
176 |
| - self.assert_metric_expected( |
177 |
| - client_response_size, |
178 |
| - self.create_histogram_data_points( |
179 |
| - client_response_size_expected, |
| 182 | + ) |
| 183 | + ], |
| 184 | + ) |
| 185 | + |
| 186 | + def test_fields_request_body_size_metrics(self): |
| 187 | + self.pool.request("POST", self.HTTP_URL, fields={"foo": "bar"}) |
| 188 | + |
| 189 | + metrics = self.get_sorted_metrics() |
| 190 | + (_, client_request_size, _) = metrics |
| 191 | + |
| 192 | + self.assertEqual(client_request_size.name, "http.client.request.size") |
| 193 | + expected_value = len(encode_multipart_formdata({"foo": "bar"})[0]) |
| 194 | + self.assert_metric_expected( |
| 195 | + client_request_size, |
| 196 | + [ |
| 197 | + self.create_histogram_data_point( |
| 198 | + count=1, |
| 199 | + sum_data_point=expected_value, |
| 200 | + max_data_point=expected_value, |
| 201 | + min_data_point=expected_value, |
180 | 202 | attributes={
|
181 |
| - "http.status_code": 501, |
182 |
| - "http.host": self.assert_ip, |
| 203 | + "http.flavor": "1.1", |
| 204 | + "http.host": "httpbin.org", |
183 | 205 | "http.method": "POST",
|
| 206 | + "http.scheme": "http", |
| 207 | + "http.status_code": 200, |
| 208 | + "net.peer.name": "httpbin.org", |
| 209 | + "net.peer.port": 80, |
| 210 | + }, |
| 211 | + ) |
| 212 | + ], |
| 213 | + ) |
| 214 | + |
| 215 | + def test_bytesio_request_body_size_metrics(self): |
| 216 | + self.pool.request("POST", self.HTTP_URL, body=io.BytesIO(b"foobar")) |
| 217 | + |
| 218 | + metrics = self.get_sorted_metrics() |
| 219 | + (_, client_request_size, _) = metrics |
| 220 | + |
| 221 | + self.assertEqual(client_request_size.name, "http.client.request.size") |
| 222 | + self.assert_metric_expected( |
| 223 | + client_request_size, |
| 224 | + [ |
| 225 | + self.create_histogram_data_point( |
| 226 | + count=1, |
| 227 | + sum_data_point=6, |
| 228 | + max_data_point=6, |
| 229 | + min_data_point=6, |
| 230 | + attributes={ |
184 | 231 | "http.flavor": "1.1",
|
| 232 | + "http.host": "httpbin.org", |
| 233 | + "http.method": "POST", |
185 | 234 | "http.scheme": "http",
|
186 |
| - "net.peer.name": self.assert_ip, |
187 |
| - "net.peer.port": self.assert_port, |
| 235 | + "http.status_code": 200, |
| 236 | + "net.peer.name": "httpbin.org", |
| 237 | + "net.peer.port": 80, |
188 | 238 | },
|
189 |
| - ), |
190 |
| - ) |
| 239 | + ) |
| 240 | + ], |
| 241 | + ) |
| 242 | + |
| 243 | + def test_generator_request_body_size_metrics(self): |
| 244 | + self.pool.request( |
| 245 | + "POST", self.HTTP_URL, body=(b for b in (b"foo", b"bar")) |
| 246 | + ) |
| 247 | + |
| 248 | + metrics = self.get_sorted_metrics() |
| 249 | + self.assertEqual(len(metrics), 2) |
| 250 | + self.assertNotIn("http.client.request.size", [m.name for m in metrics]) |
191 | 251 |
|
192 | 252 | def test_metric_uninstrument(self):
|
193 |
| - with urllib3.PoolManager() as pool: |
194 |
| - pool.request("GET", self.http_url) |
195 |
| - URLLib3Instrumentor().uninstrument() |
196 |
| - pool.request("GET", self.http_url) |
| 253 | + self.pool.request("GET", self.HTTP_URL) |
| 254 | + URLLib3Instrumentor().uninstrument() |
| 255 | + self.pool.request("GET", self.HTTP_URL) |
197 | 256 |
|
198 |
| - metrics = self.get_sorted_metrics() |
199 |
| - self.assertEqual(len(metrics), 3) |
| 257 | + metrics = self.get_sorted_metrics() |
| 258 | + self.assertEqual(len(metrics), 3) |
200 | 259 |
|
201 |
| - for metric in metrics: |
202 |
| - for point in list(metric.data.data_points): |
203 |
| - self.assertEqual(point.count, 1) |
| 260 | + for metric in metrics: |
| 261 | + for point in list(metric.data.data_points): |
| 262 | + self.assertEqual(point.count, 1) |
0 commit comments