mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-08-01 17:34:38 +08:00
Set schema_url on all tracers and meters (#1977)
This commit is contained in:
@ -11,10 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
([#1800](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1800))
|
||||
|
||||
### Added
|
||||
|
||||
- `opentelemetry-instrumentation-botocore` Include SNS topic ARN as a span attribute with name `messaging.destination.name` to uniquely identify the SNS topic
|
||||
([#1995](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1995))
|
||||
- `opentelemetry-instrumentation-system-metrics` Add support for collecting process metrics
|
||||
([#1948](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1948))
|
||||
- Added schema_url (`"https://opentelemetry.io/schemas/1.11.0"`) to all metrics and traces
|
||||
([#1977](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1977))
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -64,7 +64,10 @@ class AioPikaInstrumentor(BaseInstrumentor):
|
||||
def _instrument(self, **kwargs):
|
||||
tracer_provider = kwargs.get("tracer_provider", None)
|
||||
tracer = trace.get_tracer(
|
||||
_INSTRUMENTATION_MODULE_NAME, __version__, tracer_provider
|
||||
_INSTRUMENTATION_MODULE_NAME,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._instrument_queue(tracer)
|
||||
self._instrument_exchange(tracer)
|
||||
|
@ -163,7 +163,12 @@ def create_trace_config(
|
||||
# Explicitly specify the type for the `request_hook` and `response_hook` param and rtype to work
|
||||
# around this issue.
|
||||
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
def _end_trace(trace_config_ctx: types.SimpleNamespace):
|
||||
context_api.detach(trace_config_ctx.token)
|
||||
|
@ -134,6 +134,21 @@ class TestAioHttpIntegration(TestBase):
|
||||
|
||||
self.memory_exporter.clear()
|
||||
|
||||
def test_schema_url(self):
|
||||
with self.subTest(status_code=200):
|
||||
host, port = self._http_request(
|
||||
trace_config=aiohttp_client.create_trace_config(),
|
||||
url="/test-path?query=param#foobar",
|
||||
status_code=200,
|
||||
)
|
||||
|
||||
span = self.memory_exporter.get_finished_spans()[0]
|
||||
self.assertEqual(
|
||||
span.instrumentation_info.schema_url,
|
||||
"https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.memory_exporter.clear()
|
||||
|
||||
def test_not_recording(self):
|
||||
mock_tracer = mock.Mock()
|
||||
mock_span = mock.Mock()
|
||||
|
@ -495,9 +495,19 @@ class OpenTelemetryMiddleware:
|
||||
meter=None,
|
||||
):
|
||||
self.app = guarantee_single_callable(app)
|
||||
self.tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self.tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.meter = (
|
||||
get_meter(__name__, __version__, meter_provider)
|
||||
get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
if meter is None
|
||||
else meter
|
||||
)
|
||||
|
@ -107,7 +107,12 @@ class AsyncPGInstrumentor(BaseInstrumentor):
|
||||
|
||||
def _instrument(self, **kwargs):
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
self._tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self._tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
for method in [
|
||||
"Connection.execute",
|
||||
|
@ -321,7 +321,12 @@ def _instrument(
|
||||
except (IndexError, KeyError, TypeError):
|
||||
span_kind = SpanKind.SERVER
|
||||
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
with tracer.start_as_current_span(
|
||||
name=orig_handler_name,
|
||||
|
@ -91,7 +91,10 @@ class BotoInstrumentor(BaseInstrumentor):
|
||||
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._tracer = get_tracer(
|
||||
__name__, __version__, kwargs.get("tracer_provider")
|
||||
__name__,
|
||||
__version__,
|
||||
kwargs.get("tracer_provider"),
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
wrap_function_wrapper(
|
||||
|
@ -422,7 +422,10 @@ class Boto3SQSInstrumentor(BaseInstrumentor):
|
||||
"tracer_provider"
|
||||
)
|
||||
self._tracer: Tracer = trace.get_tracer(
|
||||
__name__, __version__, self._tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
self._tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._wrap_client_creation()
|
||||
|
||||
|
@ -127,7 +127,10 @@ class BotocoreInstrumentor(BaseInstrumentor):
|
||||
def _instrument(self, **kwargs):
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._tracer = get_tracer(
|
||||
__name__, __version__, kwargs.get("tracer_provider")
|
||||
__name__,
|
||||
__version__,
|
||||
kwargs.get("tracer_provider"),
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
self.request_hook = kwargs.get("request_hook")
|
||||
|
@ -55,7 +55,12 @@ def _instrument(tracer_provider, include_db_statement=False):
|
||||
|
||||
Wraps cassandra.cluster.Session.execute_async().
|
||||
"""
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
name = "Cassandra"
|
||||
|
||||
def _traced_execute_async(func, instance, args, kwargs):
|
||||
@ -65,7 +70,10 @@ def _instrument(tracer_provider, include_db_statement=False):
|
||||
if span.is_recording():
|
||||
span.set_attribute(SpanAttributes.DB_NAME, instance.keyspace)
|
||||
span.set_attribute(SpanAttributes.DB_SYSTEM, "cassandra")
|
||||
span.set_attribute(SpanAttributes.NET_PEER_NAME, instance.cluster.contact_points)
|
||||
span.set_attribute(
|
||||
SpanAttributes.NET_PEER_NAME,
|
||||
instance.cluster.contact_points,
|
||||
)
|
||||
|
||||
if include_db_statement:
|
||||
query = args[0]
|
||||
@ -74,7 +82,9 @@ def _instrument(tracer_provider, include_db_statement=False):
|
||||
response = func(*args, **kwargs)
|
||||
return response
|
||||
|
||||
wrap_function_wrapper("cassandra.cluster", "Session.execute_async", _traced_execute_async)
|
||||
wrap_function_wrapper(
|
||||
"cassandra.cluster", "Session.execute_async", _traced_execute_async
|
||||
)
|
||||
|
||||
|
||||
class CassandraInstrumentor(BaseInstrumentor):
|
||||
|
@ -46,15 +46,25 @@ class TestCassandraIntegration(TestBase):
|
||||
def test_instrument_uninstrument(self):
|
||||
instrumentation = CassandraInstrumentor()
|
||||
instrumentation.instrument()
|
||||
self.assertTrue(isinstance(cassandra.cluster.Session.execute_async, BoundFunctionWrapper))
|
||||
self.assertTrue(
|
||||
isinstance(
|
||||
cassandra.cluster.Session.execute_async, BoundFunctionWrapper
|
||||
)
|
||||
)
|
||||
|
||||
instrumentation.uninstrument()
|
||||
self.assertFalse(isinstance(cassandra.cluster.Session.execute_async, BoundFunctionWrapper))
|
||||
self.assertFalse(
|
||||
isinstance(
|
||||
cassandra.cluster.Session.execute_async, BoundFunctionWrapper
|
||||
)
|
||||
)
|
||||
|
||||
@mock.patch("cassandra.cluster.Cluster.connect")
|
||||
@mock.patch("cassandra.cluster.Session.__init__")
|
||||
@mock.patch("cassandra.cluster.Session._create_response_future")
|
||||
def test_instrumentor(self, mock_create_response_future, mock_session_init, mock_connect):
|
||||
def test_instrumentor(
|
||||
self, mock_create_response_future, mock_session_init, mock_connect
|
||||
):
|
||||
mock_create_response_future.return_value = mock.Mock()
|
||||
mock_session_init.return_value = None
|
||||
mock_connect.return_value = cassandra.cluster.Session()
|
||||
@ -85,7 +95,9 @@ class TestCassandraIntegration(TestBase):
|
||||
@mock.patch("cassandra.cluster.Cluster.connect")
|
||||
@mock.patch("cassandra.cluster.Session.__init__")
|
||||
@mock.patch("cassandra.cluster.Session._create_response_future")
|
||||
def test_custom_tracer_provider(self, mock_create_response_future, mock_session_init, mock_connect):
|
||||
def test_custom_tracer_provider(
|
||||
self, mock_create_response_future, mock_session_init, mock_connect
|
||||
):
|
||||
mock_create_response_future.return_value = mock.Mock()
|
||||
mock_session_init.return_value = None
|
||||
mock_connect.return_value = cassandra.cluster.Session()
|
||||
@ -107,7 +119,9 @@ class TestCassandraIntegration(TestBase):
|
||||
@mock.patch("cassandra.cluster.Cluster.connect")
|
||||
@mock.patch("cassandra.cluster.Session.__init__")
|
||||
@mock.patch("cassandra.cluster.Session._create_response_future")
|
||||
def test_instrument_connection_no_op_tracer_provider(self, mock_create_response_future, mock_session_init, mock_connect):
|
||||
def test_instrument_connection_no_op_tracer_provider(
|
||||
self, mock_create_response_future, mock_session_init, mock_connect
|
||||
):
|
||||
mock_create_response_future.return_value = mock.Mock()
|
||||
mock_session_init.return_value = None
|
||||
mock_connect.return_value = cassandra.cluster.Session()
|
||||
|
@ -126,10 +126,20 @@ class CeleryInstrumentor(BaseInstrumentor):
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self._tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
self.create_celery_metrics(meter)
|
||||
|
||||
|
@ -229,7 +229,10 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
|
||||
producer: Producer, tracer_provider=None
|
||||
) -> ProxiedProducer:
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider=tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
manual_producer = ProxiedProducer(producer, tracer)
|
||||
@ -241,7 +244,10 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
|
||||
consumer: Consumer, tracer_provider=None
|
||||
) -> ProxiedConsumer:
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider=tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
manual_consumer = ProxiedConsumer(consumer, tracer)
|
||||
@ -272,7 +278,10 @@ class ConfluentKafkaInstrumentor(BaseInstrumentor):
|
||||
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider=tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
self._tracer = tracer
|
||||
|
@ -264,6 +264,7 @@ class DatabaseApiIntegration:
|
||||
self._name,
|
||||
instrumenting_library_version=self._version,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.capture_parameters = capture_parameters
|
||||
self.enable_commenter = enable_commenter
|
||||
|
@ -300,8 +300,14 @@ class DjangoInstrumentor(BaseInstrumentor):
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider=meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
meter = get_meter(__name__, __version__, meter_provider=meter_provider)
|
||||
_DjangoMiddleware._tracer = tracer
|
||||
_DjangoMiddleware._meter = meter
|
||||
_DjangoMiddleware._excluded_urls = (
|
||||
|
@ -140,7 +140,12 @@ class ElasticsearchInstrumentor(BaseInstrumentor):
|
||||
Instruments Elasticsearch module
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
request_hook = kwargs.get("request_hook")
|
||||
response_hook = kwargs.get("response_hook")
|
||||
if es_transport_split:
|
||||
|
@ -254,9 +254,17 @@ class _InstrumentedFalconAPI(getattr(falcon, _instrument_app)):
|
||||
self._middlewares_list = [self._middlewares_list]
|
||||
|
||||
self._otel_tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._otel_meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._otel_meter = get_meter(__name__, __version__, meter_provider)
|
||||
self.duration_histogram = self._otel_meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_SERVER_DURATION,
|
||||
unit="ms",
|
||||
|
@ -222,7 +222,12 @@ class FastAPIInstrumentor(BaseInstrumentor):
|
||||
excluded_urls = _excluded_urls_from_env
|
||||
else:
|
||||
excluded_urls = parse_excluded_urls(excluded_urls)
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
app.add_middleware(
|
||||
OpenTelemetryMiddleware,
|
||||
@ -295,7 +300,10 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
meter = get_meter(
|
||||
__name__, __version__, _InstrumentedFastAPI._meter_provider
|
||||
__name__,
|
||||
__version__,
|
||||
_InstrumentedFastAPI._meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.add_middleware(
|
||||
OpenTelemetryMiddleware,
|
||||
|
@ -495,7 +495,10 @@ class _InstrumentedFlask(flask.Flask):
|
||||
self._is_instrumented_by_opentelemetry = True
|
||||
|
||||
meter = get_meter(
|
||||
__name__, __version__, _InstrumentedFlask._meter_provider
|
||||
__name__,
|
||||
__version__,
|
||||
_InstrumentedFlask._meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
duration_histogram = meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_SERVER_DURATION,
|
||||
@ -517,7 +520,10 @@ class _InstrumentedFlask(flask.Flask):
|
||||
)
|
||||
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, _InstrumentedFlask._tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
_InstrumentedFlask._tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
_before_request = _wrapped_before_request(
|
||||
@ -594,7 +600,12 @@ class FlaskInstrumentor(BaseInstrumentor):
|
||||
if excluded_urls is not None
|
||||
else _excluded_urls_from_env
|
||||
)
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
duration_histogram = meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_SERVER_DURATION,
|
||||
unit="ms",
|
||||
@ -615,7 +626,12 @@ class FlaskInstrumentor(BaseInstrumentor):
|
||||
excluded_urls=excluded_urls,
|
||||
)
|
||||
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
_before_request = _wrapped_before_request(
|
||||
request_hook,
|
||||
|
@ -328,7 +328,9 @@ class TestProgrammatic(InstrumentationTest, WsgiTestBase):
|
||||
if isinstance(point, NumberDataPoint):
|
||||
self.assertEqual(point.value, 0)
|
||||
|
||||
def _assert_basic_metric(self, expected_duration_attributes, expected_requests_count_attributes):
|
||||
def _assert_basic_metric(
|
||||
self, expected_duration_attributes, expected_requests_count_attributes
|
||||
):
|
||||
metrics_list = self.memory_metrics_reader.get_metrics_data()
|
||||
for resource_metric in metrics_list.resource_metrics:
|
||||
for scope_metrics in resource_metric.scope_metrics:
|
||||
|
@ -576,7 +576,12 @@ def client_interceptor(
|
||||
"""
|
||||
from . import _client
|
||||
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
return _client.OpenTelemetryClientInterceptor(
|
||||
tracer,
|
||||
@ -601,7 +606,12 @@ def server_interceptor(tracer_provider=None, filter_=None):
|
||||
"""
|
||||
from . import _server
|
||||
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
return _server.OpenTelemetryServerInterceptor(tracer, filter_=filter_)
|
||||
|
||||
@ -619,7 +629,12 @@ def aio_client_interceptors(
|
||||
"""
|
||||
from . import _aio_client
|
||||
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
return [
|
||||
_aio_client.UnaryUnaryAioClientInterceptor(
|
||||
@ -660,7 +675,12 @@ def aio_server_interceptor(tracer_provider=None, filter_=None):
|
||||
"""
|
||||
from . import _aio_server
|
||||
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
return _aio_server.OpenTelemetryAioServerInterceptor(
|
||||
tracer, filter_=filter_
|
||||
|
@ -290,6 +290,7 @@ class SyncOpenTelemetryTransport(httpx.BaseTransport):
|
||||
__name__,
|
||||
instrumenting_library_version=__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._request_hook = request_hook
|
||||
self._response_hook = response_hook
|
||||
@ -384,6 +385,7 @@ class AsyncOpenTelemetryTransport(httpx.AsyncBaseTransport):
|
||||
__name__,
|
||||
instrumenting_library_version=__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self._request_hook = request_hook
|
||||
self._response_hook = response_hook
|
||||
|
@ -130,7 +130,12 @@ class Jinja2Instrumentor(BaseInstrumentor):
|
||||
|
||||
def _instrument(self, **kwargs):
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
_wrap(jinja2, "environment.Template.render", _wrap_render(tracer))
|
||||
_wrap(jinja2, "environment.Template.generate", _wrap_render(tracer))
|
||||
|
@ -102,7 +102,10 @@ class KafkaInstrumentor(BaseInstrumentor):
|
||||
consume_hook = kwargs.get("consume_hook")
|
||||
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider=tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
wrap_function_wrapper(
|
||||
|
@ -122,7 +122,12 @@ class PikaInstrumentor(BaseInstrumentor): # type: ignore
|
||||
"Attempting to instrument Pika channel while already instrumented!"
|
||||
)
|
||||
return
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
PikaInstrumentor._instrument_blocking_channel_consumers(
|
||||
channel, tracer, consume_hook
|
||||
)
|
||||
|
@ -182,7 +182,12 @@ class PymemcacheInstrumentor(BaseInstrumentor):
|
||||
|
||||
def _instrument(self, **kwargs):
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
for cmd in COMMANDS:
|
||||
_wrap(
|
||||
|
@ -248,7 +248,12 @@ class PymongoInstrumentor(BaseInstrumentor):
|
||||
capture_statement = kwargs.get("capture_statement")
|
||||
# Create and register a CommandTracer only the first time
|
||||
if self._commandtracer_instance is None:
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
self._commandtracer_instance = CommandTracer(
|
||||
tracer,
|
||||
|
@ -84,7 +84,11 @@ def _before_traversal(event):
|
||||
return
|
||||
|
||||
start_time = request_environ.get(_ENVIRON_STARTTIME_KEY)
|
||||
tracer = trace.get_tracer(__name__, __version__)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
if request.matched_route:
|
||||
span_name = request.matched_route.pattern
|
||||
@ -128,7 +132,11 @@ def trace_tween_factory(handler, registry):
|
||||
# pylint: disable=too-many-statements
|
||||
settings = registry.settings
|
||||
enabled = asbool(settings.get(SETTING_TRACE_ENABLED, True))
|
||||
meter = get_meter(__name__, __version__)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
duration_histogram = meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_SERVER_DURATION,
|
||||
unit="ms",
|
||||
|
@ -333,7 +333,10 @@ class RedisInstrumentor(BaseInstrumentor):
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = trace.get_tracer(
|
||||
__name__, __version__, tracer_provider=tracer_provider
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider=tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
_instrument(
|
||||
tracer,
|
||||
|
@ -176,7 +176,12 @@ class RemouladeInstrumentor(BaseInstrumentor):
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self._tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
instrumentation_middleware = _InstrumentationMiddleware(self._tracer)
|
||||
|
||||
broker.add_extra_default_middleware(instrumentation_middleware)
|
||||
|
@ -277,13 +277,19 @@ class RequestsInstrumentor(BaseInstrumentor):
|
||||
list of regexes used to exclude URLs from tracking
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
excluded_urls = kwargs.get("excluded_urls")
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
duration_histogram = meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_CLIENT_DURATION,
|
||||
|
@ -129,9 +129,11 @@ def implement_span_function(func: Callable, name: str, attributes: Attributes):
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
with get_tracer(__name__, __version__).start_as_current_span(
|
||||
name=name
|
||||
) as span:
|
||||
with get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
).start_as_current_span(name=name) as span:
|
||||
if span.is_recording():
|
||||
for key, val in attributes.items():
|
||||
span.set_attribute(key, val)
|
||||
|
@ -142,10 +142,20 @@ class SQLAlchemyInstrumentor(BaseInstrumentor):
|
||||
An instrumented engine if passed in as an argument or list of instrumented engines, None otherwise.
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
connections_usage = meter.create_up_down_counter(
|
||||
name=MetricInstruments.DB_CLIENT_CONNECTIONS_USAGE,
|
||||
|
@ -207,7 +207,12 @@ class StarletteInstrumentor(BaseInstrumentor):
|
||||
tracer_provider=None,
|
||||
):
|
||||
"""Instrument an uninstrumented Starlette application."""
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
if not getattr(app, "is_instrumented_by_opentelemetry", False):
|
||||
app.add_middleware(
|
||||
OpenTelemetryMiddleware,
|
||||
@ -273,7 +278,10 @@ class _InstrumentedStarlette(applications.Starlette):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
meter = get_meter(
|
||||
__name__, __version__, _InstrumentedStarlette._meter_provider
|
||||
__name__,
|
||||
__version__,
|
||||
_InstrumentedStarlette._meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.add_middleware(
|
||||
OpenTelemetryMiddleware,
|
||||
|
@ -172,6 +172,7 @@ class SystemMetricsInstrumentor(BaseInstrumentor):
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
if "system.cpu.time" in self._config:
|
||||
|
@ -236,10 +236,20 @@ class TornadoInstrumentor(BaseInstrumentor):
|
||||
process lifetime.
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
client_histograms = _create_client_histograms(meter)
|
||||
server_histograms = _create_server_histograms(meter)
|
||||
|
@ -95,7 +95,12 @@ class TortoiseORMInstrumentor(BaseInstrumentor):
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self._tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.capture_parameters = kwargs.get("capture_parameters", False)
|
||||
if TORTOISE_SQLITE_SUPPORT:
|
||||
funcs = [
|
||||
|
@ -137,10 +137,20 @@ class URLLibInstrumentor(BaseInstrumentor):
|
||||
list of regexes used to exclude URLs from tracking
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
excluded_urls = kwargs.get("excluded_urls")
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
histograms = _create_client_histograms(meter)
|
||||
|
||||
|
@ -163,12 +163,22 @@ class URLLib3Instrumentor(BaseInstrumentor):
|
||||
list of regexes used to exclude URLs from tracking
|
||||
"""
|
||||
tracer_provider = kwargs.get("tracer_provider")
|
||||
tracer = get_tracer(__name__, __version__, tracer_provider)
|
||||
tracer = get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
excluded_urls = kwargs.get("excluded_urls")
|
||||
|
||||
meter_provider = kwargs.get("meter_provider")
|
||||
meter = get_meter(__name__, __version__, meter_provider)
|
||||
meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
duration_histogram = meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_CLIENT_DURATION,
|
||||
|
@ -138,6 +138,17 @@ class TestURLLib3Instrumentor(TestBase):
|
||||
|
||||
self.assert_success_span(response, self.HTTPS_URL)
|
||||
|
||||
def test_schema_url(self):
|
||||
pool = urllib3.HTTPSConnectionPool("mock")
|
||||
response = pool.request("GET", "/status/200")
|
||||
|
||||
self.assertEqual(b"Hello!", response.data)
|
||||
span = self.assert_span()
|
||||
self.assertEqual(
|
||||
span.instrumentation_info.schema_url,
|
||||
"https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
def test_basic_not_found(self):
|
||||
url_404 = "http://mock/status/404"
|
||||
httpretty.register_uri(httpretty.GET, url_404, status=404)
|
||||
|
@ -155,6 +155,20 @@ class TestURLLib3InstrumentorMetric(HttpTestBase, TestBase):
|
||||
],
|
||||
)
|
||||
|
||||
def test_schema_url(self):
|
||||
self.pool.request("POST", self.HTTP_URL, body="foobar")
|
||||
|
||||
resource_metrics = (
|
||||
self.memory_metrics_reader.get_metrics_data().resource_metrics
|
||||
)
|
||||
|
||||
for metrics in resource_metrics:
|
||||
for scope_metrics in metrics.scope_metrics:
|
||||
self.assertEqual(
|
||||
scope_metrics.scope.schema_url,
|
||||
"https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
|
||||
def test_bytes_request_body_size_metrics(self):
|
||||
self.pool.request("POST", self.HTTP_URL, body=b"foobar")
|
||||
|
||||
|
@ -302,7 +302,9 @@ def collect_request_attributes(environ):
|
||||
"""
|
||||
|
||||
result = {
|
||||
SpanAttributes.HTTP_METHOD: sanitize_method(environ.get("REQUEST_METHOD")),
|
||||
SpanAttributes.HTTP_METHOD: sanitize_method(
|
||||
environ.get("REQUEST_METHOD")
|
||||
),
|
||||
SpanAttributes.HTTP_SERVER_NAME: environ.get("SERVER_NAME"),
|
||||
SpanAttributes.HTTP_SCHEME: environ.get("wsgi.url_scheme"),
|
||||
}
|
||||
@ -490,8 +492,18 @@ class OpenTelemetryMiddleware:
|
||||
meter_provider=None,
|
||||
):
|
||||
self.wsgi = wsgi
|
||||
self.tracer = trace.get_tracer(__name__, __version__, tracer_provider)
|
||||
self.meter = get_meter(__name__, __version__, meter_provider)
|
||||
self.tracer = trace.get_tracer(
|
||||
__name__,
|
||||
__version__,
|
||||
tracer_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.meter = get_meter(
|
||||
__name__,
|
||||
__version__,
|
||||
meter_provider,
|
||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||
)
|
||||
self.duration_histogram = self.meter.create_histogram(
|
||||
name=MetricInstruments.HTTP_SERVER_DURATION,
|
||||
unit="ms",
|
||||
|
@ -286,10 +286,12 @@ class TestWsgiApplication(WsgiTestBase):
|
||||
self.assertTrue(number_data_point_seen and histogram_data_point_seen)
|
||||
|
||||
def test_nonstandard_http_method(self):
|
||||
self.environ["REQUEST_METHOD"]= "NONSTANDARD"
|
||||
self.environ["REQUEST_METHOD"] = "NONSTANDARD"
|
||||
app = otel_wsgi.OpenTelemetryMiddleware(simple_wsgi)
|
||||
response = app(self.environ, self.start_response)
|
||||
self.validate_response(response, span_name="UNKNOWN /", http_method="UNKNOWN")
|
||||
self.validate_response(
|
||||
response, span_name="UNKNOWN /", http_method="UNKNOWN"
|
||||
)
|
||||
|
||||
@mock.patch.dict(
|
||||
"os.environ",
|
||||
@ -298,10 +300,12 @@ class TestWsgiApplication(WsgiTestBase):
|
||||
},
|
||||
)
|
||||
def test_nonstandard_http_method_allowed(self):
|
||||
self.environ["REQUEST_METHOD"]= "NONSTANDARD"
|
||||
self.environ["REQUEST_METHOD"] = "NONSTANDARD"
|
||||
app = otel_wsgi.OpenTelemetryMiddleware(simple_wsgi)
|
||||
response = app(self.environ, self.start_response)
|
||||
self.validate_response(response, span_name="NONSTANDARD /", http_method="NONSTANDARD")
|
||||
self.validate_response(
|
||||
response, span_name="NONSTANDARD /", http_method="NONSTANDARD"
|
||||
)
|
||||
|
||||
def test_default_span_name_missing_path_info(self):
|
||||
"""Test that default span_names with missing path info."""
|
||||
|
@ -47,17 +47,25 @@ EXPECTED_AZURE_AMS_ATTRIBUTES = [
|
||||
ResourceAttributes.SERVICE_INSTANCE_ID,
|
||||
]
|
||||
|
||||
|
||||
class AzureVMResourceDetector(ResourceDetector):
|
||||
# pylint: disable=no-self-use
|
||||
def detect(self) -> "Resource":
|
||||
attributes = {}
|
||||
metadata_json = _AzureVMMetadataServiceRequestor().get_azure_vm_metadata()
|
||||
metadata_json = (
|
||||
_AzureVMMetadataServiceRequestor().get_azure_vm_metadata()
|
||||
)
|
||||
if not metadata_json:
|
||||
return Resource(attributes)
|
||||
for attribute_key in EXPECTED_AZURE_AMS_ATTRIBUTES:
|
||||
attributes[attribute_key] = _AzureVMMetadataServiceRequestor().get_attribute_from_metadata(metadata_json, attribute_key)
|
||||
attributes[
|
||||
attribute_key
|
||||
] = _AzureVMMetadataServiceRequestor().get_attribute_from_metadata(
|
||||
metadata_json, attribute_key
|
||||
)
|
||||
return Resource(attributes)
|
||||
|
||||
|
||||
class _AzureVMMetadataServiceRequestor:
|
||||
def get_azure_vm_metadata(self):
|
||||
request = Request(_AZURE_VM_METADATA_ENDPOINT)
|
||||
@ -86,8 +94,10 @@ class _AzureVMMetadataServiceRequestor:
|
||||
ams_value = metadata_json["location"]
|
||||
elif attribute_key == ResourceAttributes.CLOUD_RESOURCE_ID:
|
||||
ams_value = metadata_json["resourceId"]
|
||||
elif attribute_key == ResourceAttributes.HOST_ID or \
|
||||
attribute_key == ResourceAttributes.SERVICE_INSTANCE_ID:
|
||||
elif (
|
||||
attribute_key == ResourceAttributes.HOST_ID
|
||||
or attribute_key == ResourceAttributes.SERVICE_INSTANCE_ID
|
||||
):
|
||||
ams_value = metadata_json["vmId"]
|
||||
elif attribute_key == ResourceAttributes.HOST_NAME:
|
||||
ams_value = metadata_json["name"]
|
||||
|
@ -28,8 +28,11 @@ TEST_WEBSITE_HOME_STAMPNAME = "TEST_WEBSITE_HOME_STAMPNAME"
|
||||
TEST_WEBSITE_RESOURCE_GROUP = "TEST_WEBSITE_RESOURCE_GROUP"
|
||||
TEST_WEBSITE_OWNER_NAME = "TEST_WEBSITE_OWNER_NAME"
|
||||
|
||||
|
||||
class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
@patch.dict("os.environ", {
|
||||
@patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
|
||||
"REGION_NAME": TEST_REGION_NAME,
|
||||
"WEBSITE_SLOT_NAME": TEST_WEBSITE_SLOT_NAME,
|
||||
@ -38,7 +41,9 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
"WEBSITE_HOME_STAMPNAME": TEST_WEBSITE_HOME_STAMPNAME,
|
||||
"WEBSITE_RESOURCE_GROUP": TEST_WEBSITE_RESOURCE_GROUP,
|
||||
"WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME,
|
||||
}, clear=True)
|
||||
},
|
||||
clear=True,
|
||||
)
|
||||
def test_on_app_service(self):
|
||||
resource = AzureAppServiceResourceDetector().detect()
|
||||
attributes = resource.attributes
|
||||
@ -46,16 +51,26 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
self.assertEqual(attributes["cloud.provider"], "azure")
|
||||
self.assertEqual(attributes["cloud.platform"], "azure_app_service")
|
||||
|
||||
self.assertEqual(attributes["cloud.resource_id"], \
|
||||
f"/subscriptions/{TEST_WEBSITE_OWNER_NAME}/resourceGroups/{TEST_WEBSITE_RESOURCE_GROUP}/providers/Microsoft.Web/sites/{TEST_WEBSITE_SITE_NAME}")
|
||||
self.assertEqual(
|
||||
attributes["cloud.resource_id"],
|
||||
f"/subscriptions/{TEST_WEBSITE_OWNER_NAME}/resourceGroups/{TEST_WEBSITE_RESOURCE_GROUP}/providers/Microsoft.Web/sites/{TEST_WEBSITE_SITE_NAME}",
|
||||
)
|
||||
|
||||
self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME)
|
||||
self.assertEqual(attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME)
|
||||
self.assertEqual(
|
||||
attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME
|
||||
)
|
||||
self.assertEqual(attributes["host.id"], TEST_WEBSITE_HOSTNAME)
|
||||
self.assertEqual(attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID)
|
||||
self.assertEqual(attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME)
|
||||
self.assertEqual(
|
||||
attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID
|
||||
)
|
||||
self.assertEqual(
|
||||
attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME
|
||||
)
|
||||
|
||||
@patch.dict("os.environ", {
|
||||
@patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
|
||||
"REGION_NAME": TEST_REGION_NAME,
|
||||
"WEBSITE_SLOT_NAME": TEST_WEBSITE_SLOT_NAME,
|
||||
@ -63,7 +78,9 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
"WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID,
|
||||
"WEBSITE_HOME_STAMPNAME": TEST_WEBSITE_HOME_STAMPNAME,
|
||||
"WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME,
|
||||
}, clear=True)
|
||||
},
|
||||
clear=True,
|
||||
)
|
||||
def test_on_app_service_no_resource_group(self):
|
||||
resource = AzureAppServiceResourceDetector().detect()
|
||||
attributes = resource.attributes
|
||||
@ -74,12 +91,20 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
self.assertTrue("cloud.resource_id" not in attributes)
|
||||
|
||||
self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME)
|
||||
self.assertEqual(attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME)
|
||||
self.assertEqual(
|
||||
attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME
|
||||
)
|
||||
self.assertEqual(attributes["host.id"], TEST_WEBSITE_HOSTNAME)
|
||||
self.assertEqual(attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID)
|
||||
self.assertEqual(attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME)
|
||||
self.assertEqual(
|
||||
attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID
|
||||
)
|
||||
self.assertEqual(
|
||||
attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME
|
||||
)
|
||||
|
||||
@patch.dict("os.environ", {
|
||||
@patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
|
||||
"REGION_NAME": TEST_REGION_NAME,
|
||||
"WEBSITE_SLOT_NAME": TEST_WEBSITE_SLOT_NAME,
|
||||
@ -87,7 +112,9 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
"WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID,
|
||||
"WEBSITE_HOME_STAMPNAME": TEST_WEBSITE_HOME_STAMPNAME,
|
||||
"WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME,
|
||||
}, clear=True)
|
||||
},
|
||||
clear=True,
|
||||
)
|
||||
def test_on_app_service_no_owner(self):
|
||||
resource = AzureAppServiceResourceDetector().detect()
|
||||
attributes = resource.attributes
|
||||
@ -98,19 +125,29 @@ class TestAzureAppServiceResourceDetector(unittest.TestCase):
|
||||
self.assertTrue("cloud.resource_id" not in attributes)
|
||||
|
||||
self.assertEqual(attributes["cloud.region"], TEST_REGION_NAME)
|
||||
self.assertEqual(attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME)
|
||||
self.assertEqual(
|
||||
attributes["deployment.environment"], TEST_WEBSITE_SLOT_NAME
|
||||
)
|
||||
self.assertEqual(attributes["host.id"], TEST_WEBSITE_HOSTNAME)
|
||||
self.assertEqual(attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID)
|
||||
self.assertEqual(attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME)
|
||||
self.assertEqual(
|
||||
attributes["service.instance.id"], TEST_WEBSITE_INSTANCE_ID
|
||||
)
|
||||
self.assertEqual(
|
||||
attributes["azure.app.service.stamp"], TEST_WEBSITE_HOME_STAMPNAME
|
||||
)
|
||||
|
||||
@patch.dict("os.environ", {
|
||||
@patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"REGION_NAME": TEST_REGION_NAME,
|
||||
"WEBSITE_SLOT_NAME": TEST_WEBSITE_SLOT_NAME,
|
||||
"WEBSITE_HOSTNAME": TEST_WEBSITE_HOSTNAME,
|
||||
"WEBSITE_INSTANCE_ID": TEST_WEBSITE_INSTANCE_ID,
|
||||
"WEBSITE_HOME_STAMPNAME": TEST_WEBSITE_HOME_STAMPNAME,
|
||||
"WEBSITE_OWNER_NAME": TEST_WEBSITE_OWNER_NAME,
|
||||
}, clear=True)
|
||||
},
|
||||
clear=True,
|
||||
)
|
||||
def test_off_app_service(self):
|
||||
resource = AzureAppServiceResourceDetector().detect()
|
||||
self.assertEqual(resource.attributes, {})
|
||||
|
@ -175,7 +175,7 @@ LINUX_JSON = """
|
||||
"zone": "1"
|
||||
}
|
||||
"""
|
||||
WINDOWS_JSON ="""
|
||||
WINDOWS_JSON = """
|
||||
{
|
||||
"additionalCapabilities": {
|
||||
"hibernationEnabled": "false"
|
||||
@ -370,7 +370,9 @@ class TestAzureVMResourceDetector(unittest.TestCase):
|
||||
mock_open.read.return_value = LINUX_JSON
|
||||
attributes = AzureVMResourceDetector().detect().attributes
|
||||
for attribute_key in LINUX_ATTRIBUTES:
|
||||
self.assertEqual(attributes[attribute_key], LINUX_ATTRIBUTES[attribute_key])
|
||||
self.assertEqual(
|
||||
attributes[attribute_key], LINUX_ATTRIBUTES[attribute_key]
|
||||
)
|
||||
|
||||
@patch("opentelemetry.resource.detector.azure.vm.urlopen")
|
||||
def test_windows(self, mock_urlopen):
|
||||
@ -379,4 +381,6 @@ class TestAzureVMResourceDetector(unittest.TestCase):
|
||||
mock_open.read.return_value = WINDOWS_JSON
|
||||
attributes = AzureVMResourceDetector().detect().attributes
|
||||
for attribute_key in WINDOWS_ATTRIBUTES:
|
||||
self.assertEqual(attributes[attribute_key], WINDOWS_ATTRIBUTES[attribute_key])
|
||||
self.assertEqual(
|
||||
attributes[attribute_key], WINDOWS_ATTRIBUTES[attribute_key]
|
||||
)
|
||||
|
@ -190,16 +190,32 @@ def normalise_response_header_name(header: str) -> str:
|
||||
key = header.lower().replace("-", "_")
|
||||
return f"http.response.header.{key}"
|
||||
|
||||
|
||||
def sanitize_method(method: Optional[str]) -> Optional[str]:
|
||||
if method is None:
|
||||
return None
|
||||
method = method.upper()
|
||||
if (environ.get(OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS) or
|
||||
if (
|
||||
environ.get(OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS)
|
||||
or
|
||||
# Based on https://www.rfc-editor.org/rfc/rfc7231#section-4.1 and https://www.rfc-editor.org/rfc/rfc5789#section-2.
|
||||
method in ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"]):
|
||||
method
|
||||
in [
|
||||
"GET",
|
||||
"HEAD",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"CONNECT",
|
||||
"OPTIONS",
|
||||
"TRACE",
|
||||
"PATCH",
|
||||
]
|
||||
):
|
||||
return method
|
||||
return "UNKNOWN"
|
||||
|
||||
|
||||
def get_custom_headers(env_var: str) -> List[str]:
|
||||
custom_headers = environ.get(env_var, [])
|
||||
if custom_headers:
|
||||
|
@ -20,6 +20,7 @@ from opentelemetry.util.http import (
|
||||
sanitize_method,
|
||||
)
|
||||
|
||||
|
||||
class TestSanitizeMethod(unittest.TestCase):
|
||||
def test_standard_method_uppercase(self):
|
||||
method = sanitize_method("GET")
|
||||
|
Reference in New Issue
Block a user