Do not use `asgi` name and version for tracer/meter for instrumentations using Asgi Middleware (#2580)
This commit is contained in:
parent
bb9eebb73e
commit
5b841282ab
|
|
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Breaking changes
|
||||||
|
|
||||||
|
- `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware
|
||||||
|
([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580))
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented
|
- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,8 @@ class OpenTelemetryMiddleware:
|
||||||
scope and event which are sent as dictionaries for when the method send is called.
|
scope and event which are sent as dictionaries for when the method send is called.
|
||||||
tracer_provider: The optional tracer provider to use. If omitted
|
tracer_provider: The optional tracer provider to use. If omitted
|
||||||
the current globally configured one is used.
|
the current globally configured one is used.
|
||||||
|
meter_provider: The optional meter provider to use. If omitted
|
||||||
|
the current globally configured one is used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|
@ -474,18 +476,23 @@ class OpenTelemetryMiddleware:
|
||||||
client_response_hook: ClientResponseHook = None,
|
client_response_hook: ClientResponseHook = None,
|
||||||
tracer_provider=None,
|
tracer_provider=None,
|
||||||
meter_provider=None,
|
meter_provider=None,
|
||||||
|
tracer=None,
|
||||||
meter=None,
|
meter=None,
|
||||||
http_capture_headers_server_request: list[str] | None = None,
|
http_capture_headers_server_request: list[str] | None = None,
|
||||||
http_capture_headers_server_response: list[str] | None = None,
|
http_capture_headers_server_response: list[str] | None = None,
|
||||||
http_capture_headers_sanitize_fields: list[str] | None = None,
|
http_capture_headers_sanitize_fields: list[str] | None = None,
|
||||||
):
|
):
|
||||||
self.app = guarantee_single_callable(app)
|
self.app = guarantee_single_callable(app)
|
||||||
self.tracer = trace.get_tracer(
|
self.tracer = (
|
||||||
|
trace.get_tracer(
|
||||||
__name__,
|
__name__,
|
||||||
__version__,
|
__version__,
|
||||||
tracer_provider,
|
tracer_provider,
|
||||||
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||||
)
|
)
|
||||||
|
if tracer is None
|
||||||
|
else tracer
|
||||||
|
)
|
||||||
self.meter = (
|
self.meter = (
|
||||||
get_meter(
|
get_meter(
|
||||||
__name__,
|
__name__,
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||||
self.assertEqual(span.name, expected["name"])
|
self.assertEqual(span.name, expected["name"])
|
||||||
self.assertEqual(span.kind, expected["kind"])
|
self.assertEqual(span.kind, expected["kind"])
|
||||||
self.assertDictEqual(dict(span.attributes), expected["attributes"])
|
self.assertDictEqual(dict(span.attributes), expected["attributes"])
|
||||||
|
self.assertEqual(
|
||||||
|
span.instrumentation_scope.name,
|
||||||
|
"opentelemetry.instrumentation.asgi",
|
||||||
|
)
|
||||||
|
|
||||||
def test_basic_asgi_call(self):
|
def test_basic_asgi_call(self):
|
||||||
"""Test that spans are emitted as expected."""
|
"""Test that spans are emitted as expected."""
|
||||||
|
|
@ -728,6 +732,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||||
self.assertTrue(len(resource_metric.scope_metrics) != 0)
|
self.assertTrue(len(resource_metric.scope_metrics) != 0)
|
||||||
for scope_metric in resource_metric.scope_metrics:
|
for scope_metric in resource_metric.scope_metrics:
|
||||||
self.assertTrue(len(scope_metric.metrics) != 0)
|
self.assertTrue(len(scope_metric.metrics) != 0)
|
||||||
|
self.assertEqual(
|
||||||
|
scope_metric.scope.name,
|
||||||
|
"opentelemetry.instrumentation.asgi",
|
||||||
|
)
|
||||||
for metric in scope_metric.metrics:
|
for metric in scope_metric.metrics:
|
||||||
self.assertIn(metric.name, _expected_metric_names)
|
self.assertIn(metric.name, _expected_metric_names)
|
||||||
data_points = list(metric.data.data_points)
|
data_points = list(metric.data.data_points)
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,7 @@ from opentelemetry.instrumentation.fastapi.version import __version__
|
||||||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
||||||
from opentelemetry.metrics import get_meter
|
from opentelemetry.metrics import get_meter
|
||||||
from opentelemetry.semconv.trace import SpanAttributes
|
from opentelemetry.semconv.trace import SpanAttributes
|
||||||
|
from opentelemetry.trace import get_tracer
|
||||||
from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls
|
from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls
|
||||||
|
|
||||||
_excluded_urls_from_env = get_excluded_urls("FASTAPI")
|
_excluded_urls_from_env = get_excluded_urls("FASTAPI")
|
||||||
|
|
@ -221,6 +222,12 @@ class FastAPIInstrumentor(BaseInstrumentor):
|
||||||
excluded_urls = _excluded_urls_from_env
|
excluded_urls = _excluded_urls_from_env
|
||||||
else:
|
else:
|
||||||
excluded_urls = parse_excluded_urls(excluded_urls)
|
excluded_urls = parse_excluded_urls(excluded_urls)
|
||||||
|
tracer = get_tracer(
|
||||||
|
__name__,
|
||||||
|
__version__,
|
||||||
|
tracer_provider,
|
||||||
|
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||||
|
)
|
||||||
meter = get_meter(
|
meter = get_meter(
|
||||||
__name__,
|
__name__,
|
||||||
__version__,
|
__version__,
|
||||||
|
|
@ -235,7 +242,8 @@ class FastAPIInstrumentor(BaseInstrumentor):
|
||||||
server_request_hook=server_request_hook,
|
server_request_hook=server_request_hook,
|
||||||
client_request_hook=client_request_hook,
|
client_request_hook=client_request_hook,
|
||||||
client_response_hook=client_response_hook,
|
client_response_hook=client_response_hook,
|
||||||
tracer_provider=tracer_provider,
|
# Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation
|
||||||
|
tracer=tracer,
|
||||||
meter=meter,
|
meter=meter,
|
||||||
)
|
)
|
||||||
app._is_instrumented_by_opentelemetry = True
|
app._is_instrumented_by_opentelemetry = True
|
||||||
|
|
@ -298,6 +306,12 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
tracer = get_tracer(
|
||||||
|
__name__,
|
||||||
|
__version__,
|
||||||
|
_InstrumentedFastAPI._tracer_provider,
|
||||||
|
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||||
|
)
|
||||||
meter = get_meter(
|
meter = get_meter(
|
||||||
__name__,
|
__name__,
|
||||||
__version__,
|
__version__,
|
||||||
|
|
@ -311,7 +325,8 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
|
||||||
server_request_hook=_InstrumentedFastAPI._server_request_hook,
|
server_request_hook=_InstrumentedFastAPI._server_request_hook,
|
||||||
client_request_hook=_InstrumentedFastAPI._client_request_hook,
|
client_request_hook=_InstrumentedFastAPI._client_request_hook,
|
||||||
client_response_hook=_InstrumentedFastAPI._client_response_hook,
|
client_response_hook=_InstrumentedFastAPI._client_response_hook,
|
||||||
tracer_provider=_InstrumentedFastAPI._tracer_provider,
|
# Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation
|
||||||
|
tracer=tracer,
|
||||||
meter=meter,
|
meter=meter,
|
||||||
)
|
)
|
||||||
self._is_instrumented_by_opentelemetry = True
|
self._is_instrumented_by_opentelemetry = True
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ class TestFastAPIManualInstrumentation(TestBase):
|
||||||
self.assertEqual(len(spans), 3)
|
self.assertEqual(len(spans), 3)
|
||||||
for span in spans:
|
for span in spans:
|
||||||
self.assertIn("GET /foobar", span.name)
|
self.assertIn("GET /foobar", span.name)
|
||||||
|
self.assertEqual(
|
||||||
|
span.instrumentation_scope.name,
|
||||||
|
"opentelemetry.instrumentation.fastapi",
|
||||||
|
)
|
||||||
|
|
||||||
def test_uninstrument_app(self):
|
def test_uninstrument_app(self):
|
||||||
self._client.get("/foobar")
|
self._client.get("/foobar")
|
||||||
|
|
@ -197,6 +201,10 @@ class TestFastAPIManualInstrumentation(TestBase):
|
||||||
for resource_metric in metrics_list.resource_metrics:
|
for resource_metric in metrics_list.resource_metrics:
|
||||||
self.assertTrue(len(resource_metric.scope_metrics) == 1)
|
self.assertTrue(len(resource_metric.scope_metrics) == 1)
|
||||||
for scope_metric in resource_metric.scope_metrics:
|
for scope_metric in resource_metric.scope_metrics:
|
||||||
|
self.assertEqual(
|
||||||
|
scope_metric.scope.name,
|
||||||
|
"opentelemetry.instrumentation.fastapi",
|
||||||
|
)
|
||||||
self.assertTrue(len(scope_metric.metrics) == 3)
|
self.assertTrue(len(scope_metric.metrics) == 3)
|
||||||
for metric in scope_metric.metrics:
|
for metric in scope_metric.metrics:
|
||||||
self.assertIn(metric.name, _expected_metric_names)
|
self.assertIn(metric.name, _expected_metric_names)
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ from opentelemetry.instrumentation.starlette.package import _instruments
|
||||||
from opentelemetry.instrumentation.starlette.version import __version__
|
from opentelemetry.instrumentation.starlette.version import __version__
|
||||||
from opentelemetry.metrics import get_meter
|
from opentelemetry.metrics import get_meter
|
||||||
from opentelemetry.semconv.trace import SpanAttributes
|
from opentelemetry.semconv.trace import SpanAttributes
|
||||||
|
from opentelemetry.trace import get_tracer
|
||||||
from opentelemetry.util.http import get_excluded_urls
|
from opentelemetry.util.http import get_excluded_urls
|
||||||
|
|
||||||
_excluded_urls = get_excluded_urls("STARLETTE")
|
_excluded_urls = get_excluded_urls("STARLETTE")
|
||||||
|
|
@ -208,6 +209,12 @@ class StarletteInstrumentor(BaseInstrumentor):
|
||||||
tracer_provider=None,
|
tracer_provider=None,
|
||||||
):
|
):
|
||||||
"""Instrument an uninstrumented Starlette application."""
|
"""Instrument an uninstrumented Starlette application."""
|
||||||
|
tracer = get_tracer(
|
||||||
|
__name__,
|
||||||
|
__version__,
|
||||||
|
tracer_provider,
|
||||||
|
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||||
|
)
|
||||||
meter = get_meter(
|
meter = get_meter(
|
||||||
__name__,
|
__name__,
|
||||||
__version__,
|
__version__,
|
||||||
|
|
@ -222,7 +229,8 @@ class StarletteInstrumentor(BaseInstrumentor):
|
||||||
server_request_hook=server_request_hook,
|
server_request_hook=server_request_hook,
|
||||||
client_request_hook=client_request_hook,
|
client_request_hook=client_request_hook,
|
||||||
client_response_hook=client_response_hook,
|
client_response_hook=client_response_hook,
|
||||||
tracer_provider=tracer_provider,
|
# Pass in tracer/meter to get __name__and __version__ of starlette instrumentation
|
||||||
|
tracer=tracer,
|
||||||
meter=meter,
|
meter=meter,
|
||||||
)
|
)
|
||||||
app.is_instrumented_by_opentelemetry = True
|
app.is_instrumented_by_opentelemetry = True
|
||||||
|
|
@ -278,6 +286,12 @@ class _InstrumentedStarlette(applications.Starlette):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
tracer = get_tracer(
|
||||||
|
__name__,
|
||||||
|
__version__,
|
||||||
|
_InstrumentedStarlette._tracer_provider,
|
||||||
|
schema_url="https://opentelemetry.io/schemas/1.11.0",
|
||||||
|
)
|
||||||
meter = get_meter(
|
meter = get_meter(
|
||||||
__name__,
|
__name__,
|
||||||
__version__,
|
__version__,
|
||||||
|
|
@ -291,7 +305,8 @@ class _InstrumentedStarlette(applications.Starlette):
|
||||||
server_request_hook=_InstrumentedStarlette._server_request_hook,
|
server_request_hook=_InstrumentedStarlette._server_request_hook,
|
||||||
client_request_hook=_InstrumentedStarlette._client_request_hook,
|
client_request_hook=_InstrumentedStarlette._client_request_hook,
|
||||||
client_response_hook=_InstrumentedStarlette._client_response_hook,
|
client_response_hook=_InstrumentedStarlette._client_response_hook,
|
||||||
tracer_provider=_InstrumentedStarlette._tracer_provider,
|
# Pass in tracer/meter to get __name__and __version__ of starlette instrumentation
|
||||||
|
tracer=tracer,
|
||||||
meter=meter,
|
meter=meter,
|
||||||
)
|
)
|
||||||
self._is_instrumented_by_opentelemetry = True
|
self._is_instrumented_by_opentelemetry = True
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,10 @@ class TestStarletteManualInstrumentation(TestBase):
|
||||||
self.assertEqual(len(spans), 3)
|
self.assertEqual(len(spans), 3)
|
||||||
for span in spans:
|
for span in spans:
|
||||||
self.assertIn("GET /foobar", span.name)
|
self.assertIn("GET /foobar", span.name)
|
||||||
|
self.assertEqual(
|
||||||
|
span.instrumentation_scope.name,
|
||||||
|
"opentelemetry.instrumentation.starlette",
|
||||||
|
)
|
||||||
|
|
||||||
def test_starlette_route_attribute_added(self):
|
def test_starlette_route_attribute_added(self):
|
||||||
"""Ensure that starlette routes are used as the span name."""
|
"""Ensure that starlette routes are used as the span name."""
|
||||||
|
|
@ -132,6 +136,10 @@ class TestStarletteManualInstrumentation(TestBase):
|
||||||
for resource_metric in metrics_list.resource_metrics:
|
for resource_metric in metrics_list.resource_metrics:
|
||||||
self.assertTrue(len(resource_metric.scope_metrics) == 1)
|
self.assertTrue(len(resource_metric.scope_metrics) == 1)
|
||||||
for scope_metric in resource_metric.scope_metrics:
|
for scope_metric in resource_metric.scope_metrics:
|
||||||
|
self.assertEqual(
|
||||||
|
scope_metric.scope.name,
|
||||||
|
"opentelemetry.instrumentation.starlette",
|
||||||
|
)
|
||||||
self.assertTrue(len(scope_metric.metrics) == 3)
|
self.assertTrue(len(scope_metric.metrics) == 3)
|
||||||
for metric in scope_metric.metrics:
|
for metric in scope_metric.metrics:
|
||||||
self.assertIn(metric.name, _expected_metric_names)
|
self.assertIn(metric.name, _expected_metric_names)
|
||||||
|
|
|
||||||
|
|
@ -533,6 +533,8 @@ class OpenTelemetryMiddleware:
|
||||||
incoming request.
|
incoming request.
|
||||||
tracer_provider: Optional tracer provider to use. If omitted the current
|
tracer_provider: Optional tracer provider to use. If omitted the current
|
||||||
globally configured one is used.
|
globally configured one is used.
|
||||||
|
meter_provider: Optional meter provider to use. If omitted the current
|
||||||
|
globally configured one is used.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue