From b31d7f66d561b6c9cb0d334410d69f1820724ab1 Mon Sep 17 00:00:00 2001 From: Max Kuzkin Date: Thu, 1 Sep 2016 20:15:43 +0300 Subject: [PATCH 1/4] Add support for the comparison filters of Google Monitoring API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google Monitoring API filters support <,<=,>,>= operators as described in its documentation: https://cloud.google.com/monitoring/api/v3/filters. Current version of the library only has mappings of: 1. ’{key}_prefix:{value}' -> '{key} = starts_with("{value}")' 2. ’{key}_suffix:{value}' -> '{key} = ends_with("{value}")' This patch introduces additional mappings of: 3. ’{key}_greater:{value}' -> '{key} > {value}' 4. ’{key}_greaterequal:{value}' -> '{key} >= {value}' 5. ’{key}_less:{value}' -> '{key} < {value}' 6. ’{key}_lessequal:{value}' -> '{key} <= {value}' So that it is possible, for example, to filter based on the response_code values range, as shown below: metric.type = "appengine.googleapis.com/http/server/response_count" AND metric.label.response_code < 600 AND metric.label.response_code >= 500 This patch will allow to remove “hack” in the following tool: https://github.com/odin-public/gcpmetrics that enables queries to the monitoring api from the command line. --- gcloud/monitoring/query.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gcloud/monitoring/query.py b/gcloud/monitoring/query.py index 4e2d7d62cfa2..d010865b53aa 100644 --- a/gcloud/monitoring/query.py +++ b/gcloud/monitoring/query.py @@ -637,7 +637,9 @@ def _build_label_filter(category, *args, **kwargs): continue suffix = None - if key.endswith('_prefix') or key.endswith('_suffix'): + ends = ['_prefix', '_suffix', '_greater', '_greaterequal', + '_less', '_lessequal'] + if key.endswith(tuple(ends)): key, suffix = key.rsplit('_', 1) if category == 'resource' and key == 'resource_type': @@ -649,6 +651,14 @@ def _build_label_filter(category, *args, **kwargs): term = '{key} = starts_with("{value}")' elif suffix == 'suffix': term = '{key} = ends_with("{value}")' + elif suffix == 'greater': + term = '{key} > {value}' + elif suffix == 'greaterequal': + term = '{key} >= {value}' + elif suffix == 'less': + term = '{key} < {value}' + elif suffix == 'lessequal': + term = '{key} <= {value}' else: term = '{key} = "{value}"' From ddb68290364cb6450a0a3ea0277d1a24943daccf Mon Sep 17 00:00:00 2001 From: Max Kuzkin Date: Thu, 1 Sep 2016 22:37:11 +0300 Subject: [PATCH 2/4] Added unit tests to validate added comparison operators Fixed `tox -e cover` to have 100% coverage after proposed patch --- gcloud/monitoring/test_query.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/gcloud/monitoring/test_query.py b/gcloud/monitoring/test_query.py index aa08a493384f..720a5ec61678 100644 --- a/gcloud/monitoring/test_query.py +++ b/gcloud/monitoring/test_query.py @@ -557,6 +557,28 @@ def test_metric_labels(self): ) self.assertEqual(actual, expected) + def test_metric_label_response_code_greater_less(self): + actual = self._callFUT( + 'metric', + response_code_greater=500, + response_code_less=600) + expected = ( + 'metric.label.response_code < 600' + ' AND metric.label.response_code > 500' + ) + self.assertEqual(actual, expected) + + def test_metric_label_response_code_greater_less_equal(self): + actual = self._callFUT( + 'metric', + response_code_greaterequal=500, + response_code_lessequal=600) + expected = ( + 'metric.label.response_code <= 600' + ' AND metric.label.response_code >= 500' + ) + self.assertEqual(actual, expected) + def test_resource_labels(self): actual = self._callFUT( 'resource', From c5bf03326720535e58e684bed35acf2f6eddfa4d Mon Sep 17 00:00:00 2001 From: Max Kuzkin Date: Fri, 2 Sep 2016 10:48:02 +0300 Subject: [PATCH 3/4] PR improvements as suggested by Ken Rimey 1. Added docstring for select_metrics with the explanation of additional endings. No reason to do the same for select_resources, because all of the currently defined monitored resource labels are strings. 2. Removed array->tuple conversion, moved constant directly into the if condition. --- gcloud/monitoring/query.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/gcloud/monitoring/query.py b/gcloud/monitoring/query.py index d010865b53aa..7d4af83f9174 100644 --- a/gcloud/monitoring/query.py +++ b/gcloud/monitoring/query.py @@ -313,6 +313,25 @@ def select_metrics(self, *args, **kwargs): metric.label.