-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor v2 samples in to separate directory Add v3 Samples Renamed auth to list_env
- Loading branch information
Bill Prin
committed
Mar 16, 2016
1 parent
1034b81
commit 2c52c6e
Showing
14 changed files
with
525 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Cloud Monitoring v3 Sample | ||
|
||
Sample command-line programs for retrieving Google Monitoring API V3 data. | ||
|
||
`list_resources.py` is a simple command-line program to demonstrate connecting to the Google | ||
Monitoring API to retrieve API data and print out some of the resources. | ||
|
||
`custom_metric.py` demonstrates how to create a custom metric and write a TimeSeries | ||
value to it. | ||
|
||
## Prerequisites to run locally: | ||
|
||
* [pip](https://pypi.python.org/pypi/pip) | ||
|
||
Go to the [Google Cloud Console](https://console.cloud.google.com). | ||
|
||
* Go to API Manager -> Credentials | ||
* Click 'New Credentials', and create a Service Account or [click here](https://console.cloud.google | ||
.com/project/_/apiui/credential/serviceaccount) | ||
Download the JSON for this service account, and set the `GOOGLE_APPLICATION_CREDENTIALS` | ||
environment variable to point to the file containing the JSON credentials. | ||
|
||
|
||
export GOOGLE_APPLICATION_CREDENTIALS=~/Downloads/<project-id>-0123456789abcdef.json | ||
|
||
|
||
# Set Up Your Local Dev Environment | ||
To install, run the following commands. If you want to use [virtualenv](https://virtualenv.readthedocs.org/en/latest/) | ||
(recommended), run the commands within a virtualenv. | ||
|
||
* pip install -r requirements.txt | ||
|
||
To run locally: | ||
|
||
python list_resources.py --project_id=<YOUR-PROJECT-ID> | ||
python custom_metric.py --project_id=<YOUR-PROJECT-ID | ||
|
||
|
||
## Contributing changes | ||
|
||
* See [CONTRIBUTING.md](CONTRIBUTING.md) | ||
|
||
## Licensing | ||
|
||
* See [LICENSE](LICENSE) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
#!/usr/bin/env python | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" Sample command-line program for writing and reading Google Monitoring API | ||
V3 custom metrics. | ||
Simple command-line program to demonstrate connecting to the Google | ||
Monitoring API to write custom metrics and read them back. | ||
See README.md for instructions on setting up your development environment. | ||
This example creates a custom metric based on a hypothetical GAUGE measurement. | ||
To run locally: | ||
python custom_metric.py --project_id=<YOUR-PROJECT-ID> | ||
""" | ||
|
||
# [START all] | ||
import argparse | ||
import datetime | ||
import pprint | ||
import random | ||
import time | ||
|
||
import list_resources | ||
|
||
|
||
def format_rfc3339(datetime_instance=None): | ||
"""Formats a datetime per RFC 3339. | ||
:param datetime_instance: Datetime instanec to format, defaults to utcnow | ||
""" | ||
return datetime_instance.isoformat("T") + "Z" | ||
|
||
|
||
def get_start_time(): | ||
# Return now- 5 minutes | ||
start_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=5) | ||
return format_rfc3339(start_time) | ||
|
||
|
||
def get_now_rfc3339(): | ||
# Return now | ||
return format_rfc3339(datetime.datetime.utcnow()) | ||
|
||
|
||
def create_custom_metric(client, project_id, | ||
custom_metric_name, metric_kind): | ||
"""Create custom metric descriptor""" | ||
metrics_descriptor = { | ||
"name": "projects/{}/metricDescriptors/{}".format( | ||
project_id, custom_metric_name), | ||
"type": custom_metric_name, | ||
"labels": [ | ||
{ | ||
"key": "environment", | ||
"valueType": "STRING", | ||
"description": "An abritrary measurement" | ||
} | ||
], | ||
"metricKind": metric_kind, | ||
"valueType": "INT64", | ||
"unit": "items", | ||
"description": "An arbitrary measurement.", | ||
"displayName": "Custom Metric" | ||
} | ||
|
||
client.projects().metricDescriptors().create( | ||
name=project_id, body=metrics_descriptor).execute() | ||
|
||
|
||
def get_custom_metric(client, project_id, custom_metric_name): | ||
"""Retrieve the custom metric we created""" | ||
request = client.projects().metricDescriptors().list( | ||
name=project_id, | ||
filter='metric.type=starts_with("{}")'.format(custom_metric_name)) | ||
response = request.execute() | ||
print('ListCustomMetrics response:') | ||
pprint.pprint(response) | ||
try: | ||
return response['metricDescriptors'] | ||
except KeyError: | ||
return None | ||
|
||
|
||
def get_custom_data_point(): | ||
"""Dummy method to return a mock measurement for demonstration purposes. | ||
Returns a random number between 0 and 10""" | ||
length = random.randint(0, 10) | ||
print("reporting timeseries value {}".format(str(length))) | ||
return length | ||
|
||
|
||
def write_timeseries_value(client, project_resource, | ||
custom_metric_name, instance_id, metric_kind): | ||
"""Write the custom metric obtained by get_custom_data_point at a point in | ||
time.""" | ||
# Specify a new data point for the time series. | ||
now = get_now_rfc3339() | ||
timeseries_data = { | ||
"metric": { | ||
"type": custom_metric_name, | ||
"labels": { | ||
"environment": "STAGING" | ||
} | ||
}, | ||
"resource": { | ||
"type": 'gce_instance', | ||
"labels": { | ||
'instance_id': instance_id, | ||
'zone': 'us-central1-f' | ||
} | ||
}, | ||
"metricKind": metric_kind, | ||
"valueType": "INT64", | ||
"points": [ | ||
{ | ||
"interval": { | ||
"startTime": now, | ||
"endTime": now | ||
}, | ||
"value": { | ||
"int64Value": get_custom_data_point() | ||
} | ||
} | ||
] | ||
} | ||
|
||
request = client.projects().timeSeries().create( | ||
name=project_resource, body={"timeSeries": [timeseries_data]}) | ||
request.execute() | ||
|
||
|
||
def read_timeseries(client, project_resource, custom_metric_name): | ||
"""Reads all of the CUSTOM_METRICS that we have written between START_TIME | ||
and END_TIME | ||
:param project_resource: Resource of the project to read the timeseries | ||
from. | ||
:param custom_metric_name: The name of the timeseries we want to read. | ||
""" | ||
request = client.projects().timeSeries().list( | ||
name=project_resource, | ||
filter='metric.type="{0}"'.format(custom_metric_name), | ||
pageSize=3, | ||
interval_startTime=get_start_time(), | ||
interval_endTime=get_now_rfc3339()) | ||
response = request.execute() | ||
return response | ||
|
||
|
||
def main(project_id): | ||
# This is the namespace for all custom metrics | ||
CUSTOM_METRIC_DOMAIN = "custom.googleapis.com" | ||
# This is our specific metric name | ||
CUSTOM_METRIC_NAME = "{}/custom_measurement".format(CUSTOM_METRIC_DOMAIN) | ||
INSTANCE_ID = "test_instance" | ||
METRIC_KIND = "GAUGE" | ||
|
||
project_resource = "projects/{0}".format(project_id) | ||
client = list_resources.get_client() | ||
create_custom_metric(client, project_resource, | ||
CUSTOM_METRIC_NAME, METRIC_KIND) | ||
custom_metric = None | ||
while not custom_metric: | ||
# wait until it's created | ||
time.sleep(1) | ||
custom_metric = get_custom_metric( | ||
client, project_resource, CUSTOM_METRIC_NAME) | ||
|
||
write_timeseries_value(client, project_resource, | ||
CUSTOM_METRIC_NAME, INSTANCE_ID, METRIC_KIND) | ||
# Sometimes on new metric descriptors, writes have a delay in being read | ||
# back. 3 seconds should be enough to make sure our read call picks up the | ||
# write | ||
time.sleep(3) | ||
timeseries = read_timeseries(client, project_resource, CUSTOM_METRIC_NAME) | ||
print('read_timeseries response:\n{}'.format(pprint.pformat(timeseries))) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser( | ||
description=__doc__, | ||
formatter_class=argparse.RawDescriptionHelpFormatter | ||
) | ||
parser.add_argument( | ||
'--project_id', help='Project ID you want to access.', required=True) | ||
|
||
args = parser.parse_args() | ||
main(args.project_id) | ||
|
||
# [END all] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#!/usr/bin/env python | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
""" Integration test for custom_metric.py | ||
GOOGLE_APPLICATION_CREDENTIALS must be set to a Service Account for a project | ||
that has enabled the Monitoring API. | ||
Currently the TEST_PROJECT_ID is hard-coded to run using the project created | ||
for this test, but it could be changed to a different project. | ||
""" | ||
|
||
import random | ||
import time | ||
|
||
from custom_metric import create_custom_metric, get_custom_metric | ||
from custom_metric import read_timeseries, write_timeseries_value | ||
import list_resources | ||
|
||
""" Change this to run against other prjoects | ||
GOOGLE_APPLICATION_CREDENTIALS must be the service account for this project | ||
""" | ||
|
||
# temporarily hard code to whitelisted project | ||
TEST_PROJECT_ID = 'cloud-monitoring-dev' | ||
# TEST_PROJECT_ID = os.getenv("GCLOUD_PROJECT", 'cloud-monitoring-dev') | ||
|
||
""" Custom metric domain for all cusotm metrics""" | ||
CUSTOM_METRIC_DOMAIN = "custom.googleapis.com" | ||
|
||
project_resource = "projects/{}".format(TEST_PROJECT_ID) | ||
client = list_resources.get_client() | ||
metric = 'compute.googleapis.com/instance/cpu/usage_time' | ||
metric_name = ''.join( | ||
random.choice('0123456789ABCDEF') for i in range(16)) | ||
metric_resource = "{}/{}".format( | ||
CUSTOM_METRIC_DOMAIN, metric_name) | ||
|
||
|
||
def test_custom_metric(): | ||
# Use a constant seed so psuedo random number is known ahead of time | ||
random.seed(1) | ||
pseudo_random_value = random.randint(0, 10) | ||
# Reseed it | ||
random.seed(1) | ||
|
||
INSTANCE_ID = "test_instance" | ||
METRIC_KIND = "GAUGE" | ||
|
||
create_custom_metric( | ||
client, project_resource, metric_resource, METRIC_KIND) | ||
custom_metric = None | ||
# wait until metric has been created, use the get call to wait until | ||
# a response comes back with the new metric | ||
while not custom_metric: | ||
time.sleep(1) | ||
custom_metric = get_custom_metric( | ||
client, project_resource, metric_resource) | ||
|
||
write_timeseries_value(client, project_resource, | ||
metric_resource, INSTANCE_ID, | ||
METRIC_KIND) | ||
# Sometimes on new metric descriptors, writes have a delay in being | ||
# read back. 3 seconds should be enough to make sure our read call | ||
# picks up the write | ||
time.sleep(3) | ||
response = read_timeseries(client, project_resource, metric_resource) | ||
value = int( | ||
response['timeSeries'][0]['points'][0]['value']['int64Value']) | ||
# using seed of 1 will create a value of 1 | ||
assert value == pseudo_random_value |
Oops, something went wrong.