mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
prepare semconv utilities to support database stability opt-in (#3111)
This commit is contained in:
@ -11,11 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- Add support to database stability opt-in in `_semconv` utilities and add tests
|
||||
([#3111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3111))
|
||||
|
||||
### Fixed
|
||||
|
||||
- `opentelemetry-instrumentation-httpx` Fix `RequestInfo`/`ResponseInfo` type hints
|
||||
([#3105](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3105))
|
||||
|
||||
|
||||
## Version 1.29.0/0.50b0 (2024-12-11)
|
||||
|
||||
### Added
|
||||
|
@ -92,13 +92,13 @@ from opentelemetry import context as context_api
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
_set_http_method,
|
||||
_set_http_url,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.aiohttp_client.package import _instruments
|
||||
from opentelemetry.instrumentation.aiohttp_client.version import __version__
|
||||
@ -142,7 +142,7 @@ def _set_http_status_code_attribute(
|
||||
span,
|
||||
status_code,
|
||||
metric_attributes=None,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
status_code_str = str(status_code)
|
||||
try:
|
||||
@ -169,7 +169,7 @@ def create_trace_config(
|
||||
request_hook: _RequestHookT = None,
|
||||
response_hook: _ResponseHookT = None,
|
||||
tracer_provider: TracerProvider = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
) -> aiohttp.TraceConfig:
|
||||
"""Create an aiohttp-compatible trace configuration.
|
||||
|
||||
@ -326,7 +326,7 @@ def _instrument(
|
||||
trace_configs: typing.Optional[
|
||||
typing.Sequence[aiohttp.TraceConfig]
|
||||
] = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
"""Enables tracing of all ClientSessions
|
||||
|
||||
|
@ -29,8 +29,8 @@ from opentelemetry import trace as trace_api
|
||||
from opentelemetry.instrumentation import aiohttp_client
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.aiohttp_client import (
|
||||
AioHttpClientInstrumentor,
|
||||
@ -150,7 +150,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
path = "test-path?query=param#foobar"
|
||||
host, port = self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP
|
||||
),
|
||||
url=f"/{path}",
|
||||
status_code=status_code,
|
||||
@ -173,7 +173,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
path = "test-path?query=param#foobar"
|
||||
host, port = self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP
|
||||
),
|
||||
url=f"/{path}",
|
||||
status_code=status_code,
|
||||
@ -213,7 +213,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
with self.subTest(status_code=200):
|
||||
self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP
|
||||
),
|
||||
url="/test-path?query=param#foobar",
|
||||
status_code=200,
|
||||
@ -230,7 +230,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
with self.subTest(status_code=200):
|
||||
self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP
|
||||
),
|
||||
url="/test-path?query=param#foobar",
|
||||
status_code=200,
|
||||
@ -398,7 +398,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
|
||||
host, port = self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP
|
||||
),
|
||||
url="/test",
|
||||
request_handler=request_handler,
|
||||
@ -426,7 +426,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
|
||||
host, port = self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP
|
||||
),
|
||||
url="/test",
|
||||
request_handler=request_handler,
|
||||
@ -546,7 +546,7 @@ class TestAioHttpIntegration(TestBase):
|
||||
def test_nonstandard_http_method_new_semconv(self):
|
||||
trace_configs = [
|
||||
aiohttp_client.create_trace_config(
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP
|
||||
)
|
||||
]
|
||||
app = HttpServerMock("nonstandard_method")
|
||||
|
@ -205,7 +205,6 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_filter_semconv_active_request_count_attr,
|
||||
_filter_semconv_duration_attrs,
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -225,6 +224,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_url,
|
||||
_set_http_user_agent,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.asgi.types import (
|
||||
ClientRequestHook,
|
||||
@ -324,7 +324,7 @@ asgi_setter = ASGISetter()
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
def collect_request_attributes(
|
||||
scope, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
scope, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
"""Collects HTTP request attributes from the ASGI scope and returns a
|
||||
dictionary to be used as span creation attributes."""
|
||||
@ -356,7 +356,7 @@ def collect_request_attributes(
|
||||
_set_http_url(
|
||||
result,
|
||||
remove_url_credentials(http_url),
|
||||
_HTTPStabilityMode.DEFAULT,
|
||||
_StabilityMode.DEFAULT,
|
||||
)
|
||||
http_method = scope.get("method", "")
|
||||
if http_method:
|
||||
@ -439,7 +439,7 @@ def set_status_code(
|
||||
span,
|
||||
status_code,
|
||||
metric_attributes=None,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
"""Adds HTTP response attributes to span using the status_code argument."""
|
||||
status_code_str = str(status_code)
|
||||
@ -755,12 +755,12 @@ class OpenTelemetryMiddleware:
|
||||
)
|
||||
duration_s = default_timer() - start
|
||||
duration_attrs_old = _parse_duration_attrs(
|
||||
attributes, _HTTPStabilityMode.DEFAULT
|
||||
attributes, _StabilityMode.DEFAULT
|
||||
)
|
||||
if target:
|
||||
duration_attrs_old[SpanAttributes.HTTP_TARGET] = target
|
||||
duration_attrs_new = _parse_duration_attrs(
|
||||
attributes, _HTTPStabilityMode.HTTP
|
||||
attributes, _StabilityMode.HTTP
|
||||
)
|
||||
if self.duration_histogram_old:
|
||||
self.duration_histogram_old.record(
|
||||
@ -960,7 +960,7 @@ class OpenTelemetryMiddleware:
|
||||
|
||||
|
||||
def _parse_duration_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_duration_attrs(
|
||||
req_attrs,
|
||||
@ -971,7 +971,7 @@ def _parse_duration_attrs(
|
||||
|
||||
|
||||
def _parse_active_request_count_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_active_request_count_attr(
|
||||
req_attrs,
|
||||
|
@ -24,12 +24,12 @@ import opentelemetry.instrumentation.asgi as otel_asgi
|
||||
from opentelemetry import trace as trace_api
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_server_active_requests_count_attrs_new,
|
||||
_server_active_requests_count_attrs_old,
|
||||
_server_duration_attrs_new,
|
||||
_server_duration_attrs_old,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.propagators import (
|
||||
TraceResponsePropagator,
|
||||
@ -1652,7 +1652,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
|
||||
attrs = otel_asgi.collect_request_attributes(
|
||||
self.scope,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
self.assertDictEqual(
|
||||
@ -1677,7 +1677,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
|
||||
attrs = otel_asgi.collect_request_attributes(
|
||||
self.scope,
|
||||
_HTTPStabilityMode.HTTP_DUP,
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
|
||||
self.assertDictEqual(
|
||||
@ -1715,7 +1715,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
self.scope["query_string"] = b"foo=bar"
|
||||
attrs = otel_asgi.collect_request_attributes(
|
||||
self.scope,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
self.assertEqual(attrs[URL_SCHEME], "http")
|
||||
self.assertEqual(attrs[CLIENT_ADDRESS], "127.0.0.1")
|
||||
@ -1726,7 +1726,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
self.scope["query_string"] = b"foo=bar"
|
||||
attrs = otel_asgi.collect_request_attributes(
|
||||
self.scope,
|
||||
_HTTPStabilityMode.HTTP_DUP,
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
self.assertEqual(
|
||||
attrs[SpanAttributes.HTTP_URL], "http://127.0.0.1/?foo=bar"
|
||||
@ -1762,7 +1762,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
self.span,
|
||||
404,
|
||||
None,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
expected = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),)
|
||||
self.assertEqual(self.span.set_attribute.call_count, 1)
|
||||
@ -1774,7 +1774,7 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
self.span,
|
||||
404,
|
||||
None,
|
||||
_HTTPStabilityMode.HTTP_DUP,
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
expected = (mock.call(SpanAttributes.HTTP_STATUS_CODE, 404),)
|
||||
expected2 = (mock.call(HTTP_RESPONSE_STATUS_CODE, 404),)
|
||||
|
@ -25,13 +25,13 @@ from opentelemetry.context import detach
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
_filter_semconv_active_request_count_attr,
|
||||
_filter_semconv_duration_attrs,
|
||||
_HTTPStabilityMode,
|
||||
_report_new,
|
||||
_report_old,
|
||||
_server_active_requests_count_attrs_new,
|
||||
_server_active_requests_count_attrs_old,
|
||||
_server_duration_attrs_new,
|
||||
_server_duration_attrs_old,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.propagators import (
|
||||
get_global_response_propagator,
|
||||
@ -158,7 +158,7 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
_duration_histogram_old = None
|
||||
_duration_histogram_new = None
|
||||
_active_request_counter = None
|
||||
_sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT
|
||||
_sem_conv_opt_in_mode = _StabilityMode.DEFAULT
|
||||
|
||||
_otel_request_hook: Callable[[Span, HttpRequest], None] = None
|
||||
_otel_response_hook: Callable[[Span, HttpRequest, HttpResponse], None] = (
|
||||
@ -430,7 +430,7 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
duration_s = default_timer() - request_start_time
|
||||
if self._duration_histogram_old:
|
||||
duration_attrs_old = _parse_duration_attrs(
|
||||
duration_attrs, _HTTPStabilityMode.DEFAULT
|
||||
duration_attrs, _StabilityMode.DEFAULT
|
||||
)
|
||||
# http.target to be included in old semantic conventions
|
||||
target = duration_attrs.get(SpanAttributes.HTTP_TARGET)
|
||||
@ -441,7 +441,7 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
)
|
||||
if self._duration_histogram_new:
|
||||
duration_attrs_new = _parse_duration_attrs(
|
||||
duration_attrs, _HTTPStabilityMode.HTTP
|
||||
duration_attrs, _StabilityMode.HTTP
|
||||
)
|
||||
self._duration_histogram_new.record(
|
||||
max(duration_s, 0), duration_attrs_new
|
||||
@ -455,7 +455,7 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
|
||||
|
||||
def _parse_duration_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_duration_attrs(
|
||||
req_attrs,
|
||||
@ -466,7 +466,7 @@ def _parse_duration_attrs(
|
||||
|
||||
|
||||
def _parse_active_request_count_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_active_request_count_attr(
|
||||
req_attrs,
|
||||
|
@ -186,9 +186,9 @@ from starlette.routing import Match
|
||||
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
|
||||
from opentelemetry.instrumentation.asgi.types import (
|
||||
@ -362,7 +362,7 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
|
||||
_client_request_hook: ClientRequestHook = None
|
||||
_client_response_hook: ClientResponseHook = None
|
||||
_instrumented_fastapi_apps = set()
|
||||
_sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT
|
||||
_sem_conv_opt_in_mode = _StabilityMode.DEFAULT
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -252,11 +252,11 @@ import opentelemetry.instrumentation.wsgi as otel_wsgi
|
||||
from opentelemetry import context, trace
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
_report_old,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.flask.package import _instruments
|
||||
from opentelemetry.instrumentation.flask.version import __version__
|
||||
@ -321,7 +321,7 @@ def _rewrapped_app(
|
||||
duration_histogram_old=None,
|
||||
response_hook=None,
|
||||
excluded_urls=None,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
duration_histogram_new=None,
|
||||
):
|
||||
def _wrapped_app(wrapped_app_environ, start_response):
|
||||
@ -392,7 +392,7 @@ def _rewrapped_app(
|
||||
duration_s = default_timer() - start
|
||||
if duration_histogram_old:
|
||||
duration_attrs_old = otel_wsgi._parse_duration_attrs(
|
||||
attributes, _HTTPStabilityMode.DEFAULT
|
||||
attributes, _StabilityMode.DEFAULT
|
||||
)
|
||||
|
||||
if request_route:
|
||||
@ -406,7 +406,7 @@ def _rewrapped_app(
|
||||
)
|
||||
if duration_histogram_new:
|
||||
duration_attrs_new = otel_wsgi._parse_duration_attrs(
|
||||
attributes, _HTTPStabilityMode.HTTP
|
||||
attributes, _StabilityMode.HTTP
|
||||
)
|
||||
|
||||
if request_route:
|
||||
@ -427,7 +427,7 @@ def _wrapped_before_request(
|
||||
excluded_urls=None,
|
||||
enable_commenter=True,
|
||||
commenter_options=None,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
def _before_request():
|
||||
if excluded_urls and excluded_urls.url_disabled(flask.request.url):
|
||||
@ -548,7 +548,7 @@ class _InstrumentedFlask(flask.Flask):
|
||||
_enable_commenter = True
|
||||
_commenter_options = None
|
||||
_meter_provider = None
|
||||
_sem_conv_opt_in_mode = _HTTPStabilityMode.DEFAULT
|
||||
_sem_conv_opt_in_mode = _StabilityMode.DEFAULT
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -205,7 +205,6 @@ from wrapt import wrap_function_wrapper
|
||||
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -215,6 +214,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_peer_port_client,
|
||||
_set_http_status_code,
|
||||
_set_http_url,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.httpx.package import _instruments
|
||||
from opentelemetry.instrumentation.httpx.version import __version__
|
||||
@ -334,7 +334,7 @@ def _apply_request_client_attributes_to_span(
|
||||
span_attributes: dict,
|
||||
url: typing.Union[str, URL, httpx.URL],
|
||||
method_original: str,
|
||||
semconv: _HTTPStabilityMode,
|
||||
semconv: _StabilityMode,
|
||||
):
|
||||
url = httpx.URL(url)
|
||||
# http semconv transition: http.method -> http.request.method
|
||||
@ -363,7 +363,7 @@ def _apply_response_client_attributes_to_span(
|
||||
span: Span,
|
||||
status_code: int,
|
||||
http_version: str,
|
||||
semconv: _HTTPStabilityMode,
|
||||
semconv: _StabilityMode,
|
||||
):
|
||||
# http semconv transition: http.status_code -> http.response.status_code
|
||||
# TODO: use _set_status when it's stable for http clients
|
||||
|
@ -87,7 +87,6 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_client_duration_attrs_old,
|
||||
_filter_semconv_duration_attrs,
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -100,6 +99,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_scheme,
|
||||
_set_http_status_code,
|
||||
_set_http_url,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||
from opentelemetry.instrumentation.requests.package import _instruments
|
||||
@ -147,7 +147,7 @@ def _instrument(
|
||||
request_hook: _RequestHookT = None,
|
||||
response_hook: _ResponseHookT = None,
|
||||
excluded_urls: ExcludeList = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
"""Enables tracing of all requests calls that go through
|
||||
:code:`requests.session.Session.request` (this includes
|
||||
@ -312,7 +312,7 @@ def _instrument(
|
||||
metric_labels,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
_HTTPStabilityMode.DEFAULT,
|
||||
_StabilityMode.DEFAULT,
|
||||
)
|
||||
duration_histogram_old.record(
|
||||
max(round(elapsed_time * 1000), 0),
|
||||
@ -323,7 +323,7 @@ def _instrument(
|
||||
metric_labels,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
duration_histogram_new.record(
|
||||
elapsed_time, attributes=duration_attrs_new
|
||||
|
@ -90,7 +90,6 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_client_duration_attrs_old,
|
||||
_filter_semconv_duration_attrs,
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -99,6 +98,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_network_protocol_version,
|
||||
_set_http_url,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||
from opentelemetry.instrumentation.urllib.package import _instruments
|
||||
@ -209,7 +209,7 @@ def _instrument(
|
||||
request_hook: _RequestHookT = None,
|
||||
response_hook: _ResponseHookT = None,
|
||||
excluded_urls: ExcludeList = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
"""Enables tracing of all requests calls that go through
|
||||
:code:`urllib.Client._make_request`"""
|
||||
@ -305,13 +305,13 @@ def _instrument(
|
||||
labels,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
)
|
||||
duration_attrs_new = _filter_semconv_duration_attrs(
|
||||
labels,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
duration_attrs_old[SpanAttributes.HTTP_URL] = url
|
||||
@ -372,7 +372,7 @@ def _set_status_code_attribute(
|
||||
span: Span,
|
||||
status_code: int,
|
||||
metric_attributes: dict = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
) -> None:
|
||||
status_code_str = str(status_code)
|
||||
try:
|
||||
@ -394,7 +394,7 @@ def _set_status_code_attribute(
|
||||
|
||||
|
||||
def _create_client_histograms(
|
||||
meter, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
meter, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
) -> Dict[str, Histogram]:
|
||||
histograms = {}
|
||||
if _report_old(sem_conv_opt_in_mode):
|
||||
@ -442,7 +442,7 @@ def _record_histograms(
|
||||
request_size: int,
|
||||
response_size: int,
|
||||
duration_s: float,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
if _report_old(sem_conv_opt_in_mode):
|
||||
duration = max(round(duration_s * 1000), 0)
|
||||
|
@ -98,7 +98,6 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_client_duration_attrs_old,
|
||||
_filter_semconv_duration_attrs,
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -111,6 +110,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_scheme,
|
||||
_set_http_url,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||
from opentelemetry.instrumentation.urllib3.package import _instruments
|
||||
@ -309,7 +309,7 @@ def _instrument(
|
||||
response_hook: _ResponseHookT = None,
|
||||
url_filter: _UrlFilterT = None,
|
||||
excluded_urls: ExcludeList = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
def instrumented_urlopen(wrapped, instance, args, kwargs):
|
||||
if not is_http_instrumentation_enabled():
|
||||
@ -461,7 +461,7 @@ def _set_status_code_attribute(
|
||||
span: Span,
|
||||
status_code: int,
|
||||
metric_attributes: dict = None,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
) -> None:
|
||||
status_code_str = str(status_code)
|
||||
try:
|
||||
@ -487,7 +487,7 @@ def _set_metric_attributes(
|
||||
instance: urllib3.connectionpool.HTTPConnectionPool,
|
||||
response: urllib3.response.HTTPResponse,
|
||||
method: str,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
) -> None:
|
||||
_set_http_host_client(
|
||||
metric_attributes, instance.host, sem_conv_opt_in_mode
|
||||
@ -516,7 +516,7 @@ def _set_metric_attributes(
|
||||
|
||||
def _filter_attributes_semconv(
|
||||
metric_attributes,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
duration_attrs_old = None
|
||||
duration_attrs_new = None
|
||||
@ -525,14 +525,14 @@ def _filter_attributes_semconv(
|
||||
metric_attributes,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
_HTTPStabilityMode.DEFAULT,
|
||||
_StabilityMode.DEFAULT,
|
||||
)
|
||||
if _report_new(sem_conv_opt_in_mode):
|
||||
duration_attrs_new = _filter_semconv_duration_attrs(
|
||||
metric_attributes,
|
||||
_client_duration_attrs_old,
|
||||
_client_duration_attrs_new,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
return (duration_attrs_old, duration_attrs_new)
|
||||
@ -549,7 +549,7 @@ def _record_metrics(
|
||||
duration_s: float,
|
||||
request_size: typing.Optional[int],
|
||||
response_size: int,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
attrs_old, attrs_new = _filter_attributes_semconv(
|
||||
metric_attributes, sem_conv_opt_in_mode
|
||||
|
@ -24,8 +24,8 @@ import urllib3.exceptions
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.urllib3 import (
|
||||
RequestInfo,
|
||||
@ -106,7 +106,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
self,
|
||||
response: urllib3.response.HTTPResponse,
|
||||
url: str,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
self.assertEqual(b"Hello!", response.data)
|
||||
|
||||
@ -129,9 +129,9 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
}
|
||||
|
||||
attributes = {
|
||||
_HTTPStabilityMode.DEFAULT: expected_attr_old,
|
||||
_HTTPStabilityMode.HTTP: expected_attr_new,
|
||||
_HTTPStabilityMode.HTTP_DUP: {
|
||||
_StabilityMode.DEFAULT: expected_attr_old,
|
||||
_StabilityMode.HTTP: expected_attr_new,
|
||||
_StabilityMode.HTTP_DUP: {
|
||||
**expected_attr_new,
|
||||
**expected_attr_old,
|
||||
},
|
||||
@ -143,7 +143,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
def assert_exception_span(
|
||||
self,
|
||||
url: str,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
span = self.assert_span()
|
||||
|
||||
@ -159,9 +159,9 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
}
|
||||
|
||||
attributes = {
|
||||
_HTTPStabilityMode.DEFAULT: expected_attr_old,
|
||||
_HTTPStabilityMode.HTTP: expected_attr_new,
|
||||
_HTTPStabilityMode.HTTP_DUP: {
|
||||
_StabilityMode.DEFAULT: expected_attr_old,
|
||||
_StabilityMode.HTTP: expected_attr_new,
|
||||
_StabilityMode.HTTP_DUP: {
|
||||
**expected_attr_new,
|
||||
**expected_attr_old,
|
||||
},
|
||||
@ -192,7 +192,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
self.assert_success_span(
|
||||
response,
|
||||
self.HTTP_URL,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
)
|
||||
|
||||
def test_basic_http_success_new_semconv(self):
|
||||
@ -200,7 +200,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
self.assert_success_span(
|
||||
response,
|
||||
self.HTTP_URL,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
def test_basic_http_success_both_semconv(self):
|
||||
@ -208,7 +208,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
self.assert_success_span(
|
||||
response,
|
||||
self.HTTP_URL,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
|
||||
def test_basic_http_success_using_connection_pool(self):
|
||||
@ -471,7 +471,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
)
|
||||
|
||||
self.assert_exception_span(
|
||||
self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP
|
||||
self.HTTP_URL, sem_conv_opt_in_mode=_StabilityMode.HTTP
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
@ -485,7 +485,7 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
)
|
||||
|
||||
self.assert_exception_span(
|
||||
self.HTTP_URL, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP_DUP
|
||||
self.HTTP_URL, sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
|
@ -217,7 +217,6 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_filter_semconv_active_request_count_attr,
|
||||
_filter_semconv_duration_attrs,
|
||||
_get_schema_url,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_report_new,
|
||||
@ -237,6 +236,7 @@ from opentelemetry.instrumentation._semconv import (
|
||||
_set_http_target,
|
||||
_set_http_user_agent,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.instrumentation.utils import _start_internal_or_server_span
|
||||
from opentelemetry.instrumentation.wsgi.version import __version__
|
||||
@ -308,7 +308,7 @@ def setifnotnone(dic, key, value):
|
||||
|
||||
def collect_request_attributes(
|
||||
environ,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
"""Collects HTTP request attributes from the PEP3333-conforming
|
||||
WSGI environ and returns a dictionary to be used as span creation attributes.
|
||||
@ -449,7 +449,7 @@ def _parse_status_code(resp_status):
|
||||
|
||||
|
||||
def _parse_active_request_count_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_active_request_count_attr(
|
||||
req_attrs,
|
||||
@ -460,7 +460,7 @@ def _parse_active_request_count_attrs(
|
||||
|
||||
|
||||
def _parse_duration_attrs(
|
||||
req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT
|
||||
req_attrs, sem_conv_opt_in_mode=_StabilityMode.DEFAULT
|
||||
):
|
||||
return _filter_semconv_duration_attrs(
|
||||
req_attrs,
|
||||
@ -475,7 +475,7 @@ def add_response_attributes(
|
||||
start_response_status,
|
||||
response_headers,
|
||||
duration_attrs=None,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
): # pylint: disable=unused-argument
|
||||
"""Adds HTTP response attributes to span using the arguments
|
||||
passed to a PEP3333-conforming start_response callable.
|
||||
@ -685,14 +685,14 @@ class OpenTelemetryMiddleware:
|
||||
duration_s = default_timer() - start
|
||||
if self.duration_histogram_old:
|
||||
duration_attrs_old = _parse_duration_attrs(
|
||||
req_attrs, _HTTPStabilityMode.DEFAULT
|
||||
req_attrs, _StabilityMode.DEFAULT
|
||||
)
|
||||
self.duration_histogram_old.record(
|
||||
max(round(duration_s * 1000), 0), duration_attrs_old
|
||||
)
|
||||
if self.duration_histogram_new:
|
||||
duration_attrs_new = _parse_duration_attrs(
|
||||
req_attrs, _HTTPStabilityMode.HTTP
|
||||
req_attrs, _StabilityMode.HTTP
|
||||
)
|
||||
self.duration_histogram_new.record(
|
||||
max(duration_s, 0), duration_attrs_new
|
||||
|
@ -24,12 +24,12 @@ import opentelemetry.instrumentation.wsgi as otel_wsgi
|
||||
from opentelemetry import trace as trace_api
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||
_HTTPStabilityMode,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_server_active_requests_count_attrs_new,
|
||||
_server_active_requests_count_attrs_old,
|
||||
_server_duration_attrs_new,
|
||||
_server_duration_attrs_old,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.sdk.metrics.export import (
|
||||
HistogramDataPoint,
|
||||
@ -527,7 +527,7 @@ class TestWsgiAttributes(unittest.TestCase):
|
||||
|
||||
attrs = otel_wsgi.collect_request_attributes(
|
||||
self.environ,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
self.assertDictEqual(
|
||||
attrs,
|
||||
@ -742,7 +742,7 @@ class TestWsgiAttributes(unittest.TestCase):
|
||||
self.assertGreaterEqual(
|
||||
otel_wsgi.collect_request_attributes(
|
||||
self.environ,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
).items(),
|
||||
expected_new.items(),
|
||||
)
|
||||
@ -758,7 +758,7 @@ class TestWsgiAttributes(unittest.TestCase):
|
||||
self.assertGreaterEqual(
|
||||
otel_wsgi.collect_request_attributes(
|
||||
self.environ,
|
||||
_HTTPStabilityMode.HTTP,
|
||||
_StabilityMode.HTTP,
|
||||
).items(),
|
||||
expected_new.items(),
|
||||
)
|
||||
@ -769,7 +769,7 @@ class TestWsgiAttributes(unittest.TestCase):
|
||||
self.span,
|
||||
"404 Not Found",
|
||||
{},
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP,
|
||||
)
|
||||
expected = (mock.call(SpanAttributes.HTTP_STATUS_CODE, 404),)
|
||||
expected_new = (
|
||||
|
@ -109,23 +109,23 @@ OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN"
|
||||
|
||||
class _OpenTelemetryStabilitySignalType:
|
||||
HTTP = "http"
|
||||
DATABASE = "database"
|
||||
|
||||
|
||||
class _HTTPStabilityMode(Enum):
|
||||
# http - emit the new, stable HTTP and networking conventions ONLY
|
||||
HTTP = "http"
|
||||
# http/dup - emit both the old and the stable HTTP and networking conventions
|
||||
HTTP_DUP = "http/dup"
|
||||
# default - continue emitting old experimental HTTP and networking conventions
|
||||
class _StabilityMode(Enum):
|
||||
DEFAULT = "default"
|
||||
HTTP = "http"
|
||||
HTTP_DUP = "http/dup"
|
||||
DATABASE = "database"
|
||||
DATABASE_DUP = "database/dup"
|
||||
|
||||
|
||||
def _report_new(mode):
|
||||
return mode.name != _HTTPStabilityMode.DEFAULT.name
|
||||
def _report_new(mode: _StabilityMode):
|
||||
return mode != _StabilityMode.DEFAULT
|
||||
|
||||
|
||||
def _report_old(mode):
|
||||
return mode.name != _HTTPStabilityMode.HTTP.name
|
||||
def _report_old(mode: _StabilityMode):
|
||||
return mode not in (_StabilityMode.HTTP, _StabilityMode.DATABASE)
|
||||
|
||||
|
||||
class _OpenTelemetrySemanticConventionStability:
|
||||
@ -135,35 +135,61 @@ class _OpenTelemetrySemanticConventionStability:
|
||||
|
||||
@classmethod
|
||||
def _initialize(cls):
|
||||
with _OpenTelemetrySemanticConventionStability._lock:
|
||||
if not _OpenTelemetrySemanticConventionStability._initialized:
|
||||
with cls._lock:
|
||||
if cls._initialized:
|
||||
return
|
||||
|
||||
# Users can pass in comma delimited string for opt-in options
|
||||
# Only values for http stability are supported for now
|
||||
opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN, "")
|
||||
opt_in_list = []
|
||||
if opt_in:
|
||||
# Only values for http and database stability are supported for now
|
||||
opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN)
|
||||
|
||||
if not opt_in:
|
||||
# early return in case of default
|
||||
cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = {
|
||||
_OpenTelemetryStabilitySignalType.HTTP: _StabilityMode.DEFAULT,
|
||||
_OpenTelemetryStabilitySignalType.DATABASE: _StabilityMode.DEFAULT,
|
||||
}
|
||||
cls._initialized = True
|
||||
return
|
||||
|
||||
opt_in_list = [s.strip() for s in opt_in.split(",")]
|
||||
http_opt_in = _HTTPStabilityMode.DEFAULT
|
||||
if opt_in_list:
|
||||
# Process http opt-in
|
||||
# http/dup takes priority over http
|
||||
if _HTTPStabilityMode.HTTP_DUP.value in opt_in_list:
|
||||
http_opt_in = _HTTPStabilityMode.HTTP_DUP
|
||||
elif _HTTPStabilityMode.HTTP.value in opt_in_list:
|
||||
http_opt_in = _HTTPStabilityMode.HTTP
|
||||
_OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[
|
||||
|
||||
cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
] = http_opt_in
|
||||
_OpenTelemetrySemanticConventionStability._initialized = True
|
||||
] = cls._filter_mode(
|
||||
opt_in_list, _StabilityMode.HTTP, _StabilityMode.HTTP_DUP
|
||||
)
|
||||
|
||||
cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
] = cls._filter_mode(
|
||||
opt_in_list,
|
||||
_StabilityMode.DATABASE,
|
||||
_StabilityMode.DATABASE_DUP,
|
||||
)
|
||||
|
||||
cls._initialized = True
|
||||
|
||||
@staticmethod
|
||||
def _filter_mode(opt_in_list, stable_mode, dup_mode):
|
||||
# Process semconv stability opt-in
|
||||
# http/dup,database/dup has higher precedence over http,database
|
||||
if dup_mode.value in opt_in_list:
|
||||
return dup_mode
|
||||
|
||||
return (
|
||||
stable_mode
|
||||
if stable_mode.value in opt_in_list
|
||||
else _StabilityMode.DEFAULT
|
||||
)
|
||||
|
||||
@classmethod
|
||||
# Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.)
|
||||
def _get_opentelemetry_stability_opt_in_mode(
|
||||
cls,
|
||||
signal_type: _OpenTelemetryStabilitySignalType,
|
||||
) -> _HTTPStabilityMode:
|
||||
return _OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get(
|
||||
signal_type, _HTTPStabilityMode.DEFAULT
|
||||
cls, signal_type: _OpenTelemetryStabilitySignalType
|
||||
) -> _StabilityMode:
|
||||
# Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.)
|
||||
return cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get(
|
||||
signal_type, _StabilityMode.DEFAULT
|
||||
)
|
||||
|
||||
|
||||
@ -171,14 +197,12 @@ def _filter_semconv_duration_attrs(
|
||||
attrs,
|
||||
old_attrs,
|
||||
new_attrs,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
filtered_attrs = {}
|
||||
# duration is two different metrics depending on sem_conv_opt_in_mode, so no DUP attributes
|
||||
allowed_attributes = (
|
||||
new_attrs
|
||||
if sem_conv_opt_in_mode == _HTTPStabilityMode.HTTP
|
||||
else old_attrs
|
||||
new_attrs if sem_conv_opt_in_mode == _StabilityMode.HTTP else old_attrs
|
||||
)
|
||||
for key, val in attrs.items():
|
||||
if key in allowed_attributes:
|
||||
@ -190,7 +214,7 @@ def _filter_semconv_active_request_count_attr(
|
||||
attrs,
|
||||
old_attrs,
|
||||
new_attrs,
|
||||
sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
):
|
||||
filtered_attrs = {}
|
||||
if _report_old(sem_conv_opt_in_mode):
|
||||
@ -367,9 +391,10 @@ def _set_status(
|
||||
status_code: int,
|
||||
status_code_str: str,
|
||||
server_span: bool = True,
|
||||
sem_conv_opt_in_mode: _HTTPStabilityMode = _HTTPStabilityMode.DEFAULT,
|
||||
sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
|
||||
):
|
||||
if status_code < 0:
|
||||
if _report_new(sem_conv_opt_in_mode):
|
||||
metrics_attributes[ERROR_TYPE] = status_code_str
|
||||
if span.is_recording():
|
||||
if _report_new(sem_conv_opt_in_mode):
|
||||
@ -404,7 +429,7 @@ def _set_status(
|
||||
|
||||
|
||||
# Get schema version based off of opt-in mode
|
||||
def _get_schema_url(mode: _HTTPStabilityMode) -> str:
|
||||
if mode is _HTTPStabilityMode.DEFAULT:
|
||||
def _get_schema_url(mode: _StabilityMode) -> str:
|
||||
if mode is _StabilityMode.DEFAULT:
|
||||
return "https://opentelemetry.io/schemas/1.11.0"
|
||||
return SpanAttributes.SCHEMA_URL
|
||||
|
258
opentelemetry-instrumentation/tests/test_semconv.py
Normal file
258
opentelemetry-instrumentation/tests/test_semconv.py
Normal file
@ -0,0 +1,258 @@
|
||||
# Copyright The OpenTelemetry Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from unittest import TestCase
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from opentelemetry.instrumentation._semconv import (
|
||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||
_OpenTelemetrySemanticConventionStability,
|
||||
_OpenTelemetryStabilitySignalType,
|
||||
_set_status,
|
||||
_StabilityMode,
|
||||
)
|
||||
from opentelemetry.trace.status import StatusCode
|
||||
|
||||
|
||||
def stability_mode(mode):
|
||||
def decorator(test_case):
|
||||
@patch.dict(os.environ, {OTEL_SEMCONV_STABILITY_OPT_IN: mode})
|
||||
def wrapper(*args, **kwargs):
|
||||
_OpenTelemetrySemanticConventionStability._initialized = False
|
||||
_OpenTelemetrySemanticConventionStability._initialize()
|
||||
return test_case(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class TestOpenTelemetrySemConvStability(TestCase):
|
||||
@stability_mode("")
|
||||
def test_default_mode(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.DEFAULT,
|
||||
)
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DEFAULT,
|
||||
)
|
||||
|
||||
@stability_mode("http")
|
||||
def test_http_stable_mode(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
@stability_mode("http/dup")
|
||||
def test_http_dup_mode(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
|
||||
@stability_mode("database")
|
||||
def test_database_stable_mode(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE,
|
||||
)
|
||||
|
||||
@stability_mode("database/dup")
|
||||
def test_database_dup_mode(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE_DUP,
|
||||
)
|
||||
|
||||
@stability_mode("database,http")
|
||||
def test_multiple_stability_database_http_modes(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE,
|
||||
)
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
@stability_mode("database,http/dup")
|
||||
def test_multiple_stability_database_http_dup_modes(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE,
|
||||
)
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
|
||||
@stability_mode("database/dup,http")
|
||||
def test_multiple_stability_database_dup_http_stable_modes(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE_DUP,
|
||||
)
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP,
|
||||
)
|
||||
|
||||
@stability_mode("database,database/dup,http,http/dup")
|
||||
def test_stability_mode_dup_precedence(self):
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.DATABASE
|
||||
),
|
||||
_StabilityMode.DATABASE_DUP,
|
||||
)
|
||||
self.assertEqual(
|
||||
_OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
|
||||
_OpenTelemetryStabilitySignalType.HTTP
|
||||
),
|
||||
_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
|
||||
|
||||
class TestOpenTelemetrySemConvStabilityHTTP(TestCase):
|
||||
def test_set_status_for_non_http_code_with_recording_span(self):
|
||||
span = Mock()
|
||||
span.is_recording.return_value = True
|
||||
metric_attributes = {}
|
||||
_set_status(
|
||||
span,
|
||||
metric_attributes,
|
||||
-1,
|
||||
"Exception",
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
)
|
||||
|
||||
self.assertIsNone(metric_attributes.get("error.type"))
|
||||
span.set_attribute.assert_not_called()
|
||||
status_call = span.set_status.call_args[0][0]
|
||||
self.assertEqual(status_call.status_code, StatusCode.ERROR)
|
||||
self.assertEqual(
|
||||
status_call.description, "Non-integer HTTP status: " + "Exception"
|
||||
)
|
||||
|
||||
def test_status_code_http_default(self):
|
||||
span = Mock()
|
||||
metrics_attributes = {}
|
||||
_set_status(
|
||||
span=span,
|
||||
metrics_attributes=metrics_attributes,
|
||||
status_code=404,
|
||||
status_code_str="404",
|
||||
server_span=True,
|
||||
sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
|
||||
)
|
||||
# Verify only old conventions are emitted
|
||||
span.set_attribute.assert_called_with("http.status_code", 404)
|
||||
self.assertIn("http.status_code", metrics_attributes)
|
||||
self.assertNotIn("http.response_status_code", metrics_attributes)
|
||||
|
||||
def test_status_code_http_stable(self):
|
||||
span = Mock()
|
||||
metrics_attributes = {}
|
||||
_set_status(
|
||||
span=span,
|
||||
metrics_attributes=metrics_attributes,
|
||||
status_code=200,
|
||||
status_code_str="200",
|
||||
server_span=True,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP,
|
||||
)
|
||||
# Verify only new conventions are emitted
|
||||
span.set_attribute.assert_called_with("http.response.status_code", 200)
|
||||
self.assertIn("http.response.status_code", metrics_attributes)
|
||||
self.assertNotIn("http.status_code", metrics_attributes)
|
||||
|
||||
def test_status_code_http_dup(self):
|
||||
span = Mock()
|
||||
metrics_attributes = {}
|
||||
_set_status(
|
||||
span=span,
|
||||
metrics_attributes=metrics_attributes,
|
||||
status_code=500,
|
||||
status_code_str="500",
|
||||
server_span=True,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
# Verify both old and new conventions are emitted
|
||||
span.set_attribute.assert_any_call("http.status_code", 500)
|
||||
span.set_attribute.assert_any_call("http.response.status_code", 500)
|
||||
self.assertIn("http.status_code", metrics_attributes)
|
||||
self.assertIn("http.response.status_code", metrics_attributes)
|
||||
|
||||
def test_error_status_code_new_mode(self):
|
||||
span = Mock()
|
||||
metrics_attributes = {}
|
||||
_set_status(
|
||||
span=span,
|
||||
metrics_attributes=metrics_attributes,
|
||||
status_code=500,
|
||||
status_code_str="500",
|
||||
server_span=True,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP,
|
||||
)
|
||||
# Verify error type is set for new conventions
|
||||
span.set_attribute.assert_any_call("error.type", "500")
|
||||
self.assertIn("error.type", metrics_attributes)
|
||||
self.assertEqual(metrics_attributes["error.type"], "500")
|
||||
|
||||
def test_non_recording_span(self):
|
||||
span = Mock()
|
||||
span.is_recording.return_value = False
|
||||
metrics_attributes = {}
|
||||
_set_status(
|
||||
span=span,
|
||||
metrics_attributes=metrics_attributes,
|
||||
status_code=200,
|
||||
status_code_str="200",
|
||||
server_span=True,
|
||||
sem_conv_opt_in_mode=_StabilityMode.HTTP_DUP,
|
||||
)
|
||||
# Verify no span attributes are set if not recording
|
||||
span.set_attribute.assert_not_called()
|
||||
span.set_status.assert_not_called()
|
||||
# Verify status code set for metrics independent of tracing decision
|
||||
self.assertIn("http.status_code", metrics_attributes)
|
||||
self.assertIn("http.response.status_code", metrics_attributes)
|
Reference in New Issue
Block a user