diff --git a/.gitignore b/.gitignore index 7989886d..a6497b23 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ dist/ build/ .venv/ +.vscode/ .env .pytest_cache/ .mypy_cache/ diff --git a/CHANGELOG.md b/CHANGELOG.md index ecb72abd..3f11fdd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Release History +# 1.3.8 (Unreleased) + +### Other Changes +- Contribute Microsoft distro profile information (`component="mot"` and distro version) to the OneSettings control plane during `use_microsoft_opentelemetry()`. + # 1.3.7 (2026-08-05) ### Features Added - Mark `gen_ai.tool.description` and `gen_ai.tool.definitions` as sensitive attributes per [GenAI Spec](https://github.com/open-telemetry/semantic-conventions-genai/pull/431) @@ -361,4 +366,3 @@ ([#10](https://github.com/microsoft/opentelemetry-distro-python/pull/10)) - Microsoft mandatory file ([#2](https://github.com/microsoft/opentelemetry-distro-python/pull/2)) - diff --git a/pyproject.toml b/pyproject.toml index 92c785ef..6d89f2a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ classifiers = [ dependencies = [ "azure-core<2.0.0,>=1.28.0", "azure-core-tracing-opentelemetry~=1.0.0b11", - "azure-monitor-opentelemetry-exporter~=1.0.0b54", + "azure-monitor-opentelemetry-exporter~=1.0.0b56", "opentelemetry-sdk~=1.43.0", "opentelemetry-api~=1.43.0", "opentelemetry-exporter-otlp-proto-http~=1.43.0", diff --git a/src/microsoft/opentelemetry/_distro.py b/src/microsoft/opentelemetry/_distro.py index 3c5cfcb2..79b2336c 100644 --- a/src/microsoft/opentelemetry/_distro.py +++ b/src/microsoft/opentelemetry/_distro.py @@ -6,7 +6,7 @@ import os from functools import cached_property from logging import getLogger, Formatter -from typing import Any, Dict, List, Optional +from typing import Any, Callable, Dict, List, Optional from opentelemetry.metrics import set_meter_provider from opentelemetry.sdk.metrics import MeterProvider @@ -24,6 +24,14 @@ entry_points, ) +_get_configuration_manager: Optional[Callable[[], Any]] +try: + from azure.monitor.opentelemetry.exporter._configuration._state import ( # pylint: disable=import-error,no-name-in-module + get_configuration_manager as _get_configuration_manager, + ) +except ImportError: + _get_configuration_manager = None + from microsoft.opentelemetry._constants import ( DISABLE_LOGGING_ARG, DISABLE_METRICS_ARG, @@ -95,6 +103,17 @@ _logger = getLogger(__name__) +def _initialize_configuration_manager() -> None: + """Contribute the Microsoft distro identity to the shared OneSettings profile.""" + if _get_configuration_manager is None: + return + + config_manager = _get_configuration_manager() + if config_manager: + # Profile fields are first-wins, so initialize before exporters add their fields. + config_manager.initialize(component="mot", version=VERSION) + + def use_microsoft_opentelemetry(**kwargs: object) -> None: # pylint: disable=too-many-statements """Configure OpenTelemetry with optional Azure Monitor support. @@ -207,6 +226,8 @@ def use_microsoft_opentelemetry(**kwargs: object) -> None: # pylint: disable=to :rtype: None """ + _initialize_configuration_manager() + enable_azure_monitor: bool = bool(kwargs.pop(ENABLE_AZURE_MONITOR_ARG, False)) enable_console: bool = bool(kwargs.pop(ENABLE_CONSOLE_ARG, False)) enable_a365: bool = bool(kwargs.pop(ENABLE_A365_ARG, False)) diff --git a/tests/test_distro.py b/tests/test_distro.py index a45f0de7..ba037d58 100644 --- a/tests/test_distro.py +++ b/tests/test_distro.py @@ -32,6 +32,7 @@ _setup_metrics, _setup_logging, ) +from microsoft.opentelemetry._version import VERSION TEST_RESOURCE = Resource({"service.name": "test-service"}) TEST_CONNECTION_STRING = "InstrumentationKey=test-key;IngestionEndpoint=https://test.in.ai.azure.com/" @@ -40,6 +41,37 @@ class TestUseMicrosoftOpenTelemetry(unittest.TestCase): """Tests for use_microsoft_opentelemetry() orchestration.""" + @patch("microsoft.opentelemetry._distro._append_azure_monitor_components", return_value=(None, None, None)) + @patch("microsoft.opentelemetry._distro._get_configuration_manager") + def test_initializes_config_manager_before_exporters(self, get_config_manager_mock, append_mock): + call_order = [] + config_manager_mock = get_config_manager_mock.return_value + config_manager_mock.initialize.side_effect = lambda *args, **kwargs: call_order.append("initialize") + + def append_azure_monitor_components(*args, **kwargs): + call_order.append("exporter") + return None, None, None + + append_mock.side_effect = append_azure_monitor_components + + use_microsoft_opentelemetry( + enable_azure_monitor=True, + azure_monitor_connection_string=TEST_CONNECTION_STRING, + ) + + config_manager_mock.initialize.assert_called_once_with(component="mot", version=VERSION) + self.assertEqual(call_order, ["initialize", "exporter"]) + + @patch("microsoft.opentelemetry._distro._get_configuration_manager", return_value=None) + def test_configuration_manager_can_be_disabled(self, get_config_manager_mock): + use_microsoft_opentelemetry() + + get_config_manager_mock.assert_called_once_with() + + @patch("microsoft.opentelemetry._distro._get_configuration_manager", None) + def test_configuration_manager_can_be_unavailable(self): + use_microsoft_opentelemetry() + @patch("microsoft.opentelemetry._distro._setup_logging") @patch("microsoft.opentelemetry._distro._setup_metrics") @patch("microsoft.opentelemetry._distro._setup_tracing") diff --git a/uv.lock b/uv.lock index ec1f3984..7626d8c2 100644 --- a/uv.lock +++ b/uv.lock @@ -847,7 +847,7 @@ wheels = [ [[package]] name = "azure-monitor-opentelemetry-exporter" -version = "1.0.0b55" +version = "1.0.0b56" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "azure-core" }, @@ -857,9 +857,9 @@ dependencies = [ { name = "opentelemetry-sdk" }, { name = "psutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/21/178fed00e9738e4c953e147d46f5f803bfeb3fde50b11efdb99ae016f05f/azure_monitor_opentelemetry_exporter-1.0.0b55.tar.gz", hash = "sha256:6701307124e5eeb1837b269ddafab0affb69020fdb842d7c5ff1a3122514595a", size = 342308, upload-time = "2026-07-01T23:59:14.53Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/0e/c74f9bf0b071f5e13c93c285d585ddc96de43658076733cab039844c198a/azure_monitor_opentelemetry_exporter-1.0.0b56.tar.gz", hash = "sha256:d645e2dbde68123a1c0ab6a5705424bae5bbda53495f2cd8be1bb2a78e9f31d3", size = 355000, upload-time = "2026-08-05T22:49:43.804Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/80/c1e58ea1c7dd7452579ab98912e9a3aa9a5fdb22f24a676f3cdaac3ab096/azure_monitor_opentelemetry_exporter-1.0.0b55-py2.py3-none-any.whl", hash = "sha256:5f0bcfcfd36d82f3f55cf5fe894ea05c5c0a32d2e38adf571eaa0e2b655aeb9e", size = 251064, upload-time = "2026-07-01T23:59:16.305Z" }, + { url = "https://files.pythonhosted.org/packages/09/fa/d56f55dae96b8c7ee675ffedbacdb65fd28c5cf00d5134e0fd69aeaea5d1/azure_monitor_opentelemetry_exporter-1.0.0b56-py2.py3-none-any.whl", hash = "sha256:9d006bef633fed895333c6b632eda21411acf5eedcfc396f2813c6d11515278c", size = 255013, upload-time = "2026-08-05T22:49:45.219Z" }, ] [[package]] @@ -2604,7 +2604,7 @@ requires-dist = [ { name = "aiohttp", specifier = ">=3.8.0" }, { name = "azure-core", specifier = ">=1.28.0,<2.0.0" }, { name = "azure-core-tracing-opentelemetry", specifier = "~=1.0.0b11" }, - { name = "azure-monitor-opentelemetry-exporter", specifier = "~=1.0.0b54" }, + { name = "azure-monitor-opentelemetry-exporter", specifier = "~=1.0.0b56" }, { name = "black", marker = "extra == 'dev'", specifier = ">=24.0" }, { name = "langchain-core", marker = "extra == 'langchain'", specifier = ">=0.2.0" }, { name = "microsoft-agents-activity", marker = "extra == 'hosting'", specifier = ">=0.9.0" },