Skip to content

Commit 6f7e078

Browse files
authored
Rename Customer Statsbeat to Customer SDKStats (#42573)
* Rename Customer Statsbeat to Customer SDKStats * Updated CHANGELOG * Fixed shutdown issue * Added tests * Updated CHANGELOG
1 parent 6ec414a commit 6f7e078

File tree

9 files changed

+803
-747
lines changed

9 files changed

+803
-747
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
([#42542](https://github.com/Azure/azure-sdk-for-python/pull/42542))
1212
- Customer Facing SDKStats: Added the export interval env var for customer sdkstats
1313
([#42551](https://github.com/Azure/azure-sdk-for-python/pull/42551))
14+
- Rename Customer Statsbeat to Customer SDKStats as per [Spec] - https://github.com/aep-health-and-standards/Telemetry-Collection-Spec/pull/581
15+
([#42573](https://github.com/Azure/azure-sdk-for-python/pull/42573))
1416

1517
### Breaking Changes
1618

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@
146146
_TRACE = "TRACE"
147147
_UNKNOWN = "UNKNOWN"
148148

149-
# Customer Facing Statsbeat
150-
_APPLICATIONINSIGHTS_STATSBEAT_ENABLED_PREVIEW = "APPLICATIONINSIGHTS_STATSBEAT_ENABLED_PREVIEW"
149+
# Customer Facing SDKStats
150+
_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW = "APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW"
151151
_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL = "APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL"
152-
_CUSTOMER_STATSBEAT_LANGUAGE = "python"
152+
_CUSTOMER_SDKSTATS_LANGUAGE = "python"
153153

154154
class DropCode(str, Enum, metaclass=CaseInsensitiveEnumMeta):
155155
CLIENT_READONLY = "CLIENT_READONLY"
@@ -167,12 +167,12 @@ class RetryCode(str, Enum, metaclass=CaseInsensitiveEnumMeta):
167167

168168
RetryCodeType = Union[RetryCode, int]
169169

170-
class CustomerStatsbeatMetricName(str, Enum, metaclass=CaseInsensitiveEnumMeta):
170+
class CustomerSdkStatsMetricName(str, Enum, metaclass=CaseInsensitiveEnumMeta):
171171
ITEM_SUCCESS_COUNT = "preview.item.success.count"
172172
ITEM_DROP_COUNT = "preview.item.dropped.count"
173173
ITEM_RETRY_COUNT = "preview.item.retry.count"
174174

175-
class CustomerStatsbeatProperties:
175+
class CustomerSdkStatsProperties:
176176
language: str
177177
version: str
178178
compute_type: str

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/_base.py

Lines changed: 58 additions & 58 deletions
Large diffs are not rendered by default.
Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT License.
3-
"""Customer Statsbeat implementation for Azure Monitor OpenTelemetry Exporter.
3+
"""Customer SDKStats implementation for Azure Monitor OpenTelemetry Exporter.
44
5-
This module provides the implementation for collecting and reporting customer statsbeat
5+
This module provides the implementation for collecting and reporting Customer SDKStats
66
metrics that track the usage and performance of the Azure Monitor OpenTelemetry Exporter.
77
"""
88

@@ -15,14 +15,14 @@
1515
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
1616

1717
from azure.monitor.opentelemetry.exporter._constants import (
18-
_APPLICATIONINSIGHTS_STATSBEAT_ENABLED_PREVIEW,
19-
CustomerStatsbeatProperties,
18+
_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW,
19+
CustomerSdkStatsProperties,
2020
DropCode,
2121
DropCodeType,
2222
RetryCode,
2323
RetryCodeType,
24-
CustomerStatsbeatMetricName,
25-
_CUSTOMER_STATSBEAT_LANGUAGE,
24+
CustomerSdkStatsMetricName,
25+
_CUSTOMER_SDKSTATS_LANGUAGE,
2626
)
2727

2828
from azure.monitor.opentelemetry.exporter.export.metrics._exporter import AzureMonitorMetricExporter
@@ -38,23 +38,21 @@
3838
from azure.monitor.opentelemetry.exporter import VERSION
3939

4040
from azure.monitor.opentelemetry.exporter.statsbeat._state import (
41-
_CUSTOMER_STATSBEAT_STATE,
42-
_CUSTOMER_STATSBEAT_STATE_LOCK,
41+
_CUSTOMER_SDKSTATS_STATE,
42+
_CUSTOMER_SDKSTATS_STATE_LOCK,
4343
)
4444

45-
_CUSTOMER_STATSBEAT_MAP_LOCK = threading.Lock()
46-
47-
class _CustomerStatsbeatTelemetryCounters:
45+
class _CustomerSdkStatsTelemetryCounters:
4846
def __init__(self):
4947
self.total_item_success_count: Dict[str, Any] = {}
5048
self.total_item_drop_count: Dict[str, Dict[DropCodeType, Dict[str, int]]] = {}
5149
self.total_item_retry_count: Dict[str, Dict[RetryCodeType, Dict[str, int]]] = {}
5250

53-
class CustomerStatsbeatMetrics(metaclass=Singleton): # pylint: disable=too-many-instance-attributes
51+
class CustomerSdkStatsMetrics(metaclass=Singleton): # pylint: disable=too-many-instance-attributes
5452
def __init__(self, connection_string):
55-
self._counters = _CustomerStatsbeatTelemetryCounters()
56-
self._language = _CUSTOMER_STATSBEAT_LANGUAGE
57-
self._is_enabled = os.environ.get(_APPLICATIONINSIGHTS_STATSBEAT_ENABLED_PREVIEW, "").lower() in ("true")
53+
self._counters = _CustomerSdkStatsTelemetryCounters()
54+
self._language = _CUSTOMER_SDKSTATS_LANGUAGE
55+
self._is_enabled = os.environ.get(_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW, "").lower() in ("true")
5856
if not self._is_enabled:
5957
return
6058

@@ -63,36 +61,36 @@ def __init__(self, connection_string):
6361
"instrumentation_collection": True, # Prevent circular dependency
6462
}
6563

66-
self._customer_statsbeat_exporter = AzureMonitorMetricExporter(**exporter_config)
67-
self._customer_statsbeat_exporter._is_customer_statsbeat = True
64+
self._customer_sdkstats_exporter = AzureMonitorMetricExporter(**exporter_config)
65+
self._customer_sdkstats_exporter._is_customer_sdkstats = True
6866
metric_reader_options = {
69-
"exporter": self._customer_statsbeat_exporter,
67+
"exporter": self._customer_sdkstats_exporter,
7068
"export_interval_millis": _get_customer_sdkstats_export_interval()
7169
}
72-
self._customer_statsbeat_metric_reader = PeriodicExportingMetricReader(**metric_reader_options)
73-
self._customer_statsbeat_meter_provider = MeterProvider(
74-
metric_readers=[self._customer_statsbeat_metric_reader]
70+
self._customer_sdkstats_metric_reader = PeriodicExportingMetricReader(**metric_reader_options)
71+
self._customer_sdkstats_meter_provider = MeterProvider(
72+
metric_readers=[self._customer_sdkstats_metric_reader]
7573
)
76-
self._customer_statsbeat_meter = self._customer_statsbeat_meter_provider.get_meter(__name__)
74+
self._customer_sdkstats_meter = self._customer_sdkstats_meter_provider.get_meter(__name__)
7775

78-
self._customer_properties = CustomerStatsbeatProperties(
76+
self._customer_properties = CustomerSdkStatsProperties(
7977
language=self._language,
8078
version=VERSION,
8179
compute_type=get_compute_type(),
8280
)
8381

84-
self._success_gauge = self._customer_statsbeat_meter.create_observable_gauge(
85-
name=CustomerStatsbeatMetricName.ITEM_SUCCESS_COUNT.value,
82+
self._success_gauge = self._customer_sdkstats_meter.create_observable_gauge(
83+
name=CustomerSdkStatsMetricName.ITEM_SUCCESS_COUNT.value,
8684
description="Tracks successful telemetry items sent to Azure Monitor",
8785
callbacks=[self._item_success_callback]
8886
)
89-
self._dropped_gauge = self._customer_statsbeat_meter.create_observable_gauge(
90-
name=CustomerStatsbeatMetricName.ITEM_DROP_COUNT.value,
87+
self._dropped_gauge = self._customer_sdkstats_meter.create_observable_gauge(
88+
name=CustomerSdkStatsMetricName.ITEM_DROP_COUNT.value,
9189
description="Tracks dropped telemetry items sent to Azure Monitor",
9290
callbacks=[self._item_drop_callback]
9391
)
94-
self._retry_gauge = self._customer_statsbeat_meter.create_observable_gauge(
95-
name=CustomerStatsbeatMetricName.ITEM_RETRY_COUNT.value,
92+
self._retry_gauge = self._customer_sdkstats_meter.create_observable_gauge(
93+
name=CustomerSdkStatsMetricName.ITEM_RETRY_COUNT.value,
9694
description="Tracks retry attempts for telemetry items sent to Azure Monitor",
9795
callbacks=[self._item_retry_callback]
9896
)
@@ -236,44 +234,44 @@ def _get_retry_reason(self, retry_code: RetryCodeType, exception_message: Option
236234
}
237235
return retry_code_reasons.get(retry_code, "unknown_reason")
238236

239-
# Global customer statsbeat singleton
240-
_CUSTOMER_STATSBEAT_METRICS = None
241-
_CUSTOMER_STATSBEAT_LOCK = threading.Lock()
237+
# Global customer sdkstats singleton
238+
_CUSTOMER_SDKSTATS_METRICS = None
239+
_CUSTOMER_SDKSTATS_LOCK = threading.Lock()
242240

243241

244242
# pylint: disable=global-statement
245243
# pylint: disable=protected-access
246-
def collect_customer_statsbeat(exporter):
247-
global _CUSTOMER_STATSBEAT_METRICS
248-
# Only start customer statsbeat if did not exist before
249-
if _CUSTOMER_STATSBEAT_METRICS is None:
250-
with _CUSTOMER_STATSBEAT_LOCK:
244+
def collect_customer_sdkstats(exporter):
245+
global _CUSTOMER_SDKSTATS_METRICS
246+
# Only start customer sdkstats if did not exist before
247+
if _CUSTOMER_SDKSTATS_METRICS is None:
248+
with _CUSTOMER_SDKSTATS_LOCK:
251249
# Double-check inside the lock to avoid race conditions
252-
if _CUSTOMER_STATSBEAT_METRICS is None:
250+
if _CUSTOMER_SDKSTATS_METRICS is None:
253251

254252
connection_string = (
255253
f"InstrumentationKey={exporter._instrumentation_key};"
256254
f"IngestionEndpoint={exporter._endpoint}"
257255
)
258-
_CUSTOMER_STATSBEAT_METRICS = CustomerStatsbeatMetrics(connection_string)
256+
_CUSTOMER_SDKSTATS_METRICS = CustomerSdkStatsMetrics(connection_string)
259257

260-
exporter._customer_statsbeat_metrics = _CUSTOMER_STATSBEAT_METRICS
258+
exporter._customer_sdkstats_metrics = _CUSTOMER_SDKSTATS_METRICS
261259
if hasattr(exporter, 'storage') and exporter.storage:
262-
exporter.storage._customer_statsbeat_metrics = _CUSTOMER_STATSBEAT_METRICS
260+
exporter.storage._customer_sdkstats_metrics = _CUSTOMER_SDKSTATS_METRICS
263261

264262

265-
def shutdown_customer_statsbeat_metrics() -> None:
266-
global _CUSTOMER_STATSBEAT_METRICS
263+
def shutdown_customer_sdkstats_metrics() -> None:
264+
global _CUSTOMER_SDKSTATS_METRICS
267265
shutdown_success = False
268-
if _CUSTOMER_STATSBEAT_METRICS is not None:
269-
with _CUSTOMER_STATSBEAT_LOCK:
266+
if _CUSTOMER_SDKSTATS_METRICS is not None:
267+
with _CUSTOMER_SDKSTATS_LOCK:
270268
try:
271-
if _CUSTOMER_STATSBEAT_METRICS._meter_provider is not None:
272-
_CUSTOMER_STATSBEAT_METRICS._meter_provider.shutdown()
273-
_CUSTOMER_STATSBEAT_METRICS = None
269+
if _CUSTOMER_SDKSTATS_METRICS._customer_sdkstats_meter_provider is not None:
270+
_CUSTOMER_SDKSTATS_METRICS._customer_sdkstats_meter_provider.shutdown()
271+
_CUSTOMER_SDKSTATS_METRICS = None
274272
shutdown_success = True
275273
except: # pylint: disable=bare-except
276274
pass
277275
if shutdown_success:
278-
with _CUSTOMER_STATSBEAT_STATE_LOCK:
279-
_CUSTOMER_STATSBEAT_STATE["SHUTDOWN"] = True
276+
with _CUSTOMER_SDKSTATS_STATE_LOCK:
277+
_CUSTOMER_SDKSTATS_STATE["SHUTDOWN"] = True

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
_STATSBEAT_STATE_LOCK = threading.Lock()
2020
_STATSBEAT_FAILURE_COUNT_THRESHOLD = 3
2121

22-
_CUSTOMER_STATSBEAT_STATE = {
22+
_CUSTOMER_SDKSTATS_STATE = {
2323
"SHUTDOWN": False,
2424
}
25-
_CUSTOMER_STATSBEAT_STATE_LOCK = threading.Lock()
25+
_CUSTOMER_SDKSTATS_STATE_LOCK = threading.Lock()
2626

2727
_LOCAL_STORAGE_SETUP_STATE = {
2828
"READONLY": False,
@@ -80,8 +80,8 @@ def set_statsbeat_live_metrics_feature_set():
8080
with _STATSBEAT_STATE_LOCK:
8181
_STATSBEAT_STATE["LIVE_METRICS_FEATURE_SET"] = True
8282

83-
def get_customer_statsbeat_shutdown():
84-
return _CUSTOMER_STATSBEAT_STATE["SHUTDOWN"]
83+
def get_customer_sdkstats_shutdown():
84+
return _CUSTOMER_SDKSTATS_STATE["SHUTDOWN"]
8585

8686
def get_local_storage_setup_state_readonly():
8787
return _LOCAL_STORAGE_SETUP_STATE["READONLY"]

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

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,85 +121,85 @@ def _determine_client_retry_code(error) -> Tuple[RetryCodeType, Optional[str]]:
121121
return (RetryCode.CLIENT_TIMEOUT, error_message)
122122
return (RetryCode.CLIENT_EXCEPTION, error_message)
123123

124-
def _track_successful_items(customer_statsbeat_metrics, envelopes: List[TelemetryItem]):
125-
if customer_statsbeat_metrics:
124+
def _track_successful_items(customer_sdkstats_metrics, envelopes: List[TelemetryItem]):
125+
if customer_sdkstats_metrics:
126126
for envelope in envelopes:
127127
telemetry_type = _get_telemetry_type(envelope)
128-
customer_statsbeat_metrics.count_successful_items(
128+
customer_sdkstats_metrics.count_successful_items(
129129
1,
130130
telemetry_type
131131
)
132132

133133
def _track_dropped_items(
134-
customer_statsbeat_metrics,
134+
customer_sdkstats_metrics,
135135
envelopes: List[TelemetryItem],
136136
drop_code: DropCodeType,
137137
error_message: Optional[str] = None
138138
):
139-
if customer_statsbeat_metrics:
139+
if customer_sdkstats_metrics:
140140
if error_message is None:
141141
for envelope in envelopes:
142142
telemetry_type = _get_telemetry_type(envelope)
143-
customer_statsbeat_metrics.count_dropped_items(
143+
customer_sdkstats_metrics.count_dropped_items(
144144
1,
145145
telemetry_type,
146146
drop_code
147147
)
148148
else:
149149
for envelope in envelopes:
150150
telemetry_type = _get_telemetry_type(envelope)
151-
customer_statsbeat_metrics.count_dropped_items(
151+
customer_sdkstats_metrics.count_dropped_items(
152152
1,
153153
telemetry_type,
154154
drop_code,
155155
error_message
156156
)
157157

158-
def _track_retry_items(customer_statsbeat_metrics, envelopes: List[TelemetryItem], error) -> None:
159-
if customer_statsbeat_metrics:
158+
def _track_retry_items(customer_sdkstats_metrics, envelopes: List[TelemetryItem], error) -> None:
159+
if customer_sdkstats_metrics:
160160
retry_code, message = _determine_client_retry_code(error)
161161
for envelope in envelopes:
162162
telemetry_type = _get_telemetry_type(envelope)
163163
if isinstance(retry_code, int):
164164
# For status codes, include the message if available
165165
if message:
166-
customer_statsbeat_metrics.count_retry_items(
166+
customer_sdkstats_metrics.count_retry_items(
167167
1,
168168
telemetry_type,
169169
retry_code,
170170
str(message)
171171
)
172172
else:
173-
customer_statsbeat_metrics.count_retry_items(
173+
customer_sdkstats_metrics.count_retry_items(
174174
1,
175175
telemetry_type,
176176
retry_code
177177
)
178178
else:
179-
customer_statsbeat_metrics.count_retry_items(
179+
customer_sdkstats_metrics.count_retry_items(
180180
1,
181181
telemetry_type,
182182
retry_code,
183183
str(message)
184184
)
185185

186-
def _track_dropped_items_from_storage(customer_statsbeat_metrics, result_from_storage_put, envelopes):
187-
if customer_statsbeat_metrics:
186+
def _track_dropped_items_from_storage(customer_sdkstats_metrics, result_from_storage_put, envelopes):
187+
if customer_sdkstats_metrics:
188188
if result_from_storage_put == StorageExportResult.CLIENT_STORAGE_DISABLED:
189189
# Track items that would have been retried but are dropped since client has local storage disabled
190-
_track_dropped_items(customer_statsbeat_metrics, envelopes, DropCode.CLIENT_STORAGE_DISABLED)
190+
_track_dropped_items(customer_sdkstats_metrics, envelopes, DropCode.CLIENT_STORAGE_DISABLED)
191191
elif result_from_storage_put == StorageExportResult.CLIENT_READONLY:
192-
# If filesystem is readonly, track dropped items in customer statsbeat
193-
_track_dropped_items(customer_statsbeat_metrics, envelopes, DropCode.CLIENT_READONLY)
192+
# If filesystem is readonly, track dropped items in customer sdkstats
193+
_track_dropped_items(customer_sdkstats_metrics, envelopes, DropCode.CLIENT_READONLY)
194194
elif result_from_storage_put == StorageExportResult.CLIENT_PERSISTENCE_CAPACITY_REACHED:
195195
# If data has to be dropped due to persistent storage being full, track dropped items
196-
_track_dropped_items(customer_statsbeat_metrics, envelopes, DropCode.CLIENT_PERSISTENCE_CAPACITY)
196+
_track_dropped_items(customer_sdkstats_metrics, envelopes, DropCode.CLIENT_PERSISTENCE_CAPACITY)
197197
elif get_local_storage_setup_state_exception() != "":
198198
# For exceptions caught in _check_and_set_folder_permissions during storage setup
199-
_track_dropped_items(customer_statsbeat_metrics, envelopes, DropCode.CLIENT_EXCEPTION, result_from_storage_put) # pylint: disable=line-too-long
199+
_track_dropped_items(customer_sdkstats_metrics, envelopes, DropCode.CLIENT_EXCEPTION, result_from_storage_put) # pylint: disable=line-too-long
200200
elif isinstance(result_from_storage_put, str):
201201
# For any exceptions occurred in put method of either LocalFileStorage or LocalFileBlob, track dropped item with reason # pylint: disable=line-too-long
202-
_track_dropped_items(customer_statsbeat_metrics, envelopes, DropCode.CLIENT_EXCEPTION, result_from_storage_put) # pylint: disable=line-too-long
202+
_track_dropped_items(customer_sdkstats_metrics, envelopes, DropCode.CLIENT_EXCEPTION, result_from_storage_put) # pylint: disable=line-too-long
203203
else:
204204
# LocalFileBlob.put returns StorageExportResult.LOCAL_FILE_BLOB_SUCCESS here. Don't need to track anything in this case. # pylint: disable=line-too-long
205205
pass

0 commit comments

Comments
 (0)