opentelemetry-instrumentation-tornado 0.47b0__tar.gz → 0.49b0__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.
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/PKG-INFO +4 -4
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/pyproject.toml +3 -3
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/src/opentelemetry/instrumentation/tornado/__init__.py +1 -2
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/src/opentelemetry/instrumentation/tornado/client.py +36 -20
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/src/opentelemetry/instrumentation/tornado/version.py +1 -1
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/tests/test_instrumentation.py +45 -2
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/.gitignore +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/LICENSE +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/README.rst +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/src/opentelemetry/instrumentation/tornado/package.py +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/tests/__init__.py +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/tests/test_metrics_instrumentation.py +0 -0
- {opentelemetry_instrumentation_tornado-0.47b0 → opentelemetry_instrumentation_tornado-0.49b0}/tests/tornado_test_app.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: opentelemetry-instrumentation-tornado
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.49b0
|
4
4
|
Summary: Tornado instrumentation for OpenTelemetry
|
5
5
|
Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-tornado
|
6
6
|
Author-email: OpenTelemetry Authors <cncf-opentelemetry-contributors@lists.cncf.io>
|
@@ -17,9 +17,9 @@ Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
18
18
|
Requires-Python: >=3.8
|
19
19
|
Requires-Dist: opentelemetry-api~=1.12
|
20
|
-
Requires-Dist: opentelemetry-instrumentation==0.
|
21
|
-
Requires-Dist: opentelemetry-semantic-conventions==0.
|
22
|
-
Requires-Dist: opentelemetry-util-http==0.
|
20
|
+
Requires-Dist: opentelemetry-instrumentation==0.49b0
|
21
|
+
Requires-Dist: opentelemetry-semantic-conventions==0.49b0
|
22
|
+
Requires-Dist: opentelemetry-util-http==0.49b0
|
23
23
|
Provides-Extra: instruments
|
24
24
|
Requires-Dist: tornado>=5.1.1; extra == 'instruments'
|
25
25
|
Description-Content-Type: text/x-rst
|
@@ -25,9 +25,9 @@ classifiers = [
|
|
25
25
|
]
|
26
26
|
dependencies = [
|
27
27
|
"opentelemetry-api ~= 1.12",
|
28
|
-
"opentelemetry-instrumentation == 0.
|
29
|
-
"opentelemetry-semantic-conventions == 0.
|
30
|
-
"opentelemetry-util-http == 0.
|
28
|
+
"opentelemetry-instrumentation == 0.49b0",
|
29
|
+
"opentelemetry-semantic-conventions == 0.49b0",
|
30
|
+
"opentelemetry-util-http == 0.49b0",
|
31
31
|
]
|
32
32
|
|
33
33
|
[project.optional-dependencies]
|
@@ -152,7 +152,6 @@ API
|
|
152
152
|
---
|
153
153
|
"""
|
154
154
|
|
155
|
-
|
156
155
|
from collections import namedtuple
|
157
156
|
from functools import partial
|
158
157
|
from logging import getLogger
|
@@ -296,7 +295,7 @@ def _create_server_histograms(meter) -> Dict[str, Histogram]:
|
|
296
295
|
MetricInstruments.HTTP_SERVER_DURATION: meter.create_histogram(
|
297
296
|
name=MetricInstruments.HTTP_SERVER_DURATION,
|
298
297
|
unit="ms",
|
299
|
-
description="
|
298
|
+
description="Measures the duration of inbound HTTP requests.",
|
300
299
|
),
|
301
300
|
MetricInstruments.HTTP_SERVER_REQUEST_SIZE: meter.create_histogram(
|
302
301
|
name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE,
|
@@ -21,7 +21,7 @@ from opentelemetry import trace
|
|
21
21
|
from opentelemetry.instrumentation.utils import http_status_to_status_code
|
22
22
|
from opentelemetry.propagate import inject
|
23
23
|
from opentelemetry.semconv.trace import SpanAttributes
|
24
|
-
from opentelemetry.trace.status import Status
|
24
|
+
from opentelemetry.trace.status import Status, StatusCode
|
25
25
|
from opentelemetry.util.http import remove_url_credentials
|
26
26
|
|
27
27
|
|
@@ -105,37 +105,53 @@ def _finish_tracing_callback(
|
|
105
105
|
request_size_histogram,
|
106
106
|
response_size_histogram,
|
107
107
|
):
|
108
|
+
response = None
|
108
109
|
status_code = None
|
110
|
+
status = None
|
109
111
|
description = None
|
110
|
-
exc = future.exception()
|
111
|
-
|
112
|
-
response = future.result()
|
113
112
|
|
114
|
-
|
113
|
+
exc = future.exception()
|
114
|
+
if exc:
|
115
|
+
description = f"{type(exc).__qualname__}: {exc}"
|
115
116
|
if isinstance(exc, HTTPError):
|
117
|
+
response = exc.response
|
116
118
|
status_code = exc.code
|
117
|
-
|
119
|
+
status = Status(
|
120
|
+
status_code=http_status_to_status_code(status_code),
|
121
|
+
description=description,
|
122
|
+
)
|
123
|
+
else:
|
124
|
+
status = Status(
|
125
|
+
status_code=StatusCode.ERROR,
|
126
|
+
description=description,
|
127
|
+
)
|
128
|
+
span.record_exception(exc)
|
118
129
|
else:
|
130
|
+
response = future.result()
|
119
131
|
status_code = response.code
|
132
|
+
status = Status(
|
133
|
+
status_code=http_status_to_status_code(status_code),
|
134
|
+
description=description,
|
135
|
+
)
|
120
136
|
|
121
137
|
if status_code is not None:
|
122
138
|
span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
|
123
|
-
|
124
|
-
Status(
|
125
|
-
status_code=http_status_to_status_code(status_code),
|
126
|
-
description=description,
|
127
|
-
)
|
128
|
-
)
|
139
|
+
span.set_status(status)
|
129
140
|
|
130
|
-
|
131
|
-
|
132
|
-
|
141
|
+
if response is not None:
|
142
|
+
metric_attributes = _create_metric_attributes(response)
|
143
|
+
request_size = int(response.request.headers.get("Content-Length", 0))
|
144
|
+
response_size = int(response.headers.get("Content-Length", 0))
|
133
145
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
146
|
+
duration_histogram.record(
|
147
|
+
response.request_time, attributes=metric_attributes
|
148
|
+
)
|
149
|
+
request_size_histogram.record(
|
150
|
+
request_size, attributes=metric_attributes
|
151
|
+
)
|
152
|
+
response_size_histogram.record(
|
153
|
+
response_size, attributes=metric_attributes
|
154
|
+
)
|
139
155
|
|
140
156
|
if response_hook:
|
141
157
|
response_hook(span, future)
|
@@ -16,6 +16,7 @@
|
|
16
16
|
from unittest.mock import Mock, patch
|
17
17
|
|
18
18
|
from http_server_mock import HttpServerMock
|
19
|
+
from tornado.httpclient import HTTPClientError
|
19
20
|
from tornado.testing import AsyncHTTPTestCase
|
20
21
|
|
21
22
|
from opentelemetry import trace
|
@@ -32,7 +33,7 @@ from opentelemetry.instrumentation.tornado import (
|
|
32
33
|
from opentelemetry.semconv.trace import SpanAttributes
|
33
34
|
from opentelemetry.test.test_base import TestBase
|
34
35
|
from opentelemetry.test.wsgitestutil import WsgiTestBase
|
35
|
-
from opentelemetry.trace import SpanKind
|
36
|
+
from opentelemetry.trace import SpanKind, StatusCode
|
36
37
|
from opentelemetry.util.http import (
|
37
38
|
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
|
38
39
|
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE,
|
@@ -493,7 +494,6 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
|
|
493
494
|
self.assertEqual(len(spans), 3)
|
494
495
|
self.assertTraceResponseHeaderMatchesSpan(response.headers, spans[1])
|
495
496
|
|
496
|
-
self.memory_exporter.clear()
|
497
497
|
set_global_response_propagator(orig)
|
498
498
|
|
499
499
|
def test_credential_removal(self):
|
@@ -602,6 +602,49 @@ class TornadoHookTest(TornadoTest):
|
|
602
602
|
self.memory_exporter.clear()
|
603
603
|
|
604
604
|
|
605
|
+
class TestTornadoHTTPClientInstrumentation(TornadoTest, WsgiTestBase):
|
606
|
+
def test_http_client_success_response(self):
|
607
|
+
response = self.fetch("/")
|
608
|
+
self.assertEqual(response.code, 201)
|
609
|
+
|
610
|
+
spans = self.memory_exporter.get_finished_spans()
|
611
|
+
self.assertEqual(len(spans), 3)
|
612
|
+
manual, server, client = self.sorted_spans(spans)
|
613
|
+
self.assertEqual(manual.name, "manual")
|
614
|
+
self.assertEqual(server.name, "GET /")
|
615
|
+
self.assertEqual(client.name, "GET")
|
616
|
+
self.assertEqual(client.status.status_code, StatusCode.UNSET)
|
617
|
+
self.memory_exporter.clear()
|
618
|
+
|
619
|
+
def test_http_client_failed_response(self):
|
620
|
+
# when an exception isn't thrown
|
621
|
+
response = self.fetch("/some-404")
|
622
|
+
self.assertEqual(response.code, 404)
|
623
|
+
|
624
|
+
spans = self.memory_exporter.get_finished_spans()
|
625
|
+
self.assertEqual(len(spans), 2)
|
626
|
+
server, client = self.sorted_spans(spans)
|
627
|
+
self.assertEqual(server.name, "GET /some-404")
|
628
|
+
self.assertEqual(client.name, "GET")
|
629
|
+
self.assertEqual(client.status.status_code, StatusCode.ERROR)
|
630
|
+
self.memory_exporter.clear()
|
631
|
+
|
632
|
+
# when an exception is thrown
|
633
|
+
try:
|
634
|
+
response = self.fetch("/some-404", raise_error=True)
|
635
|
+
self.assertEqual(response.code, 404)
|
636
|
+
except HTTPClientError:
|
637
|
+
pass # expected exception - continue
|
638
|
+
|
639
|
+
spans = self.memory_exporter.get_finished_spans()
|
640
|
+
self.assertEqual(len(spans), 2)
|
641
|
+
server, client = self.sorted_spans(spans)
|
642
|
+
self.assertEqual(server.name, "GET /some-404")
|
643
|
+
self.assertEqual(client.name, "GET")
|
644
|
+
self.assertEqual(client.status.status_code, StatusCode.ERROR)
|
645
|
+
self.memory_exporter.clear()
|
646
|
+
|
647
|
+
|
605
648
|
class TestTornadoUninstrument(TornadoTest):
|
606
649
|
def test_uninstrument(self):
|
607
650
|
response = self.fetch("/")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|