diff --git a/CHANGELOG.md b/CHANGELOG.md index 93f0cab4fc..868aba56f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation`: Add warning when no `opentelemetry_configurator` + entry points are found, suggesting to install `opentelemetry-distro`. + ([#4543](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4543)) - Bump `pylint` to `4.0.5` ([#4244](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4244)) - `opentelemetry-instrumentation-sqlite3`: Add uninstrument, error status, suppress, and no-op tests diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py index fab95bf843..68712ac244 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/auto_instrumentation/_load.py @@ -187,3 +187,10 @@ def _load_configurators(): except Exception as exc: # pylint: disable=broad-except _logger.exception("Configuration of %s failed", entry_point.name) raise exc + + if configured is None: + _logger.warning( + "No configurator found. Make sure 'opentelemetry-distro' is " + "installed if you are using automatic instrumentation. " + "See https://opentelemetry.io/docs/zero-code/python/ for details." + ) diff --git a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py index c192c819b1..450b93e42c 100644 --- a/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py +++ b/opentelemetry-instrumentation/tests/auto_instrumentation/test_load.py @@ -67,6 +67,14 @@ def test_load_configurators(self, iter_mock): # pylint: disable=no-self-use ) def test_load_configurators_no_ep(self, iter_mock): # pylint: disable=no-self-use iter_mock.return_value = () + with self.assertLogs( + "opentelemetry.instrumentation.auto_instrumentation._load", + level="WARNING", + ) as cm: + _load._load_configurators() + self.assertTrue( + any("opentelemetry-distro" in msg for msg in cm.output) + ) # Confirm method does not crash if not entry points exist. _load._load_configurators()