Skip to content
This repository was archived by the owner on Dec 31, 2023. It is now read-only.

Commit d162881

Browse files
author
Takashi Matsuo
authored
[monitoring] fix: use backoff for writing the value [(#3697)](GoogleCloudPlatform/python-docs-samples#3697)
* [monitoring] fix: use backoff for writing the value fixes #3694 * use uuid
1 parent eb03f5d commit d162881

File tree

1 file changed

+49
-41
lines changed

1 file changed

+49
-41
lines changed

samples/snippets/v3/api-client/custom_metric_test.py

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import os
2424
import random
2525
import time
26+
import uuid
2627

2728
import backoff
2829
import googleapiclient.discovery
@@ -37,69 +38,76 @@
3738

3839

3940
PROJECT = os.environ['GCLOUD_PROJECT']
41+
PROJECT_RESOURCE = "projects/{}".format(PROJECT)
4042

4143
""" Custom metric domain for all custom metrics"""
4244
CUSTOM_METRIC_DOMAIN = "custom.googleapis.com"
4345

4446
METRIC = 'compute.googleapis.com/instance/cpu/usage_time'
45-
METRIC_NAME = ''.join(
46-
random.choice('0123456789ABCDEF') for i in range(16))
47+
METRIC_NAME = uuid.uuid4().hex
4748
METRIC_RESOURCE = "{}/{}".format(
4849
CUSTOM_METRIC_DOMAIN, METRIC_NAME)
50+
METRIC_KIND = "GAUGE"
4951

5052

5153
@pytest.fixture(scope='module')
5254
def client():
5355
return googleapiclient.discovery.build('monitoring', 'v3')
5456

5557

56-
def test_custom_metric(client):
57-
PROJECT_RESOURCE = "projects/{}".format(PROJECT)
58+
@pytest.fixture(scope='module')
59+
def custom_metric(client):
60+
custom_metric_descriptor = create_custom_metric(
61+
client, PROJECT_RESOURCE, METRIC_RESOURCE, METRIC_KIND)
62+
63+
# wait until metric has been created, use the get call to wait until
64+
# a response comes back with the new metric with 10 retries.
65+
custom_metric = None
66+
retry_count = 0
67+
while not custom_metric and retry_count < 10:
68+
time.sleep(1)
69+
retry_count += 1
70+
custom_metric = get_custom_metric(
71+
client, PROJECT_RESOURCE, METRIC_RESOURCE)
72+
73+
# make sure we get the custom_metric
74+
assert custom_metric
75+
76+
yield custom_metric
77+
78+
# cleanup
79+
delete_metric_descriptor(client, custom_metric_descriptor['name'])
80+
81+
82+
def test_custom_metric(client, custom_metric):
5883
# Use a constant seed so psuedo random number is known ahead of time
5984
random.seed(1)
6085
pseudo_random_value = random.randint(0, 10)
6186
# Reseed it
6287
random.seed(1)
6388

6489
INSTANCE_ID = "test_instance"
65-
METRIC_KIND = "GAUGE"
66-
67-
try:
68-
custom_metric_descriptor = create_custom_metric(
69-
client, PROJECT_RESOURCE, METRIC_RESOURCE, METRIC_KIND)
70-
71-
# wait until metric has been created, use the get call to wait until
72-
# a response comes back with the new metric with 10 retries.
73-
custom_metric = None
74-
retry_count = 0
75-
while not custom_metric and retry_count < 10:
76-
time.sleep(1)
77-
retry_count += 1
78-
custom_metric = get_custom_metric(
79-
client, PROJECT_RESOURCE, METRIC_RESOURCE)
80-
# Make sure we get the custom metric
81-
assert custom_metric
8290

91+
# It's rare, but write can fail with HttpError 500, so we retry.
92+
@backoff.on_exception(backoff.expo, HttpError, max_time=120)
93+
def write_value():
8394
write_timeseries_value(client, PROJECT_RESOURCE,
8495
METRIC_RESOURCE, INSTANCE_ID,
8596
METRIC_KIND)
86-
87-
# Sometimes on new metric descriptors, writes have a delay in being
88-
# read back. Use eventually_consistent to account for this.
89-
@backoff.on_exception(
90-
backoff.expo, (AssertionError, HttpError), max_time=120)
91-
def eventually_consistent_test():
92-
response = read_timeseries(
93-
client, PROJECT_RESOURCE, METRIC_RESOURCE)
94-
# Make sure the value is not empty.
95-
assert 'timeSeries' in response
96-
value = int(
97-
response['timeSeries'][0]['points'][0]['value']['int64Value'])
98-
# using seed of 1 will create a value of 1
99-
assert value == pseudo_random_value
100-
101-
eventually_consistent_test()
102-
103-
finally:
104-
# cleanup
105-
delete_metric_descriptor(client, custom_metric_descriptor['name'])
97+
write_value()
98+
99+
# Sometimes on new metric descriptors, writes have a delay in being
100+
# read back. Use backoff to account for this.
101+
@backoff.on_exception(
102+
backoff.expo, (AssertionError, HttpError), max_time=120)
103+
def eventually_consistent_test():
104+
response = read_timeseries(
105+
client, PROJECT_RESOURCE, METRIC_RESOURCE)
106+
# Make sure the value is not empty.
107+
assert 'timeSeries' in response
108+
value = int(
109+
response['timeSeries'][0]['points'][0]['value']['int64Value'])
110+
# using seed of 1 will create a value of 1
111+
assert value == pseudo_random_value
112+
113+
eventually_consistent_test()

0 commit comments

Comments
 (0)