diff --git a/libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/config.py b/libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/config.py index 6c3befd..68acc38 100644 --- a/libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/config.py +++ b/libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/config.py @@ -1,12 +1,14 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +import os import logging import threading from collections.abc import Callable from typing import Any, Optional from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ConsoleSpanExporter @@ -161,10 +163,11 @@ def _configure_internal( use_s2s_endpoint=exporter_options.use_s2s_endpoint, suppress_invoke_agent_input=suppress_invoke_agent_input, ) + else: exporter = ConsoleSpanExporter() self._logger.warning( - "is_agent365_exporter_enabled() not enabled or token_resolver not set.Falling back to console exporter." + "is_agent365_exporter_enabled() not enabled or token_resolver not set. Falling back to console exporter." ) # Add span processors @@ -181,6 +184,13 @@ def _configure_internal( self._span_processors["batch"] = batch_processor self._span_processors["agent"] = agent_processor + if os.environ.get("ENABLE_OTLP_EXPORTER", "").lower() == "true": + # The OTLPSpanExporter is auto configured from the environment variables + otlp_exporter = OTLPSpanExporter() + tracer_provider.add_span_processor( + _EnrichingBatchSpanProcessor(otlp_exporter, **batch_processor_kwargs) + ) + # Configure logging if logger_name is provided if logger_name: target_logger = logging.getLogger(logger_name) diff --git a/tests/observability/core/test_agent365.py b/tests/observability/core/test_agent365.py index 358b935..f8c4869 100644 --- a/tests/observability/core/test_agent365.py +++ b/tests/observability/core/test_agent365.py @@ -201,6 +201,42 @@ def test_configure_uses_existing_tracer_provider(self, mock_get_provider, mock_i self.assertIn("_EnrichingBatchSpanProcessor", processor_types) self.assertIn("SpanProcessor", processor_types) + @patch("microsoft_agents_a365.observability.core.config.OTLPSpanExporter") + @patch( + "microsoft_agents_a365.observability.core.config.is_agent365_exporter_enabled", + return_value=False, + ) + @patch.dict("os.environ", {"ENABLE_OTLP_EXPORTER": "true"}, clear=True) + def test_otlp_exporter_initialized_when_env_var_set(self, mock_is_enabled, mock_otlp_exporter): + """Test that OTLPSpanExporter is initialized when ENABLE_OTLP_EXPORTER is set.""" + + result = configure( + service_name="test-service", + service_namespace="test-namespace", + ) + + self.assertTrue(result, "configure() should return True") + mock_otlp_exporter.assert_called_once() + + @patch("microsoft_agents_a365.observability.core.config.OTLPSpanExporter") + @patch( + "microsoft_agents_a365.observability.core.config.is_agent365_exporter_enabled", + return_value=False, + ) + @patch.dict("os.environ", {}, clear=True) + def test_otlp_exporter_not_initialized_when_env_var_not_set( + self, mock_is_enabled, mock_otlp_exporter + ): + """Test that OTLPSpanExporter is NOT initialized when ENABLE_OTLP_EXPORTER is not set.""" + + result = configure( + service_name="test-service", + service_namespace="test-namespace", + ) + + self.assertTrue(result, "configure() should return True") + mock_otlp_exporter.assert_not_called() + if __name__ == "__main__": unittest.main()