mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Add disable_instrumentation() with sticky user-intent semantics
Add a public disable_instrumentation() entry point so users can explicitly opt out of Agent Framework telemetry, with a sticky-disable flag that makes the user's intent "leading" — no framework code path (foundry's configure_azure_monitor, configure_otel_providers, enable_instrumentation, enable_sensitive_telemetry, or direct OBSERVABILITY_SETTINGS.enable_* writes) can re-enable instrumentation until the user explicitly clears the disable with enable_instrumentation(force=True) / enable_sensitive_telemetry(force=True). Also addresses the two remaining unresolved review threads on the PR: 1. test_observability_settings_defaults_instrumentation_true pins the new "ENABLE_INSTRUMENTATION defaults to True when env unset" behavior. 2. test_enable_instrumentation_reads_env_sensitive_data restores coverage for the post-import load_dotenv() fallback path. Implementation: - ObservabilitySettings.enable_instrumentation / enable_sensitive_data become properties backed by _enable_*. While _user_disabled is True, the getters return False and the setters drop True writes (defense in depth so third- party writes can't subvert the disable). - Public is_user_disabled read-only property lets integrations (e.g. foundry's configure_azure_monitor) cheaply check the disable state without poking at privates. - enable_instrumentation() and enable_sensitive_telemetry() short-circuit with an info log when disabled; gain a force=True kwarg that clears the disable. - configure_otel_providers() still creates providers / exporters / views so a later force-enable can use them, but logs an info message when called while disabled. - Foundry's FoundryChatClient.configure_azure_monitor and FoundryAgent.configure_azure_monitor early-return when the user has disabled, so Azure Monitor's global providers aren't installed unnecessarily. Tests: 11 new tests covering default-on, env re-read at call time, sticky behavior against each re-enable surface (enable_instrumentation, enable_sensitive_telemetry, configure_otel_providers, direct attribute writes), force=True override, re-arming the disable, and the __all__ export. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
Commonly used exports:
|
||||
- enable_instrumentation
|
||||
- disable_instrumentation
|
||||
- enable_sensitive_telemetry
|
||||
- configure_otel_providers
|
||||
- AgentTelemetryLayer
|
||||
@@ -81,6 +82,7 @@ __all__ = [
|
||||
"configure_otel_providers",
|
||||
"create_metric_views",
|
||||
"create_resource",
|
||||
"disable_instrumentation",
|
||||
"enable_instrumentation",
|
||||
"enable_sensitive_telemetry",
|
||||
"get_meter",
|
||||
@@ -679,11 +681,18 @@ class ObservabilitySettings:
|
||||
env_file_encoding=env_file_encoding,
|
||||
**kwargs,
|
||||
)
|
||||
# Sticky-disable flag, set by `disable_instrumentation()`. When True, this
|
||||
# singleton refuses to be re-enabled by any subsequent assignment to the
|
||||
# `enable_instrumentation` / `enable_sensitive_data` properties (including
|
||||
# direct third-party writes). It can only be cleared by an explicit
|
||||
# `enable_instrumentation(force=True)` / `enable_sensitive_telemetry(force=True)`
|
||||
# call, which is the user re-stating their intent.
|
||||
self._user_disabled: bool = False
|
||||
# `enable_instrumentation` is defaulted to True if not set
|
||||
instrumentation_value = data.get("enable_instrumentation")
|
||||
self.enable_instrumentation: bool = True if instrumentation_value is None else instrumentation_value
|
||||
self.enable_sensitive_data: bool = data.get("enable_sensitive_data") or False
|
||||
if self.enable_sensitive_data and not self.enable_instrumentation:
|
||||
self._enable_instrumentation: bool = True if instrumentation_value is None else instrumentation_value
|
||||
self._enable_sensitive_data: bool = data.get("enable_sensitive_data") or False
|
||||
if self._enable_sensitive_data and not self._enable_instrumentation:
|
||||
logger.warning(
|
||||
"Sensitive data capture is enabled but instrumentation is disabled. "
|
||||
"Sensitive data will not be captured. Please enable instrumentation to capture sensitive data."
|
||||
@@ -695,6 +704,51 @@ class ObservabilitySettings:
|
||||
self.env_file_encoding = env_file_encoding
|
||||
self._executed_setup = False
|
||||
|
||||
@property
|
||||
def enable_instrumentation(self) -> bool:
|
||||
"""Whether instrumentation is enabled.
|
||||
|
||||
Always returns False once ``disable_instrumentation()`` has been called,
|
||||
regardless of the stored value, until ``enable_instrumentation(force=True)``
|
||||
clears the sticky disable.
|
||||
"""
|
||||
if self._user_disabled:
|
||||
return False
|
||||
return self._enable_instrumentation
|
||||
|
||||
@enable_instrumentation.setter
|
||||
def enable_instrumentation(self, value: bool) -> None:
|
||||
if self._user_disabled and value:
|
||||
# Defense in depth: a third-party (or internal) write of True is
|
||||
# silently dropped while the user-disabled flag is set, so the
|
||||
# sticky disable cannot be circumvented by direct attribute writes.
|
||||
logger.debug(
|
||||
"Ignoring enable_instrumentation=True assignment: instrumentation was explicitly disabled via "
|
||||
"disable_instrumentation(). Call enable_instrumentation(force=True) to clear the disable."
|
||||
)
|
||||
return
|
||||
self._enable_instrumentation = value
|
||||
|
||||
@property
|
||||
def enable_sensitive_data(self) -> bool:
|
||||
"""Whether sensitive-data capture is enabled.
|
||||
|
||||
Always returns False once ``disable_instrumentation()`` has been called.
|
||||
"""
|
||||
if self._user_disabled:
|
||||
return False
|
||||
return self._enable_sensitive_data
|
||||
|
||||
@enable_sensitive_data.setter
|
||||
def enable_sensitive_data(self, value: bool) -> None:
|
||||
if self._user_disabled and value:
|
||||
logger.debug(
|
||||
"Ignoring enable_sensitive_data=True assignment: instrumentation was explicitly disabled via "
|
||||
"disable_instrumentation(). Call enable_sensitive_telemetry(force=True) to clear the disable."
|
||||
)
|
||||
return
|
||||
self._enable_sensitive_data = value
|
||||
|
||||
@property
|
||||
def ENABLED(self) -> bool:
|
||||
"""Check if model diagnostics are enabled.
|
||||
@@ -716,6 +770,17 @@ class ObservabilitySettings:
|
||||
"""Check if the setup has been executed."""
|
||||
return self._executed_setup
|
||||
|
||||
@property
|
||||
def is_user_disabled(self) -> bool:
|
||||
"""Whether ``disable_instrumentation()`` has been called and the disable is still in effect.
|
||||
|
||||
Integrations that perform telemetry setup as a side-effect (e.g. provisioning Azure Monitor
|
||||
providers from a Foundry project's connection string) should consult this flag before doing
|
||||
their setup work, so the user's explicit opt-out is respected end-to-end and not just at the
|
||||
framework's span-emission boundary.
|
||||
"""
|
||||
return self._user_disabled
|
||||
|
||||
def _configure(
|
||||
self,
|
||||
*,
|
||||
@@ -961,7 +1026,7 @@ def _read_int_env(name: str, *, default: int | None = None) -> int | None:
|
||||
return default
|
||||
|
||||
|
||||
def enable_sensitive_telemetry() -> None:
|
||||
def enable_sensitive_telemetry(*, force: bool = False) -> None:
|
||||
"""Enable capture of sensitive data in telemetry for your application.
|
||||
|
||||
Instrumentation is enabled by default; this method exists to opt-in to capturing
|
||||
@@ -971,17 +1036,57 @@ def enable_sensitive_telemetry() -> None:
|
||||
instrumentation is enabled (in case it was explicitly disabled via the
|
||||
ENABLE_INSTRUMENTATION environment variable).
|
||||
|
||||
Keyword Args:
|
||||
force: When True, clears any sticky disable previously set by
|
||||
``disable_instrumentation()`` before enabling. Without it, calls are
|
||||
no-ops if instrumentation has been explicitly disabled.
|
||||
|
||||
Warning:
|
||||
Sensitive events should only be enabled on test and development environments.
|
||||
"""
|
||||
global OBSERVABILITY_SETTINGS
|
||||
if OBSERVABILITY_SETTINGS._user_disabled and not force: # type: ignore[reportPrivateUsage]
|
||||
logger.info(
|
||||
"enable_sensitive_telemetry() ignored: instrumentation was explicitly disabled via "
|
||||
"disable_instrumentation(). Pass force=True to re-enable."
|
||||
)
|
||||
return
|
||||
if force:
|
||||
OBSERVABILITY_SETTINGS._user_disabled = False # type: ignore[reportPrivateUsage]
|
||||
OBSERVABILITY_SETTINGS.enable_instrumentation = True
|
||||
OBSERVABILITY_SETTINGS.enable_sensitive_data = True
|
||||
|
||||
|
||||
def disable_instrumentation() -> None:
|
||||
"""Explicitly disable Agent Framework instrumentation for this process.
|
||||
|
||||
The disable is **sticky**: subsequent attempts by framework auto-setup paths,
|
||||
library integrations, ``enable_instrumentation()``, ``enable_sensitive_telemetry()``,
|
||||
``configure_otel_providers()``, or direct writes to
|
||||
``OBSERVABILITY_SETTINGS.enable_instrumentation`` are ignored and no spans, metrics,
|
||||
or logs are emitted by Agent Framework code paths.
|
||||
|
||||
To override the disable later, call ``enable_instrumentation(force=True)`` or
|
||||
``enable_sensitive_telemetry(force=True)``. This makes the user's intent to opt out
|
||||
win against framework code that would otherwise re-enable instrumentation
|
||||
automatically.
|
||||
|
||||
Note:
|
||||
Disabling does not tear down already-configured OpenTelemetry providers,
|
||||
exporters, or in-flight spans; it gates future captures by Agent Framework
|
||||
instrumentation only. To stop emitting telemetry from third-party
|
||||
instrumentations as well, configure them separately.
|
||||
"""
|
||||
global OBSERVABILITY_SETTINGS
|
||||
OBSERVABILITY_SETTINGS._user_disabled = True # type: ignore[reportPrivateUsage]
|
||||
OBSERVABILITY_SETTINGS._enable_instrumentation = False # type: ignore[reportPrivateUsage]
|
||||
OBSERVABILITY_SETTINGS._enable_sensitive_data = False # type: ignore[reportPrivateUsage]
|
||||
|
||||
|
||||
def enable_instrumentation(
|
||||
*,
|
||||
enable_sensitive_data: bool | None = None,
|
||||
force: bool = False,
|
||||
) -> None:
|
||||
"""Enable instrumentation for Microsoft Agent Framework.
|
||||
|
||||
@@ -993,8 +1098,19 @@ def enable_instrumentation(
|
||||
Keyword Args:
|
||||
enable_sensitive_data: Enable OpenTelemetry sensitive events. Overrides
|
||||
the environment variable ENABLE_SENSITIVE_DATA if set. Default is None.
|
||||
force: When True, clears any sticky disable previously set by
|
||||
``disable_instrumentation()`` before enabling. Without it, calls are
|
||||
no-ops if instrumentation has been explicitly disabled.
|
||||
"""
|
||||
global OBSERVABILITY_SETTINGS
|
||||
if OBSERVABILITY_SETTINGS._user_disabled and not force: # type: ignore[reportPrivateUsage]
|
||||
logger.info(
|
||||
"enable_instrumentation() ignored: instrumentation was explicitly disabled via "
|
||||
"disable_instrumentation(). Pass force=True to re-enable."
|
||||
)
|
||||
return
|
||||
if force:
|
||||
OBSERVABILITY_SETTINGS._user_disabled = False # type: ignore[reportPrivateUsage]
|
||||
OBSERVABILITY_SETTINGS.enable_instrumentation = True
|
||||
if enable_sensitive_data is not None:
|
||||
OBSERVABILITY_SETTINGS.enable_sensitive_data = enable_sensitive_data
|
||||
@@ -1125,6 +1241,12 @@ def configure_otel_providers(
|
||||
- https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/
|
||||
"""
|
||||
global OBSERVABILITY_SETTINGS
|
||||
if OBSERVABILITY_SETTINGS._user_disabled: # type: ignore[reportPrivateUsage]
|
||||
logger.info(
|
||||
"configure_otel_providers(): instrumentation was explicitly disabled via "
|
||||
"disable_instrumentation(); providers and exporters will still be configured but "
|
||||
"Agent Framework will emit no telemetry until enable_instrumentation(force=True) is called."
|
||||
)
|
||||
if env_file_path:
|
||||
# Build kwargs, excluding None values
|
||||
settings_kwargs: dict[str, Any] = {
|
||||
|
||||
@@ -1387,6 +1387,189 @@ def test_configure_otel_providers_explicit_console_exporters_overrides_env(monke
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_console_exporters is False
|
||||
|
||||
|
||||
# region Test default-on instrumentation
|
||||
|
||||
|
||||
def test_observability_settings_defaults_instrumentation_true(monkeypatch):
|
||||
"""ENABLE_INSTRUMENTATION unset → ObservabilitySettings defaults to True."""
|
||||
from agent_framework.observability import ObservabilitySettings
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
settings = ObservabilitySettings()
|
||||
assert settings.enable_instrumentation is True
|
||||
|
||||
|
||||
def test_enable_instrumentation_reads_env_sensitive_data(monkeypatch):
|
||||
"""No-arg enable_instrumentation() re-reads ENABLE_SENSITIVE_DATA from env at call time.
|
||||
|
||||
Covers the fallback branch where the env var is set AFTER import (e.g. via load_dotenv()).
|
||||
"""
|
||||
import importlib
|
||||
|
||||
monkeypatch.setenv("ENABLE_INSTRUMENTATION", "false")
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
# Simulate load_dotenv() setting the env var after import
|
||||
monkeypatch.setenv("ENABLE_SENSITIVE_DATA", "true")
|
||||
observability.enable_instrumentation()
|
||||
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is True
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is True
|
||||
|
||||
|
||||
# region Test disable_instrumentation sticky behavior
|
||||
|
||||
|
||||
def test_disable_instrumentation_flips_settings_off(monkeypatch):
|
||||
"""disable_instrumentation() immediately turns instrumentation and sensitive data off."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.setenv("ENABLE_SENSITIVE_DATA", "true")
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.enable_sensitive_telemetry()
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is True
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is True
|
||||
assert observability.OBSERVABILITY_SETTINGS.SENSITIVE_DATA_ENABLED is True
|
||||
|
||||
observability.disable_instrumentation()
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.SENSITIVE_DATA_ENABLED is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.ENABLED is False
|
||||
|
||||
|
||||
def test_disable_instrumentation_is_sticky_against_enable_instrumentation(monkeypatch):
|
||||
"""Sticky disable: enable_instrumentation() without force is a no-op after disable."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_instrumentation(enable_sensitive_data=True)
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is False
|
||||
|
||||
|
||||
def test_disable_instrumentation_is_sticky_against_enable_sensitive_telemetry(monkeypatch):
|
||||
"""Sticky disable: enable_sensitive_telemetry() without force is a no-op after disable."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_sensitive_telemetry()
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is False
|
||||
|
||||
|
||||
def test_disable_instrumentation_is_sticky_against_configure_otel_providers(monkeypatch):
|
||||
"""Sticky disable: configure_otel_providers() does not flip instrumentation back on."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
with patch.object(observability.OBSERVABILITY_SETTINGS, "_configure"):
|
||||
observability.configure_otel_providers(enable_sensitive_data=True)
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is False
|
||||
|
||||
|
||||
def test_disable_instrumentation_intercepts_direct_attribute_writes(monkeypatch):
|
||||
"""Sticky disable: direct OBSERVABILITY_SETTINGS.enable_instrumentation = True is intercepted."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.OBSERVABILITY_SETTINGS.enable_instrumentation = True
|
||||
observability.OBSERVABILITY_SETTINGS.enable_sensitive_data = True
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is False
|
||||
|
||||
|
||||
def test_enable_instrumentation_force_clears_disable(monkeypatch):
|
||||
"""enable_instrumentation(force=True) clears the sticky disable."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_instrumentation(force=True, enable_sensitive_data=True)
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is True
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is True
|
||||
|
||||
|
||||
def test_enable_sensitive_telemetry_force_clears_disable(monkeypatch):
|
||||
"""enable_sensitive_telemetry(force=True) clears the sticky disable."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_sensitive_telemetry(force=True)
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is True
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_sensitive_data is True
|
||||
|
||||
|
||||
def test_disable_instrumentation_persists_after_force_until_redisabled(monkeypatch):
|
||||
"""After force-enable then disable again, the sticky disable is re-armed."""
|
||||
import importlib
|
||||
|
||||
monkeypatch.delenv("ENABLE_INSTRUMENTATION", raising=False)
|
||||
monkeypatch.delenv("ENABLE_SENSITIVE_DATA", raising=False)
|
||||
|
||||
observability = importlib.import_module("agent_framework.observability")
|
||||
importlib.reload(observability)
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_instrumentation(force=True)
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is True
|
||||
|
||||
observability.disable_instrumentation()
|
||||
observability.enable_instrumentation()
|
||||
assert observability.OBSERVABILITY_SETTINGS.enable_instrumentation is False
|
||||
|
||||
|
||||
def test_disable_instrumentation_in_all(monkeypatch):
|
||||
"""disable_instrumentation must be re-exported from the module's __all__."""
|
||||
import agent_framework.observability as observability
|
||||
|
||||
assert "disable_instrumentation" in observability.__all__
|
||||
assert callable(observability.disable_instrumentation)
|
||||
|
||||
|
||||
# region Test _to_otel_part content types
|
||||
|
||||
|
||||
|
||||
@@ -793,8 +793,22 @@ class RawFoundryAgent( # type: ignore[misc]
|
||||
Raises:
|
||||
ImportError: If azure-monitor-opentelemetry-exporter is not installed.
|
||||
"""
|
||||
from agent_framework.observability import (
|
||||
OBSERVABILITY_SETTINGS,
|
||||
create_metric_views,
|
||||
create_resource,
|
||||
enable_instrumentation,
|
||||
)
|
||||
from azure.core.exceptions import ResourceNotFoundError
|
||||
|
||||
if OBSERVABILITY_SETTINGS.is_user_disabled:
|
||||
logger.info(
|
||||
"FoundryAgent.configure_azure_monitor(): Skipping setup because instrumentation was "
|
||||
"explicitly disabled via disable_instrumentation(). Call enable_instrumentation(force=True) "
|
||||
"to re-enable, then re-invoke configure_azure_monitor()."
|
||||
)
|
||||
return
|
||||
|
||||
client = self.client
|
||||
if not isinstance(client, RawFoundryAgentChatClient):
|
||||
raise TypeError("configure_azure_monitor requires a RawFoundryAgentChatClient-based client.")
|
||||
@@ -817,8 +831,6 @@ class RawFoundryAgent( # type: ignore[misc]
|
||||
"Install it with: pip install azure-monitor-opentelemetry"
|
||||
) from exc
|
||||
|
||||
from agent_framework.observability import create_metric_views, create_resource, enable_instrumentation
|
||||
|
||||
if "resource" not in kwargs:
|
||||
kwargs["resource"] = create_resource()
|
||||
|
||||
|
||||
@@ -271,8 +271,22 @@ class RawFoundryChatClient( # type: ignore[misc]
|
||||
Raises:
|
||||
ImportError: If azure-monitor-opentelemetry-exporter is not installed.
|
||||
"""
|
||||
from agent_framework.observability import (
|
||||
OBSERVABILITY_SETTINGS,
|
||||
create_metric_views,
|
||||
create_resource,
|
||||
enable_instrumentation,
|
||||
)
|
||||
from azure.core.exceptions import ResourceNotFoundError
|
||||
|
||||
if OBSERVABILITY_SETTINGS.is_user_disabled:
|
||||
logger.info(
|
||||
"FoundryChatClient.configure_azure_monitor(): Skipping setup because instrumentation was "
|
||||
"explicitly disabled via disable_instrumentation(). Call enable_instrumentation(force=True) "
|
||||
"to re-enable, then re-invoke configure_azure_monitor()."
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
conn_string = await self.project_client.telemetry.get_application_insights_connection_string()
|
||||
except ResourceNotFoundError:
|
||||
@@ -291,8 +305,6 @@ class RawFoundryChatClient( # type: ignore[misc]
|
||||
"Install it with: pip install azure-monitor-opentelemetry"
|
||||
) from exc
|
||||
|
||||
from agent_framework.observability import create_metric_views, create_resource, enable_instrumentation
|
||||
|
||||
if "resource" not in kwargs:
|
||||
kwargs["resource"] = create_resource()
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -602,7 +602,7 @@ dependencies = [
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "agent-framework-core", editable = "packages/core" },
|
||||
{ name = "github-copilot-sdk", marker = "python_full_version >= '3.11'", specifier = "<=1.0.0b2,>=1.0.0b2" },
|
||||
{ name = "github-copilot-sdk", marker = "python_full_version >= '3.11'", specifier = ">=1.0.0b2,<=1.0.0b2" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user