From 17a8678972a24daa60ef897e7e34f11d416d6519 Mon Sep 17 00:00:00 2001
From: Povilas Versockas
Date: Fri, 17 May 2024 06:14:50 +0300
Subject: [PATCH] fix(async-io): check for __name__ atribute when tracing
coroutine
---
CHANGELOG.md | 2 +
.../instrumentation/asyncio/__init__.py | 2 +
.../tests/test_asyncio_anext.py | 56 +++++++++++++++++++
3 files changed, 60 insertions(+)
create mode 100644 instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d10983c10b..b963cfddc2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -53,6 +53,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#2474](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2474))
- `opentelemetry-instrumentation-elasticsearch` Improved support for version 8
([#2420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2420))
+- `opentelemetry-instrumentation-asyncio` Check for __name__ attribute in the coroutine
+ ([#2521](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2521))
## Version 1.24.0/0.45b0 (2024-03-28)
diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py
index 72aa5fd2aa..6d82da6cd0 100644
--- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py
@@ -261,6 +261,8 @@ def trace_item(self, coro_or_future):
return coro_or_future
async def trace_coroutine(self, coro):
+ if not hasattr(coro, "__name__"):
+ return
start = default_timer()
attr = {
"type": "coroutine",
diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py
new file mode 100644
index 0000000000..9ce3fc4b33
--- /dev/null
+++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py
@@ -0,0 +1,56 @@
+# 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 asyncio
+from unittest.mock import patch
+
+# pylint: disable=no-name-in-module
+from opentelemetry.instrumentation.asyncio import AsyncioInstrumentor
+from opentelemetry.instrumentation.asyncio.environment_variables import (
+ OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE,
+)
+from opentelemetry.test.test_base import TestBase
+from opentelemetry.trace import get_tracer
+
+
+class TestAsyncioAnext(TestBase):
+ @patch.dict(
+ "os.environ",
+ {OTEL_PYTHON_ASYNCIO_COROUTINE_NAMES_TO_TRACE: "async_func"},
+ )
+ def setUp(self):
+ super().setUp()
+ AsyncioInstrumentor().instrument()
+ self._tracer = get_tracer(
+ __name__,
+ )
+
+ def tearDown(self):
+ super().tearDown()
+ AsyncioInstrumentor().uninstrument()
+
+ # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced.
+ # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute.
+ def test_asyncio_anext(self):
+ async def main():
+ async def async_gen():
+ for it in range(2):
+ yield it
+
+ async_gen_instance = async_gen()
+ agen = anext(async_gen_instance)
+ await asyncio.create_task(agen)
+
+ asyncio.run(main())
+ spans = self.memory_exporter.get_finished_spans()
+ self.assertEqual(len(spans), 0)