Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ def instrumentation_dependencies(self) -> Collection[str]:
def _instrument(self, **kwargs: Any) -> None:
# Enable the Agent Framework SDK's built-in span generation so users
# don't need to call enable_instrumentation() manually.
enable_sensitive_data = kwargs.get("enable_sensitive_data", False)
try:
from agent_framework.observability import enable_instrumentation

enable_instrumentation()
enable_instrumentation(enable_sensitive_data=enable_sensitive_data)
self._af_instrumentation_enabled = True
except ImportError as exc:
_logger.debug(
Expand Down
2 changes: 2 additions & 0 deletions src/microsoft/opentelemetry/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@

# --- Spectra Sidecar Constants ---

ENABLE_SENSITIVE_DATA_ARG = "enable_sensitive_data"

ENABLE_SPECTRA_ARG = "enable_spectra"
SPECTRA_ENDPOINT_ARG = "spectra_endpoint"
SPECTRA_PROTOCOL_ARG = "spectra_protocol"
Expand Down
12 changes: 9 additions & 3 deletions src/microsoft/opentelemetry/_distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
DISABLE_METRICS_ARG,
DISABLE_TRACING_ARG,
ENABLE_A365_ARG,
ENABLE_SENSITIVE_DATA_ARG,
ENABLE_SPECTRA_ARG,
SPECTRA_ENDPOINT_ARG,
SPECTRA_PROTOCOL_ARG,
Expand Down Expand Up @@ -186,6 +187,9 @@ def use_microsoft_opentelemetry(**kwargs: object) -> None: # pylint: disable=to
``SPECTRA_PROTOCOL`` env var. Defaults to ``"grpc"``.
:keyword bool spectra_insecure:
Use insecure (no TLS) connection. Defaults to True (localhost sidecar).
:keyword bool enable_sensitive_data:
Enable sensitive data recording (prompts, tool arguments, results) for
the Agent Framework SDK instrumentation. Defaults to False.
:rtype: None
"""

Expand All @@ -209,6 +213,8 @@ def use_microsoft_opentelemetry(**kwargs: object) -> None: # pylint: disable=to
spectra_protocol = kwargs.pop(SPECTRA_PROTOCOL_ARG, None)
spectra_insecure = kwargs.pop(SPECTRA_INSECURE_ARG, None)

enable_sensitive_data: bool = bool(kwargs.pop(ENABLE_SENSITIVE_DATA_ARG, False))

# Separate Azure Monitor kwargs from generic OTel kwargs
otel_kwargs: Dict[str, Any] = {k: v for k, v in kwargs.items() if k not in _AZURE_MONITOR_KWARG_MAP}
azure_monitor_kwargs: Dict[str, Any] = {
Expand Down Expand Up @@ -311,7 +317,7 @@ def use_microsoft_opentelemetry(**kwargs: object) -> None: # pylint: disable=to
set_logger_provider(logger_provider)

# ---- Instrumentations (always, after providers are set) ----
_setup_instrumentations(otel_kwargs)
_setup_instrumentations(otel_kwargs, **{ENABLE_SENSITIVE_DATA_ARG: enable_sensitive_data})

# ---- SDKStats manager (after providers, before returning) ----
_initialize_sdkstats(enable_azure_monitor)
Expand Down Expand Up @@ -670,7 +676,7 @@ def _is_instrumentation_enabled(otel_kwargs: Dict[str, Any], lib_name: str) -> b
return lib_options["enabled"] is True


def _setup_instrumentations(otel_kwargs: Dict[str, Any]) -> None:
def _setup_instrumentations(otel_kwargs: Dict[str, Any], **kwargs: Any) -> None:
"""Discover and activate OTel instrumentations for supported libraries."""
entry_point_finder = _EntryPointDistFinder()
for entry_point in entry_points(group="opentelemetry_instrumentor"):
Expand All @@ -691,7 +697,7 @@ def _setup_instrumentations(otel_kwargs: Dict[str, Any]) -> None:
)
continue
instrumentor: Any = entry_point.load()
instrumentor().instrument(skip_dep_check=True)
instrumentor().instrument(skip_dep_check=True, **kwargs)
set_sdkstats_instrumentation_by_name(lib_name)
except Exception as ex: # pylint: disable=broad-except
_logger.warning(
Expand Down
24 changes: 22 additions & 2 deletions tests/agent_framework/test_trace_instrumentor.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,27 @@ def test_instrument_calls_enable_instrumentation_when_available(self, mock_get_p
instrumentor = AgentFrameworkInstrumentor()
instrumentor._instrument()

mock_enable.assert_called_once()
mock_enable.assert_called_once_with(enable_sensitive_data=False)
self.assertTrue(instrumentor._af_instrumentation_enabled)

@patch("microsoft.opentelemetry._agent_framework._trace_instrumentor.get_tracer_provider")
def test_instrument_enables_sensitive_data_when_kwarg_set(self, mock_get_provider):
"""When enable_sensitive_data=True is passed as kwarg,
enable_instrumentation must be called with enable_sensitive_data=True."""
mock_get_provider.return_value = MagicMock()
mock_enable = MagicMock()

with patch.dict(
"sys.modules",
{
"agent_framework": MagicMock(),
"agent_framework.observability": MagicMock(enable_instrumentation=mock_enable),
},
):
instrumentor = AgentFrameworkInstrumentor()
instrumentor._instrument(enable_sensitive_data=True)

mock_enable.assert_called_once_with(enable_sensitive_data=True)
self.assertTrue(instrumentor._af_instrumentation_enabled)

@patch("microsoft.opentelemetry._agent_framework._trace_instrumentor.get_tracer_provider")
Expand Down Expand Up @@ -188,7 +208,7 @@ def test_enable_instrumentation_called_in_azure_monitor_only_scenario(self, mock
instrumentor._instrument()

# AF SDK enabled, span processor added, enricher NOT registered.
mock_enable.assert_called_once()
mock_enable.assert_called_once_with(enable_sensitive_data=False)
self.assertTrue(instrumentor._af_instrumentation_enabled)
mock_provider.add_span_processor.assert_called_once()
self.assertFalse(instrumentor._owns_enricher)
Expand Down
Loading