mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
consistently use of suppress_instrumentation utils (#2590)
This commit is contained in:
@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538))
|
([#2538](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2538))
|
||||||
- Add Python 3.12 support
|
- Add Python 3.12 support
|
||||||
([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572))
|
([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572))
|
||||||
|
- `opentelemetry-instrumentation-aiohttp-server`, `opentelemetry-instrumentation-httpx` Ensure consistently use of suppress_instrumentation utils
|
||||||
|
([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590))
|
||||||
|
|
||||||
## Version 1.25.0/0.46b0 (2024-05-31)
|
## Version 1.25.0/0.46b0 (2024-05-31)
|
||||||
|
|
||||||
|
@ -19,12 +19,14 @@ from typing import Dict, List, Tuple, Union
|
|||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from multidict import CIMultiDictProxy
|
from multidict import CIMultiDictProxy
|
||||||
|
|
||||||
from opentelemetry import context, metrics, trace
|
from opentelemetry import metrics, trace
|
||||||
from opentelemetry.context import _SUPPRESS_HTTP_INSTRUMENTATION_KEY
|
|
||||||
from opentelemetry.instrumentation.aiohttp_server.package import _instruments
|
from opentelemetry.instrumentation.aiohttp_server.package import _instruments
|
||||||
from opentelemetry.instrumentation.aiohttp_server.version import __version__
|
from opentelemetry.instrumentation.aiohttp_server.version import __version__
|
||||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||||
from opentelemetry.instrumentation.utils import http_status_to_status_code
|
from opentelemetry.instrumentation.utils import (
|
||||||
|
http_status_to_status_code,
|
||||||
|
is_http_instrumentation_enabled,
|
||||||
|
)
|
||||||
from opentelemetry.propagate import extract
|
from opentelemetry.propagate import extract
|
||||||
from opentelemetry.propagators.textmap import Getter
|
from opentelemetry.propagators.textmap import Getter
|
||||||
from opentelemetry.semconv.metrics import MetricInstruments
|
from opentelemetry.semconv.metrics import MetricInstruments
|
||||||
@ -191,10 +193,8 @@ getter = AiohttpGetter()
|
|||||||
@web.middleware
|
@web.middleware
|
||||||
async def middleware(request, handler):
|
async def middleware(request, handler):
|
||||||
"""Middleware for aiohttp implementing tracing logic"""
|
"""Middleware for aiohttp implementing tracing logic"""
|
||||||
if (
|
if not is_http_instrumentation_enabled() or _excluded_urls.url_disabled(
|
||||||
context.get_value("suppress_instrumentation")
|
request.url.path
|
||||||
or context.get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY)
|
|
||||||
or _excluded_urls.url_disabled(request.url.path)
|
|
||||||
):
|
):
|
||||||
return await handler(request)
|
return await handler(request)
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from opentelemetry import trace as trace_api
|
|||||||
from opentelemetry.instrumentation.aiohttp_server import (
|
from opentelemetry.instrumentation.aiohttp_server import (
|
||||||
AioHttpServerInstrumentor,
|
AioHttpServerInstrumentor,
|
||||||
)
|
)
|
||||||
|
from opentelemetry.instrumentation.utils import suppress_http_instrumentation
|
||||||
from opentelemetry.semconv.trace import SpanAttributes
|
from opentelemetry.semconv.trace import SpanAttributes
|
||||||
from opentelemetry.test.globals_test import reset_trace_globals
|
from opentelemetry.test.globals_test import reset_trace_globals
|
||||||
from opentelemetry.test.test_base import TestBase
|
from opentelemetry.test.test_base import TestBase
|
||||||
@ -64,16 +65,25 @@ async def default_handler(request, status=200):
|
|||||||
return aiohttp.web.Response(status=status)
|
return aiohttp.web.Response(status=status)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="suppress")
|
||||||
|
def fixture_suppress():
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@pytest_asyncio.fixture(name="server_fixture")
|
@pytest_asyncio.fixture(name="server_fixture")
|
||||||
async def fixture_server_fixture(tracer, aiohttp_server):
|
async def fixture_server_fixture(tracer, aiohttp_server, suppress):
|
||||||
_, memory_exporter = tracer
|
_, memory_exporter = tracer
|
||||||
|
|
||||||
AioHttpServerInstrumentor().instrument()
|
AioHttpServerInstrumentor().instrument()
|
||||||
|
|
||||||
app = aiohttp.web.Application()
|
app = aiohttp.web.Application()
|
||||||
app.add_routes([aiohttp.web.get("/test-path", default_handler)])
|
app.add_routes([aiohttp.web.get("/test-path", default_handler)])
|
||||||
|
if suppress:
|
||||||
|
with suppress_http_instrumentation():
|
||||||
server = await aiohttp_server(app)
|
server = await aiohttp_server(app)
|
||||||
|
else:
|
||||||
|
server = await aiohttp_server(app)
|
||||||
|
|
||||||
yield server, app
|
yield server, app
|
||||||
|
|
||||||
memory_exporter.clear()
|
memory_exporter.clear()
|
||||||
@ -128,3 +138,18 @@ async def test_status_code_instrumentation(
|
|||||||
f"http://{server.host}:{server.port}{url}"
|
f"http://{server.host}:{server.port}{url}"
|
||||||
== span.attributes[SpanAttributes.HTTP_URL]
|
== span.attributes[SpanAttributes.HTTP_URL]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
@pytest.mark.parametrize("suppress", [True])
|
||||||
|
async def test_suppress_instrumentation(
|
||||||
|
tracer, server_fixture, aiohttp_client
|
||||||
|
):
|
||||||
|
_, memory_exporter = tracer
|
||||||
|
server, _ = server_fixture
|
||||||
|
assert len(memory_exporter.get_finished_spans()) == 0
|
||||||
|
|
||||||
|
client = await aiohttp_client(server)
|
||||||
|
await client.get("/test-path")
|
||||||
|
|
||||||
|
assert len(memory_exporter.get_finished_spans()) == 0
|
||||||
|
@ -196,11 +196,13 @@ from types import TracebackType
|
|||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
from opentelemetry import context
|
|
||||||
from opentelemetry.instrumentation.httpx.package import _instruments
|
from opentelemetry.instrumentation.httpx.package import _instruments
|
||||||
from opentelemetry.instrumentation.httpx.version import __version__
|
from opentelemetry.instrumentation.httpx.version import __version__
|
||||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||||
from opentelemetry.instrumentation.utils import http_status_to_status_code
|
from opentelemetry.instrumentation.utils import (
|
||||||
|
http_status_to_status_code,
|
||||||
|
is_http_instrumentation_enabled,
|
||||||
|
)
|
||||||
from opentelemetry.propagate import inject
|
from opentelemetry.propagate import inject
|
||||||
from opentelemetry.semconv.trace import SpanAttributes
|
from opentelemetry.semconv.trace import SpanAttributes
|
||||||
from opentelemetry.trace import SpanKind, TracerProvider, get_tracer
|
from opentelemetry.trace import SpanKind, TracerProvider, get_tracer
|
||||||
@ -347,7 +349,7 @@ class SyncOpenTelemetryTransport(httpx.BaseTransport):
|
|||||||
httpx.Response,
|
httpx.Response,
|
||||||
]:
|
]:
|
||||||
"""Add request info to span."""
|
"""Add request info to span."""
|
||||||
if context.get_value("suppress_instrumentation"):
|
if not is_http_instrumentation_enabled():
|
||||||
return self._transport.handle_request(*args, **kwargs)
|
return self._transport.handle_request(*args, **kwargs)
|
||||||
|
|
||||||
method, url, headers, stream, extensions = _extract_parameters(
|
method, url, headers, stream, extensions = _extract_parameters(
|
||||||
@ -438,7 +440,7 @@ class AsyncOpenTelemetryTransport(httpx.AsyncBaseTransport):
|
|||||||
httpx.Response,
|
httpx.Response,
|
||||||
]:
|
]:
|
||||||
"""Add request info to span."""
|
"""Add request info to span."""
|
||||||
if context.get_value("suppress_instrumentation"):
|
if not is_http_instrumentation_enabled():
|
||||||
return await self._transport.handle_async_request(*args, **kwargs)
|
return await self._transport.handle_async_request(*args, **kwargs)
|
||||||
|
|
||||||
method, url, headers, stream, extensions = _extract_parameters(
|
method, url, headers, stream, extensions = _extract_parameters(
|
||||||
|
@ -21,12 +21,13 @@ import httpx
|
|||||||
import respx
|
import respx
|
||||||
|
|
||||||
import opentelemetry.instrumentation.httpx
|
import opentelemetry.instrumentation.httpx
|
||||||
from opentelemetry import context, trace
|
from opentelemetry import trace
|
||||||
from opentelemetry.instrumentation.httpx import (
|
from opentelemetry.instrumentation.httpx import (
|
||||||
AsyncOpenTelemetryTransport,
|
AsyncOpenTelemetryTransport,
|
||||||
HTTPXClientInstrumentor,
|
HTTPXClientInstrumentor,
|
||||||
SyncOpenTelemetryTransport,
|
SyncOpenTelemetryTransport,
|
||||||
)
|
)
|
||||||
|
from opentelemetry.instrumentation.utils import suppress_http_instrumentation
|
||||||
from opentelemetry.propagate import get_global_textmap, set_global_textmap
|
from opentelemetry.propagate import get_global_textmap, set_global_textmap
|
||||||
from opentelemetry.sdk import resources
|
from opentelemetry.sdk import resources
|
||||||
from opentelemetry.semconv.trace import SpanAttributes
|
from opentelemetry.semconv.trace import SpanAttributes
|
||||||
@ -191,14 +192,9 @@ class BaseTestCases:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_suppress_instrumentation(self):
|
def test_suppress_instrumentation(self):
|
||||||
token = context.attach(
|
with suppress_http_instrumentation():
|
||||||
context.set_value("suppress_instrumentation", True)
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
result = self.perform_request(self.URL)
|
result = self.perform_request(self.URL)
|
||||||
self.assertEqual(result.text, "Hello!")
|
self.assertEqual(result.text, "Hello!")
|
||||||
finally:
|
|
||||||
context.detach(token)
|
|
||||||
|
|
||||||
self.assert_span(num_spans=0)
|
self.assert_span(num_spans=0)
|
||||||
|
|
||||||
@ -512,15 +508,10 @@ class BaseTestCases:
|
|||||||
|
|
||||||
def test_suppress_instrumentation_new_client(self):
|
def test_suppress_instrumentation_new_client(self):
|
||||||
HTTPXClientInstrumentor().instrument()
|
HTTPXClientInstrumentor().instrument()
|
||||||
token = context.attach(
|
with suppress_http_instrumentation():
|
||||||
context.set_value("suppress_instrumentation", True)
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
client = self.create_client()
|
client = self.create_client()
|
||||||
result = self.perform_request(self.URL, client=client)
|
result = self.perform_request(self.URL, client=client)
|
||||||
self.assertEqual(result.text, "Hello!")
|
self.assertEqual(result.text, "Hello!")
|
||||||
finally:
|
|
||||||
context.detach(token)
|
|
||||||
|
|
||||||
self.assert_span(num_spans=0)
|
self.assert_span(num_spans=0)
|
||||||
HTTPXClientInstrumentor().uninstrument()
|
HTTPXClientInstrumentor().uninstrument()
|
||||||
|
@ -37,6 +37,10 @@ from opentelemetry.trace.propagation.tracecontext import (
|
|||||||
|
|
||||||
propagator = TraceContextTextMapPropagator()
|
propagator = TraceContextTextMapPropagator()
|
||||||
|
|
||||||
|
_SUPPRESS_INSTRUMENTATION_KEY_PLAIN = (
|
||||||
|
"suppress_instrumentation" # Set for backward compatibility
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def extract_attributes_from_object(
|
def extract_attributes_from_object(
|
||||||
obj: any, attributes: Sequence[str], existing: Dict[str, str] = None
|
obj: any, attributes: Sequence[str], existing: Dict[str, str] = None
|
||||||
@ -161,9 +165,10 @@ def _python_path_without_directory(python_path, directory, path_separator):
|
|||||||
|
|
||||||
|
|
||||||
def is_instrumentation_enabled() -> bool:
|
def is_instrumentation_enabled() -> bool:
|
||||||
if context.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
|
return not (
|
||||||
return False
|
context.get_value(_SUPPRESS_INSTRUMENTATION_KEY)
|
||||||
return True
|
or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY_PLAIN)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def is_http_instrumentation_enabled() -> bool:
|
def is_http_instrumentation_enabled() -> bool:
|
||||||
@ -188,7 +193,9 @@ def _suppress_instrumentation(*keys: str) -> Iterable[None]:
|
|||||||
@contextmanager
|
@contextmanager
|
||||||
def suppress_instrumentation() -> Iterable[None]:
|
def suppress_instrumentation() -> Iterable[None]:
|
||||||
"""Suppress instrumentation within the context."""
|
"""Suppress instrumentation within the context."""
|
||||||
with _suppress_instrumentation(_SUPPRESS_INSTRUMENTATION_KEY):
|
with _suppress_instrumentation(
|
||||||
|
_SUPPRESS_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY_PLAIN
|
||||||
|
):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,10 +15,20 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
|
from opentelemetry.context import (
|
||||||
|
_SUPPRESS_HTTP_INSTRUMENTATION_KEY,
|
||||||
|
_SUPPRESS_INSTRUMENTATION_KEY,
|
||||||
|
get_current,
|
||||||
|
get_value,
|
||||||
|
)
|
||||||
from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment
|
from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment
|
||||||
from opentelemetry.instrumentation.utils import (
|
from opentelemetry.instrumentation.utils import (
|
||||||
_python_path_without_directory,
|
_python_path_without_directory,
|
||||||
http_status_to_status_code,
|
http_status_to_status_code,
|
||||||
|
is_http_instrumentation_enabled,
|
||||||
|
is_instrumentation_enabled,
|
||||||
|
suppress_http_instrumentation,
|
||||||
|
suppress_instrumentation,
|
||||||
)
|
)
|
||||||
from opentelemetry.trace import StatusCode
|
from opentelemetry.trace import StatusCode
|
||||||
|
|
||||||
@ -186,3 +196,47 @@ class TestUtils(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(commented_sql_without_semicolon, "Select 1")
|
self.assertEqual(commented_sql_without_semicolon, "Select 1")
|
||||||
|
|
||||||
|
def test_is_instrumentation_enabled_by_default(self):
|
||||||
|
self.assertTrue(is_instrumentation_enabled())
|
||||||
|
self.assertTrue(is_http_instrumentation_enabled())
|
||||||
|
|
||||||
|
def test_suppress_instrumentation(self):
|
||||||
|
with suppress_instrumentation():
|
||||||
|
self.assertFalse(is_instrumentation_enabled())
|
||||||
|
self.assertFalse(is_http_instrumentation_enabled())
|
||||||
|
|
||||||
|
self.assertTrue(is_instrumentation_enabled())
|
||||||
|
self.assertTrue(is_http_instrumentation_enabled())
|
||||||
|
|
||||||
|
def test_suppress_http_instrumentation(self):
|
||||||
|
with suppress_http_instrumentation():
|
||||||
|
self.assertFalse(is_http_instrumentation_enabled())
|
||||||
|
self.assertTrue(is_instrumentation_enabled())
|
||||||
|
|
||||||
|
self.assertTrue(is_instrumentation_enabled())
|
||||||
|
self.assertTrue(is_http_instrumentation_enabled())
|
||||||
|
|
||||||
|
def test_suppress_instrumentation_key(self):
|
||||||
|
self.assertIsNone(get_value(_SUPPRESS_INSTRUMENTATION_KEY))
|
||||||
|
self.assertIsNone(get_value("suppress_instrumentation"))
|
||||||
|
|
||||||
|
with suppress_instrumentation():
|
||||||
|
ctx = get_current()
|
||||||
|
self.assertIn(_SUPPRESS_INSTRUMENTATION_KEY, ctx)
|
||||||
|
self.assertIn("suppress_instrumentation", ctx)
|
||||||
|
self.assertTrue(get_value(_SUPPRESS_INSTRUMENTATION_KEY))
|
||||||
|
self.assertTrue(get_value("suppress_instrumentation"))
|
||||||
|
|
||||||
|
self.assertIsNone(get_value(_SUPPRESS_INSTRUMENTATION_KEY))
|
||||||
|
self.assertIsNone(get_value("suppress_instrumentation"))
|
||||||
|
|
||||||
|
def test_suppress_http_instrumentation_key(self):
|
||||||
|
self.assertIsNone(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY))
|
||||||
|
|
||||||
|
with suppress_http_instrumentation():
|
||||||
|
ctx = get_current()
|
||||||
|
self.assertIn(_SUPPRESS_HTTP_INSTRUMENTATION_KEY, ctx)
|
||||||
|
self.assertTrue(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY))
|
||||||
|
|
||||||
|
self.assertIsNone(get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY))
|
||||||
|
@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- Ensure consistently use of suppress_instrumentation utils
|
||||||
|
([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590))
|
||||||
|
|
||||||
## Version 0.1.5 (2024-05-16)
|
## Version 0.1.5 (2024-05-16)
|
||||||
|
|
||||||
- Ignore vm detector if already in other rps
|
- Ignore vm detector if already in other rps
|
||||||
|
@ -17,12 +17,7 @@ from logging import getLogger
|
|||||||
from urllib.error import URLError
|
from urllib.error import URLError
|
||||||
from urllib.request import Request, urlopen
|
from urllib.request import Request, urlopen
|
||||||
|
|
||||||
from opentelemetry.context import (
|
from opentelemetry.instrumentation.utils import suppress_instrumentation
|
||||||
_SUPPRESS_INSTRUMENTATION_KEY,
|
|
||||||
attach,
|
|
||||||
detach,
|
|
||||||
set_value,
|
|
||||||
)
|
|
||||||
from opentelemetry.sdk.resources import Resource, ResourceDetector
|
from opentelemetry.sdk.resources import Resource, ResourceDetector
|
||||||
from opentelemetry.semconv.resource import (
|
from opentelemetry.semconv.resource import (
|
||||||
CloudPlatformValues,
|
CloudPlatformValues,
|
||||||
@ -46,7 +41,7 @@ class AzureVMResourceDetector(ResourceDetector):
|
|||||||
def detect(self) -> "Resource":
|
def detect(self) -> "Resource":
|
||||||
attributes = {}
|
attributes = {}
|
||||||
if not _can_ignore_vm_detect():
|
if not _can_ignore_vm_detect():
|
||||||
token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True))
|
with suppress_instrumentation():
|
||||||
metadata_json = _get_azure_vm_metadata()
|
metadata_json = _get_azure_vm_metadata()
|
||||||
if not metadata_json:
|
if not metadata_json:
|
||||||
return Resource(attributes)
|
return Resource(attributes)
|
||||||
@ -54,7 +49,6 @@ class AzureVMResourceDetector(ResourceDetector):
|
|||||||
attributes[attribute_key] = _get_attribute_from_metadata(
|
attributes[attribute_key] = _get_attribute_from_metadata(
|
||||||
metadata_json, attribute_key
|
metadata_json, attribute_key
|
||||||
)
|
)
|
||||||
detach(token)
|
|
||||||
return Resource(attributes)
|
return Resource(attributes)
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user