Skip to content

Commit cc83239

Browse files
authored
Adding customer sdkstats to feature statsbeat (#43066)
1 parent 6edcf5b commit cc83239

File tree

6 files changed

+76
-1
lines changed

6 files changed

+76
-1
lines changed

sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
## 1.0.0b43 (Unreleased)
44

55
### Features Added
6-
76
- OneSettings control plane: Add live metrics feature control
87
([#43032](https://github.com/Azure/azure-sdk-for-python/pull/43032))
8+
- Adding customer sdkstats to feature statsbeat
9+
([#43066](https://github.com/Azure/azure-sdk-for-python/pull/43066))
910

1011
### Breaking Changes
1112

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_state.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"SHUTDOWN": False,
1818
"CUSTOM_EVENTS_FEATURE_SET": False,
1919
"LIVE_METRICS_FEATURE_SET": False,
20+
"CUSTOMER_SDKSTATS_FEATURE_SET": False,
2021
}
2122
_STATSBEAT_STATE_LOCK = threading.Lock()
2223
_STATSBEAT_FAILURE_COUNT_THRESHOLD = 3
@@ -74,3 +75,10 @@ def set_statsbeat_live_metrics_feature_set():
7475
def set_statsbeat_shutdown(shutdown: bool):
7576
with _STATSBEAT_STATE_LOCK:
7677
_STATSBEAT_STATE["SHUTDOWN"] = shutdown
78+
79+
def get_statsbeat_customer_sdkstats_feature_set(): # pylint: disable=name-too-long
80+
return _STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"]
81+
82+
def set_statsbeat_customer_sdkstats_feature_set(): # pylint: disable=name-too-long
83+
with _STATSBEAT_STATE_LOCK:
84+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = True

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/_statsbeat_metrics.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
_REQUESTS_MAP,
3636
get_statsbeat_live_metrics_feature_set,
3737
get_statsbeat_custom_events_feature_set,
38+
get_statsbeat_customer_sdkstats_feature_set,
3839
)
3940
from azure.monitor.opentelemetry.exporter import _utils
4041

@@ -76,6 +77,7 @@ class _StatsbeatFeature:
7677
CUSTOM_EVENTS_EXTENSION = 4
7778
DISTRO = 8
7879
LIVE_METRICS = 16
80+
CUSTOMER_SDKSTATS = 32
7981

8082

8183
class _AttachTypes:
@@ -138,6 +140,8 @@ def __init__(
138140
self._feature |= _StatsbeatFeature.CUSTOM_EVENTS_EXTENSION
139141
if get_statsbeat_live_metrics_feature_set():
140142
self._feature |= _StatsbeatFeature.LIVE_METRICS
143+
if get_statsbeat_customer_sdkstats_feature_set():
144+
self._feature |= _StatsbeatFeature.CUSTOMER_SDKSTATS
141145
self._ikey = instrumentation_key
142146
self._meter_provider = meter_provider
143147
self._meter = self._meter_provider.get_meter(__name__)
@@ -260,6 +264,9 @@ def _get_feature_metric(self, options: CallbackOptions) -> Iterable[Observation]
260264
if get_statsbeat_live_metrics_feature_set():
261265
self._feature |= _StatsbeatFeature.LIVE_METRICS
262266
_StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"] = self._feature
267+
if get_statsbeat_customer_sdkstats_feature_set():
268+
self._feature |= _StatsbeatFeature.CUSTOMER_SDKSTATS
269+
_StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"] = self._feature
263270

264271
# Don't send observation if no features enabled
265272
if self._feature is not _StatsbeatFeature.NONE:

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/statsbeat/customer/_customer_sdkstats.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from typing import TYPE_CHECKING
55

6+
from azure.monitor.opentelemetry.exporter.statsbeat._state import set_statsbeat_customer_sdkstats_feature_set
7+
68
from ._state import get_customer_stats_manager
79

810
if TYPE_CHECKING:
@@ -19,6 +21,7 @@ def collect_customer_sdkstats(exporter: "BaseExporter") -> None: # type: ignore
1921
if not customer_stats.is_initialized:
2022
# The initialize method is thread-safe and handles double-initialization
2123
customer_stats.initialize(connection_string=exporter._connection_string) # type: ignore
24+
set_statsbeat_customer_sdkstats_feature_set()
2225

2326
def shutdown_customer_sdkstats_metrics() -> None:
2427
# Shutdown customer SDKStats metrics collection.

sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_metrics.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ def setUp(self):
8585
_STATSBEAT_STATE["SHUTDOWN"] = False
8686
_STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = False
8787
_STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = False
88+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = False
8889

8990
_StatsbeatMetrics._COMMON_ATTRIBUTES = dict(_StatsbeatMetrics_COMMON_ATTRS)
9091
_StatsbeatMetrics._NETWORK_ATTRIBUTES = dict(_StatsbeatMetrics_NETWORK_ATTRS)
@@ -635,6 +636,60 @@ def test_get_feature_metric_live_metrics_runtime(self):
635636
self.assertTrue((_StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"] >> 4) & 1 == 1)
636637
_STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = False
637638

639+
# pylint: disable=protected-access
640+
@mock.patch(
641+
"azure.monitor.opentelemetry.exporter.statsbeat._statsbeat_metrics.get_statsbeat_customer_sdkstats_feature_set"
642+
)
643+
def test_get_feature_metric_customer_sdkstats(self, feature_mock):
644+
feature_mock.return_value = True
645+
mp = MeterProvider()
646+
ikey = "1aa11111-bbbb-1ccc-8ddd-eeeeffff3334"
647+
endpoint = "https://westus-1.in.applicationinsights.azure.com/"
648+
metric = _StatsbeatMetrics(
649+
mp,
650+
ikey,
651+
endpoint,
652+
True,
653+
0,
654+
False,
655+
)
656+
attributes = dict(_StatsbeatMetrics._COMMON_ATTRIBUTES)
657+
attributes.update(_StatsbeatMetrics._FEATURE_ATTRIBUTES)
658+
self.assertEqual(attributes["feature"], 32)
659+
self.assertEqual(attributes["type"], _FEATURE_TYPES.FEATURE)
660+
observations = metric._get_feature_metric(options=None)
661+
for obs in observations:
662+
self.assertEqual(obs.value, 1)
663+
self.assertEqual(obs.attributes, attributes)
664+
665+
# pylint: disable=protected-access
666+
def test_get_feature_metric_customer_sdkstats_runtime(self):
667+
mp = MeterProvider()
668+
ikey = "1aa11111-bbbb-1ccc-8ddd-eeeeffff3334"
669+
endpoint = "https://westus-1.in.applicationinsights.azure.com/"
670+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = False
671+
metric = _StatsbeatMetrics(
672+
mp,
673+
ikey,
674+
endpoint,
675+
True,
676+
0,
677+
False,
678+
)
679+
self.assertTrue((metric._feature >> 5) & 1 == 0)
680+
attributes = dict(_StatsbeatMetrics._COMMON_ATTRIBUTES)
681+
attributes.update(_StatsbeatMetrics._FEATURE_ATTRIBUTES)
682+
self.assertEqual(attributes["feature"], 0)
683+
self.assertEqual(attributes["type"], _FEATURE_TYPES.FEATURE)
684+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = True
685+
observations = metric._get_feature_metric(options=None)
686+
attributes["feature"] = _StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"]
687+
for obs in observations:
688+
self.assertEqual(obs.value, 1)
689+
self.assertEqual(obs.attributes, attributes)
690+
self.assertTrue((_StatsbeatMetrics._FEATURE_ATTRIBUTES["feature"] >> 5) & 1 == 1)
691+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = False
692+
638693
# pylint: disable=protected-access
639694
def test_get_feature_metric_distro(self):
640695
mp = MeterProvider()

sdk/monitor/azure-monitor-opentelemetry-exporter/tests/statsbeat/test_statsbeat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def setUp(self):
3939
_STATSBEAT_STATE["SHUTDOWN"] = False
4040
_STATSBEAT_STATE["CUSTOM_EVENTS_FEATURE_SET"] = False
4141
_STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = False
42+
_STATSBEAT_STATE["CUSTOMER_SDKSTATS_FEATURE_SET"] = False
4243

4344
def tearDown(self):
4445
"""Clean up after tests."""

0 commit comments

Comments
 (0)