Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use asgi name and version for tracer/meter for instrumentations using Asgi Middleware #2580

Merged
merged 19 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
27e4c2c
Update .pylintrc
lzchen Apr 3, 2024
c6b4c05
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Apr 5, 2024
f690fc8
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Apr 9, 2024
008c36a
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Apr 16, 2024
b36c916
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Apr 22, 2024
2a30d60
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Apr 24, 2024
4cd5349
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen May 13, 2024
5a7b9ad
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen May 22, 2024
b721434
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen May 23, 2024
6ce38bd
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen May 28, 2024
df3275c
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen May 31, 2024
cffc12f
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Jun 4, 2024
df80e8a
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
lzchen Jun 5, 2024
44a0664
asgi
lzchen Jun 5, 2024
939d1a2
changlog
lzchen Jun 5, 2024
d18610a
tests
lzchen Jun 6, 2024
6c98982
Update test_asgi_middleware.py
lzchen Jun 6, 2024
b9c66c0
Update test_asgi_middleware.py
lzchen Jun 6, 2024
06bfc11
lint
lzchen Jun 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## 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

- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ class OpenTelemetryMiddleware:
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
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
Expand All @@ -474,17 +476,22 @@ def __init__(
client_response_hook: ClientResponseHook = None,
tracer_provider=None,
meter_provider=None,
tracer=None,
meter=None,
http_capture_headers_server_request: list[str] | None = None,
http_capture_headers_server_response: list[str] | None = None,
http_capture_headers_sanitize_fields: list[str] | None = None,
):
self.app = guarantee_single_callable(app)
self.tracer = trace.get_tracer(
__name__,
__version__,
tracer_provider,
schema_url="https://opentelemetry.io/schemas/1.11.0",
self.tracer = (
trace.get_tracer(
__name__,
__version__,
tracer_provider,
schema_url="https://opentelemetry.io/schemas/1.11.0",
)
if tracer is None
else tracer
)
self.meter = (
get_meter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ def validate_outputs(self, outputs, error=None, modifiers=None):
self.assertEqual(span.name, expected["name"])
self.assertEqual(span.kind, expected["kind"])
self.assertDictEqual(dict(span.attributes), expected["attributes"])
self.assertEqual(
span.instrumentation_scope.name,
"opentelemetry.instrumentation.asgi",
)

def test_basic_asgi_call(self):
"""Test that spans are emitted as expected."""
Expand Down Expand Up @@ -728,6 +732,10 @@ def test_asgi_metrics(self):
self.assertTrue(len(resource_metric.scope_metrics) != 0)
for scope_metric in resource_metric.scope_metrics:
self.assertTrue(len(scope_metric.metrics) != 0)
self.assertEqual(
scope_metric.scope.name,
"opentelemetry.instrumentation.asgi",
)
for metric in scope_metric.metrics:
self.assertIn(metric.name, _expected_metric_names)
data_points = list(metric.data.data_points)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
from opentelemetry.metrics import get_meter
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import get_tracer
from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls

_excluded_urls_from_env = get_excluded_urls("FASTAPI")
Expand Down Expand Up @@ -221,6 +222,12 @@ def instrument_app(
excluded_urls = _excluded_urls_from_env
else:
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(
__name__,
__version__,
Expand All @@ -235,7 +242,8 @@ def instrument_app(
server_request_hook=server_request_hook,
client_request_hook=client_request_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,
)
app._is_instrumented_by_opentelemetry = True
Expand Down Expand Up @@ -298,6 +306,12 @@ class _InstrumentedFastAPI(fastapi.FastAPI):

def __init__(self, *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(
__name__,
__version__,
Expand All @@ -311,7 +325,8 @@ def __init__(self, *args, **kwargs):
server_request_hook=_InstrumentedFastAPI._server_request_hook,
client_request_hook=_InstrumentedFastAPI._client_request_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,
)
self._is_instrumented_by_opentelemetry = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ def test_instrument_app_with_instrument(self):
self.assertEqual(len(spans), 3)
for span in spans:
self.assertIn("GET /foobar", span.name)
self.assertEqual(
span.instrumentation_scope.name,
"opentelemetry.instrumentation.fastapi",
)

def test_uninstrument_app(self):
self._client.get("/foobar")
Expand Down Expand Up @@ -197,6 +201,10 @@ def test_fastapi_metrics(self):
for resource_metric in metrics_list.resource_metrics:
self.assertTrue(len(resource_metric.scope_metrics) == 1)
for scope_metric in resource_metric.scope_metrics:
self.assertEqual(
scope_metric.scope.name,
"opentelemetry.instrumentation.fastapi",
)
self.assertTrue(len(scope_metric.metrics) == 3)
for metric in scope_metric.metrics:
self.assertIn(metric.name, _expected_metric_names)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
from opentelemetry.instrumentation.starlette.version import __version__
from opentelemetry.metrics import get_meter
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import get_tracer
from opentelemetry.util.http import get_excluded_urls

_excluded_urls = get_excluded_urls("STARLETTE")
Expand All @@ -208,6 +209,12 @@ def instrument_app(
tracer_provider=None,
):
"""Instrument an uninstrumented Starlette application."""
tracer = get_tracer(
__name__,
__version__,
tracer_provider,
schema_url="https://opentelemetry.io/schemas/1.11.0",
)
meter = get_meter(
__name__,
__version__,
Expand All @@ -222,7 +229,8 @@ def instrument_app(
server_request_hook=server_request_hook,
client_request_hook=client_request_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,
)
app.is_instrumented_by_opentelemetry = True
Expand Down Expand Up @@ -278,6 +286,12 @@ class _InstrumentedStarlette(applications.Starlette):

def __init__(self, *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(
__name__,
__version__,
Expand All @@ -291,7 +305,8 @@ def __init__(self, *args, **kwargs):
server_request_hook=_InstrumentedStarlette._server_request_hook,
client_request_hook=_InstrumentedStarlette._client_request_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,
)
self._is_instrumented_by_opentelemetry = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def test_basic_starlette_call(self):
self.assertEqual(len(spans), 3)
for span in spans:
self.assertIn("GET /foobar", span.name)
self.assertEqual(
span.instrumentation_scope.name,
"opentelemetry.instrumentation.starlette",
)

def test_starlette_route_attribute_added(self):
"""Ensure that starlette routes are used as the span name."""
Expand Down Expand Up @@ -132,6 +136,10 @@ def test_starlette_metrics(self):
for resource_metric in metrics_list.resource_metrics:
self.assertTrue(len(resource_metric.scope_metrics) == 1)
for scope_metric in resource_metric.scope_metrics:
self.assertEqual(
scope_metric.scope.name,
"opentelemetry.instrumentation.starlette",
)
self.assertTrue(len(scope_metric.metrics) == 3)
for metric in scope_metric.metrics:
self.assertIn(metric.name, _expected_metric_names)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ class OpenTelemetryMiddleware:
incoming request.
tracer_provider: Optional tracer provider to use. If omitted the current
globally configured one is used.
meter_provider: Optional meter provider to use. If omitted the current
globally configured one is used.
"""

def __init__(
Expand Down