refactor(tornado): replaces SpanAttributes by semconv attributes (#3582)

* refactor: fix import paths

* fix imports

---------

Co-authored-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
This commit is contained in:
f-kanari-safie 2025-06-16 21:09:38 +09:00 committed by GitHub
parent 85dbfe520a
commit 0a03c9abf2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 125 additions and 109 deletions

View File

@ -182,8 +182,19 @@ from opentelemetry.instrumentation.utils import (
from opentelemetry.metrics import get_meter
from opentelemetry.metrics._internal.instrument import Histogram
from opentelemetry.propagators import textmap
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_CLIENT_IP,
HTTP_FLAVOR,
HTTP_HOST,
HTTP_METHOD,
HTTP_SCHEME,
HTTP_STATUS_CODE,
HTTP_TARGET,
)
from opentelemetry.semconv._incubating.attributes.net_attributes import (
NET_PEER_IP,
)
from opentelemetry.semconv.metrics import MetricInstruments
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.util.http import (
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
@ -442,23 +453,21 @@ def _collect_custom_response_headers_attributes(response_headers):
def _get_attributes_from_request(request):
attrs = {
SpanAttributes.HTTP_METHOD: request.method,
SpanAttributes.HTTP_SCHEME: request.protocol,
SpanAttributes.HTTP_HOST: request.host,
SpanAttributes.HTTP_TARGET: request.path,
HTTP_METHOD: request.method,
HTTP_SCHEME: request.protocol,
HTTP_HOST: request.host,
HTTP_TARGET: request.path,
}
if request.remote_ip:
# NET_PEER_IP is the address of the network peer
# HTTP_CLIENT_IP is the address of the client, which might be different
# if Tornado is set to trust X-Forwarded-For headers (xheaders=True)
attrs[SpanAttributes.HTTP_CLIENT_IP] = request.remote_ip
attrs[HTTP_CLIENT_IP] = request.remote_ip
if hasattr(request.connection, "context") and getattr(
request.connection.context, "_orig_remote_ip", None
):
attrs[SpanAttributes.NET_PEER_IP] = (
request.connection.context._orig_remote_ip
)
attrs[NET_PEER_IP] = request.connection.context._orig_remote_ip
return extract_attributes_from_object(
request, _traced_request_attrs, attrs
@ -550,7 +559,7 @@ def _finish_span(tracer, handler, error=None):
return
if ctx.span.is_recording():
ctx.span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
ctx.span.set_attribute(HTTP_STATUS_CODE, status_code)
otel_status_code = http_status_to_status_code(
status_code, server_span=True
)
@ -601,7 +610,7 @@ def _record_on_finish_metrics(server_histograms, handler, error=None):
metric_attributes = _create_metric_attributes(handler)
if isinstance(error, tornado.web.HTTPError):
metric_attributes[SpanAttributes.HTTP_STATUS_CODE] = error.status_code
metric_attributes[HTTP_STATUS_CODE] = error.status_code
server_histograms[MetricInstruments.HTTP_SERVER_RESPONSE_SIZE].record(
response_size, attributes=metric_attributes
@ -621,11 +630,11 @@ def _record_on_finish_metrics(server_histograms, handler, error=None):
def _create_active_requests_attributes(request):
metric_attributes = {
SpanAttributes.HTTP_METHOD: request.method,
SpanAttributes.HTTP_SCHEME: request.protocol,
SpanAttributes.HTTP_FLAVOR: request.version,
SpanAttributes.HTTP_HOST: request.host,
SpanAttributes.HTTP_TARGET: request.path,
HTTP_METHOD: request.method,
HTTP_SCHEME: request.protocol,
HTTP_FLAVOR: request.version,
HTTP_HOST: request.host,
HTTP_TARGET: request.path,
}
return metric_attributes
@ -633,6 +642,6 @@ def _create_active_requests_attributes(request):
def _create_metric_attributes(handler):
metric_attributes = _create_active_requests_attributes(handler.request)
metric_attributes[SpanAttributes.HTTP_STATUS_CODE] = handler.get_status()
metric_attributes[HTTP_STATUS_CODE] = handler.get_status()
return metric_attributes

View File

@ -20,7 +20,11 @@ from tornado.httpclient import HTTPError, HTTPRequest
from opentelemetry import trace
from opentelemetry.instrumentation.utils import http_status_to_status_code
from opentelemetry.propagate import inject
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_METHOD,
HTTP_STATUS_CODE,
HTTP_URL,
)
from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.util.http import remove_url_credentials
@ -75,8 +79,8 @@ def fetch_async(
if span.is_recording():
attributes = {
SpanAttributes.HTTP_URL: remove_url_credentials(request.url),
SpanAttributes.HTTP_METHOD: request.method,
HTTP_URL: remove_url_credentials(request.url),
HTTP_METHOD: request.method,
}
for key, value in attributes.items():
span.set_attribute(key, value)
@ -135,7 +139,7 @@ def _finish_tracing_callback(
)
if status_code is not None:
span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
span.set_attribute(HTTP_STATUS_CODE, status_code)
span.set_status(status)
if response is not None:
@ -160,9 +164,9 @@ def _finish_tracing_callback(
def _create_metric_attributes(response):
metric_attributes = {
SpanAttributes.HTTP_STATUS_CODE: response.code,
SpanAttributes.HTTP_URL: remove_url_credentials(response.request.url),
SpanAttributes.HTTP_METHOD: response.request.method,
HTTP_STATUS_CODE: response.code,
HTTP_URL: remove_url_credentials(response.request.url),
HTTP_METHOD: response.request.method,
}
return metric_attributes

View File

@ -30,7 +30,18 @@ from opentelemetry.instrumentation.tornado import (
patch_handler_class,
unpatch_handler_class,
)
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_CLIENT_IP,
HTTP_HOST,
HTTP_METHOD,
HTTP_SCHEME,
HTTP_STATUS_CODE,
HTTP_TARGET,
HTTP_URL,
)
from opentelemetry.semconv._incubating.attributes.net_attributes import (
NET_PEER_IP,
)
from opentelemetry.test.test_base import TestBase
from opentelemetry.test.wsgitestutil import WsgiTestBase
from opentelemetry.trace import SpanKind, StatusCode
@ -146,13 +157,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: method,
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 201,
HTTP_METHOD: method,
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 201,
"tornado.handler": "tests.tornado_test_app.MainHandler",
},
)
@ -164,9 +174,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/"),
SpanAttributes.HTTP_METHOD: method,
SpanAttributes.HTTP_STATUS_CODE: 201,
HTTP_URL: self.get_url("/"),
HTTP_METHOD: method,
HTTP_STATUS_CODE: 201,
},
)
@ -224,13 +234,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: url,
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 201,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: url,
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 201,
"tornado.handler": f"tests.tornado_test_app.{handler_name}",
},
)
@ -242,9 +251,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url(url),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 201,
HTTP_URL: self.get_url(url),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 201,
},
)
@ -263,13 +272,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/error",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 500,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/error",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 500,
"tornado.handler": "tests.tornado_test_app.BadHandler",
},
)
@ -279,9 +287,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/error"),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 500,
HTTP_URL: self.get_url("/error"),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 500,
},
)
@ -298,13 +306,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/missing-url",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 404,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/missing-url",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 404,
"tornado.handler": "tornado.web.ErrorHandler",
},
)
@ -314,9 +321,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/missing-url"),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 404,
HTTP_URL: self.get_url("/missing-url"),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 404,
},
)
@ -333,13 +340,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/raise_403",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 403,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/raise_403",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 403,
"tornado.handler": "tests.tornado_test_app.RaiseHTTPErrorHandler",
},
)
@ -349,9 +355,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/raise_403"),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 403,
HTTP_URL: self.get_url("/raise_403"),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 403,
},
)
@ -378,13 +384,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/dyna",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 202,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/dyna",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 202,
"tornado.handler": "tests.tornado_test_app.DynamicHandler",
},
)
@ -396,9 +401,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/dyna"),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 202,
HTTP_URL: self.get_url("/dyna"),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 202,
},
)
@ -419,13 +424,12 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
server,
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/on_finish",
SpanAttributes.HTTP_CLIENT_IP: "127.0.0.1",
SpanAttributes.HTTP_STATUS_CODE: 200,
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/on_finish",
HTTP_CLIENT_IP: "127.0.0.1",
HTTP_STATUS_CODE: 200,
"tornado.handler": "tests.tornado_test_app.FinishedHandler",
},
)
@ -437,9 +441,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url("/on_finish"),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 200,
HTTP_URL: self.get_url("/on_finish"),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 200,
},
)
@ -463,9 +467,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: self.get_url(path),
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 200,
HTTP_URL: self.get_url(path),
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 200,
},
)
self.memory_exporter.clear()
@ -518,9 +522,9 @@ class TestTornadoInstrumentation(TornadoTest, WsgiTestBase):
self.assertSpanHasAttributes(
client,
{
SpanAttributes.HTTP_URL: "http://localhost:5000/status/200",
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_STATUS_CODE: 200,
HTTP_URL: "http://localhost:5000/status/200",
HTTP_METHOD: "GET",
HTTP_STATUS_CODE: 200,
},
)
@ -538,14 +542,13 @@ class TestTornadoInstrumentationWithXHeaders(TornadoTest):
self.assertSpanHasAttributes(
spans.by_name("GET /"),
{
SpanAttributes.HTTP_METHOD: "GET",
SpanAttributes.HTTP_SCHEME: "http",
SpanAttributes.HTTP_HOST: "127.0.0.1:"
+ str(self.get_http_port()),
SpanAttributes.HTTP_TARGET: "/",
SpanAttributes.HTTP_CLIENT_IP: "12.34.56.78",
SpanAttributes.HTTP_STATUS_CODE: 201,
SpanAttributes.NET_PEER_IP: "127.0.0.1",
HTTP_METHOD: "GET",
HTTP_SCHEME: "http",
HTTP_HOST: "127.0.0.1:" + str(self.get_http_port()),
HTTP_TARGET: "/",
HTTP_CLIENT_IP: "12.34.56.78",
HTTP_STATUS_CODE: 201,
NET_PEER_IP: "127.0.0.1",
"tornado.handler": "tests.tornado_test_app.MainHandler",
},
)