Skip to content
Draft
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 @@ -3,8 +3,12 @@
## 1.0.0b53 (Unreleased)

### Features Added

- Read for global feature sdkstats bitmap and add a 15 second delay timer
([#47031](https://github.com/Azure/azure-sdk-for-python/pull/47031))
- Use `APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE` environment variable in `_is_attach_enabled` to
reliably detect successful auto-instrumentation attach, with fallback to legacy path-based detection
([#46955](https://github.com/Azure/azure-sdk-for-python/pull/46955))

### Breaking Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
_PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY = "PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY"
_AKS_ARM_NAMESPACE_ID = "AKS_ARM_NAMESPACE_ID"
_KUBERNETES_SERVICE_HOST = "KUBERNETES_SERVICE_HOST"
_APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE = "APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE"

# Network

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from azure.monitor.opentelemetry.exporter._connection_string_parser import ConnectionStringParser
from azure.monitor.opentelemetry.exporter._constants import (
_AKS_ARM_NAMESPACE_ID,
_APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE,
_AZURE_MONITOR_DISTRO_VERSION,
_DEFAULT_AAD_SCOPE,
_FUNCTIONS_WORKER_RUNTIME,
Expand Down Expand Up @@ -68,6 +69,14 @@ def _is_on_aks():


def _is_attach_enabled():
attach_type = environ.get(_APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE)
if attach_type is not None:
# If the env var is set, attach is only enabled if the value is
# "IntegratedAuto" AND the existing per-RP logic is satisfied.
if attach_type.lower() == "integratedauto":
return True
return False
# Fallback to legacy logic when the env var is not set
if _is_on_functions():
return environ.get(_PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY) == "true"
if _is_on_app_service():
Expand Down
194 changes: 194 additions & 0 deletions sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ def test_get_sdk_version_prefix_aks_windows_attach(self, mock_system):
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME},
clear=True,
)
def test_attach_enabled(self, mock_isdir):
self.assertEqual(_utils._is_attach_enabled(), True)
Expand All @@ -742,6 +743,7 @@ def test_attach_enabled(self, mock_isdir):
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME},
clear=True,
)
def test_attach_app_service_disabled(self, mock_isdir):
self.assertEqual(_utils._is_attach_enabled(), False)
Expand Down Expand Up @@ -778,6 +780,198 @@ def test_aks_no_attach(self):
# This is not an expected scenario and just tests the default
self.assertFalse(_utils._is_attach_enabled())

# Attach with APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE env var

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_app_service(self):
self.assertTrue(_utils._is_attach_enabled())

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=True,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_app_service(self, mock_isdir):
self.assertTrue(_utils._is_attach_enabled())
mock_isdir.assert_not_called()

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=True,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "integratedauto",
},
clear=True,
)
def test_attach_type_integrated_auto_app_service_lower(self, mock_isdir):
self.assertTrue(_utils._is_attach_enabled())
mock_isdir.assert_not_called()

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=True,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "INTEGRATEDAUTO",
},
clear=True,
)
def test_attach_type_integrated_auto_app_service_upper(self, mock_isdir):
self.assertTrue(_utils._is_attach_enabled())
mock_isdir.assert_not_called()

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=True,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "Manual",
},
clear=True,
)
def test_attach_type_manual_app_service(self, mock_isdir):
self.assertFalse(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"FUNCTIONS_WORKER_RUNTIME": "python",
"PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY": "true",
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_functions(self):
self.assertTrue(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"FUNCTIONS_WORKER_RUNTIME": "python",
"PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY": "true",
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "Manual",
},
clear=True,
)
def test_attach_type_manual_functions(self):
self.assertFalse(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"KUBERNETES_SERVICE_HOST": TEST_KUBERNETES_SERVICE_HOST,
"AKS_ARM_NAMESPACE_ID": TEST_AKS_ARM_NAMESPACE_ID,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_aks(self):
self.assertTrue(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"KUBERNETES_SERVICE_HOST": TEST_KUBERNETES_SERVICE_HOST,
"AKS_ARM_NAMESPACE_ID": TEST_AKS_ARM_NAMESPACE_ID,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "Manual",
},
clear=True,
)
def test_attach_type_manual_aks(self):
self.assertFalse(_utils._is_attach_enabled())

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=False,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
)
def test_attach_type_integrated_auto_app_service_no_isdir_check(self, mock_isdir):
# APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE overrides the legacy isdir gate.
self.assertTrue(_utils._is_attach_enabled())
mock_isdir.assert_not_called()

@patch(
"azure.monitor.opentelemetry.exporter._utils.isdir",
return_value=False,
)
@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "manual",
},
)
def test_attach_type_manual_app_service_no_isdir_check(self, mock_isdir):
# APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE overrides the legacy isdir gate.
self.assertFalse(_utils._is_attach_enabled())
mock_isdir.assert_not_called()

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"FUNCTIONS_WORKER_RUNTIME": "python",
"PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY": "false",
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_functions_enable_telemetry_false(self):
# APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE overrides the legacy PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY check.
self.assertTrue(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"FUNCTIONS_WORKER_RUNTIME": "python",
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_functions_no_enable_telemetry(self):
# IntegratedAuto but ENABLE_TELEMETRY not set. Should be true. Env var overwrites other factors.
self.assertTrue(_utils._is_attach_enabled())

@patch.dict(
"azure.monitor.opentelemetry.exporter._utils.environ",
{
"KUBERNETES_SERVICE_HOST": TEST_KUBERNETES_SERVICE_HOST,
"APPLICATIONINSIGHTS_PYTHON_ATTACHTYPE": "IntegratedAuto",
},
clear=True,
)
def test_attach_type_integrated_auto_aks_no_arm_namespace(self):
# IntegratedAuto but AKS_ARM_NAMESPACE_ID not set. Should be true. Env var overwrites other factors.
self.assertTrue(_utils._is_attach_enabled())

# Synthetic

def test_is_synthetic_source_bot(self):
Expand Down