Skip to content

Commit 017983e

Browse files
authored
Flush metrics on destroy (#351)
* Flush metics after destroy() so metrics are not lost (particularly for short-lived use cases). * Add status code to failures in register/fetch. * Finish the job re: status codes and formatting. * Improve test doc slightly.
1 parent f750c8e commit 017983e

File tree

7 files changed

+35
-7
lines changed

7 files changed

+35
-7
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ install-docs: install
3434
#-----------------------------------------------------------------------
3535
fmt:
3636
black . && \
37-
ruff UnleashClient tests --fix
37+
ruff check UnleashClient tests --fix
3838

3939
lint:
4040
black . --check && \

UnleashClient/__init__.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ def __init__(
146146
self.cache.mset({METRIC_LAST_SENT_TIME: datetime.now(timezone.utc), ETAG: ""})
147147
self.unleash_bootstrapped = self.cache.bootstrapped
148148

149+
self.metrics_headers: dict = {}
150+
149151
# Scheduler bootstrapping
150152
# - Figure out the Unleash executor name.
151153
if scheduler and scheduler_executor:
@@ -233,7 +235,7 @@ def initialize_client(self, fetch_toggles: bool = True) -> None:
233235
"unleash-sdk": f"{SDK_NAME}:{SDK_VERSION}",
234236
}
235237

236-
metrics_headers = {
238+
self.metrics_headers = {
237239
**base_headers,
238240
"unleash-interval": self.unleash_metrics_interval_str_millis,
239241
}
@@ -244,7 +246,7 @@ def initialize_client(self, fetch_toggles: bool = True) -> None:
244246
"app_name": self.unleash_app_name,
245247
"connection_id": self.connection_id,
246248
"instance_id": self.unleash_instance_id,
247-
"headers": metrics_headers,
249+
"headers": self.metrics_headers,
248250
"custom_options": self.unleash_custom_options,
249251
"request_timeout": self.unleash_request_timeout,
250252
"engine": self.engine,
@@ -357,6 +359,19 @@ def destroy(self) -> None:
357359
self.fl_job.remove()
358360
if self.metric_job:
359361
self.metric_job.remove()
362+
363+
# Flush metrics before shutting down.
364+
aggregate_and_send_metrics(
365+
url=self.unleash_url,
366+
app_name=self.unleash_app_name,
367+
connection_id=self.connection_id,
368+
instance_id=self.unleash_instance_id,
369+
headers=self.metrics_headers,
370+
custom_options=self.unleash_custom_options,
371+
request_timeout=self.unleash_request_timeout,
372+
engine=self.engine,
373+
)
374+
360375
self.unleash_scheduler.shutdown()
361376
self.cache.destroy()
362377

UnleashClient/api/features.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def get_feature_toggles(
7272
if resp.status_code not in [200, 304]:
7373
log_resp_info(resp)
7474
LOGGER.warning(
75-
"Unleash Client feature fetch failed due to unexpected HTTP status code."
75+
"Unleash Client feature fetch failed due to unexpected HTTP status code: %s",
76+
resp.status_code,
7677
)
7778
raise Exception(
7879
"Unleash Client feature fetch failed!"

UnleashClient/api/metrics.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ def send_metrics(
4141

4242
if resp.status_code != 202:
4343
log_resp_info(resp)
44-
LOGGER.warning("Unleash Client metrics submission failed.")
44+
LOGGER.warning(
45+
"Unleash Client metrics submission due to unexpected HTTP status code: %s",
46+
resp.status_code,
47+
)
4548
return False
4649

4750
LOGGER.info("Unleash Client metrics successfully sent!")

UnleashClient/api/register.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ def register_client(
7474
if resp.status_code != 202:
7575
log_resp_info(resp)
7676
LOGGER.warning(
77-
"Unleash Client registration failed due to unexpected HTTP status code."
77+
"Unleash Client registration failed due to unexpected HTTP status code: %s",
78+
resp.status_code,
7879
)
7980
return False
8081

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mypy
1818
pylint
1919
pytest
2020
pytest-cov
21-
pytest-html==4.0.0rc4
21+
pytest-html
2222
pytest-mock
2323
pytest-xdist
2424
responses

tests/unit_tests/test_client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,14 @@ def test_uc_context_manager(unleash_client_nodestroy):
394394

395395
with unleash_client_nodestroy as unleash_client:
396396
assert unleash_client.is_initialized
397+
assert unleash_client.is_enabled("testFlag")
398+
399+
# Context Manager use case is usualy short-lived so even with a METRICS_INTERVAL of 2 seconds metrics can get lost. Verify that metrics are sent on destroy.
400+
metrics_request = [
401+
call for call in responses.calls if METRICS_URL in call.request.url
402+
][0].request
403+
metrics_body = json.loads(metrics_request.body)
404+
assert metrics_body["bucket"]["toggles"]["testFlag"]["yes"] == 1
397405

398406

399407
@responses.activate

0 commit comments

Comments
 (0)