diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md index 8b245d381045..57bfc353932e 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md @@ -8,6 +8,8 @@ ([#34673](https://github.com/Azure/azure-sdk-for-python/pull/34673)) - Add live metrics collection of cpu time/process memory ([#34735](https://github.com/Azure/azure-sdk-for-python/pull/34735)) +- Add live metrics collection feature detection to statsbeat + ([#34752](https://github.com/Azure/azure-sdk-for-python/pull/34752)) ### Breaking Changes diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_live_metrics.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_live_metrics.py index feb6922f4428..705b6bb2c882 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_live_metrics.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_live_metrics.py @@ -43,6 +43,9 @@ _get_log_record_document, _get_span_document, ) +from azure.monitor.opentelemetry.exporter.statsbeat._state import ( + set_statsbeat_live_metrics_feature_set, +) from azure.monitor.opentelemetry.exporter._utils import ( _get_sdk_version, _populate_part_a_fields, @@ -60,6 +63,7 @@ def enable_live_metrics(**kwargs: Any) -> None: :rtype: None """ _QuickpulseManager(kwargs.get('connection_string'), kwargs.get('resource')) + set_statsbeat_live_metrics_feature_set() # pylint: disable=protected-access,too-many-instance-attributes diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_state.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_state.py index 113625e76714..3530f71364fd 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_state.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_state.py @@ -14,6 +14,7 @@ "INITIAL_SUCCESS": False, "SHUTDOWN": False, "CUSTOM_EVENTS_FEATURE_SET": False, + "LIVE_METRICS_FEATURE_SET": False, } _STATSBEAT_STATE_LOCK = threading.Lock() _STATSBEAT_FAILURE_COUNT_THRESHOLD = 3 @@ -57,3 +58,12 @@ def get_statsbeat_custom_events_feature_set(): def set_statsbeat_custom_events_feature_set(): with _STATSBEAT_STATE_LOCK: _STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = True + + +def get_statsbeat_live_metrics_feature_set(): + return _STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] + + +def set_statsbeat_live_metrics_feature_set(): + with _STATSBEAT_STATE_LOCK: + _STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = True diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_statsbeat_metrics.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_statsbeat_metrics.py index a3b4d9859526..a3116db5edf1 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_statsbeat_metrics.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_statsbeat_metrics.py @@ -32,6 +32,7 @@ from azure.monitor.opentelemetry.exporter.statsbeat._state import ( _REQUESTS_MAP_LOCK, _REQUESTS_MAP, + get_statsbeat_live_metrics_feature_set, get_statsbeat_custom_events_feature_set, ) from azure.monitor.opentelemetry.exporter import _utils @@ -64,6 +65,7 @@ class _StatsbeatFeature: AAD = 2 CUSTOM_EVENTS_EXTENSION = 4 DISTRO = 8 + LIVE_METRICS = 16 class _AttachTypes: @@ -120,6 +122,8 @@ def __init__( self._feature |= _StatsbeatFeature.DISTRO if get_statsbeat_custom_events_feature_set(): self._feature |= _StatsbeatFeature.CUSTOM_EVENTS_EXTENSION + if get_statsbeat_live_metrics_feature_set(): + self._feature |= _StatsbeatFeature.LIVE_METRICS self._ikey = instrumentation_key self._meter_provider = meter_provider self._meter = self._meter_provider.get_meter(__name__) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_statsbeat.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_statsbeat.py index b660b8701072..fdb3f428856b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_statsbeat.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_statsbeat.py @@ -317,6 +317,7 @@ def setUp(self): _STATSBEAT_STATE["INITIAL_SUCCESS"] = False _STATSBEAT_STATE["SHUTDOWN"] = False _STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = False + _STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = False def test_statsbeat_metric_init(self): @@ -748,11 +749,12 @@ def test_get_feature_metric_aad(self): self.assertEqual(_StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"], _StatsbeatFeature.AAD) # pylint: disable=protected-access - def test_get_feature_metric_custom_events_init(self): + @mock.patch("azure.monitor.opentelemetry.exporter.statsbeat._statsbeat_metrics.get_statsbeat_custom_events_feature_set") + def test_get_feature_metric_custom_events(self, feature_mock): + feature_mock.return_value = True mp = MeterProvider() ikey = "1aa11111-bbbb-1ccc-8ddd-eeeeffff3334" endpoint = "https://westus-1.in.applicationinsights.azure.com/" - _STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = True metric = _StatsbeatMetrics( mp, ikey, @@ -770,11 +772,15 @@ def test_get_feature_metric_custom_events_init(self): self.assertEqual(obs.value, 1) self.assertEqual(obs.attributes, attributes) + # pylint: disable=protected-access - def test_get_feature_metric_custom_events_runtime(self): + @mock.patch("azure.monitor.opentelemetry.exporter.statsbeat._statsbeat_metrics.get_statsbeat_live_metrics_feature_set") + def test_get_feature_metric_live_metrics(self, feature_mock): + feature_mock.return_value = True mp = MeterProvider() ikey = "1aa11111-bbbb-1ccc-8ddd-eeeeffff3334" endpoint = "https://westus-1.in.applicationinsights.azure.com/" + _STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = True metric = _StatsbeatMetrics( mp, ikey, @@ -785,16 +791,13 @@ def test_get_feature_metric_custom_events_runtime(self): ) attributes = dict(_StatsbeatMetrics._COMMON_ATTRIBUTES) attributes.update(_StatsbeatMetrics._FEATURE_ATTRIBUTES) - self.assertEqual(attributes["feature"], 0) + self.assertEqual(attributes["feature"], 16) self.assertEqual(attributes["type"], _FEATURE_TYPES.FEATURE) - _STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = True observations = metric._get_feature_metric(options=None) - attributes.update(_StatsbeatMetrics._FEATURE_ATTRIBUTES) - self.assertEqual(attributes["feature"], 4) - self.assertEqual(metric._feature, 4) for obs in observations: self.assertEqual(obs.value, 1) self.assertEqual(obs.attributes, attributes) + _STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = False # pylint: disable=protected-access def test_get_feature_metric_distro(self):