From 12057a4e368f136fcc2a9bfb986f8ab47caff6f0 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Mon, 8 Oct 2018 17:10:15 -0700 Subject: [PATCH] Add MetricDescriptor class, tests --- .../metrics/export/metric_descriptor.py | 142 ++++++++++++++++++ tests/unit/metrics/export/__init__.py | 0 .../metrics/export/test_metric_descriptor.py | 58 +++++++ 3 files changed, 200 insertions(+) create mode 100644 opencensus/metrics/export/metric_descriptor.py delete mode 100644 tests/unit/metrics/export/__init__.py create mode 100644 tests/unit/metrics/export/test_metric_descriptor.py diff --git a/opencensus/metrics/export/metric_descriptor.py b/opencensus/metrics/export/metric_descriptor.py new file mode 100644 index 000000000..8f1f6076f --- /dev/null +++ b/opencensus/metrics/export/metric_descriptor.py @@ -0,0 +1,142 @@ +# Copyright 2018, OpenCensus Authors +# +# 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. + + +import six + + +class _MetricDescriptorTypeMeta(type): + """Helper for `x in MetricDescriptorType`.""" + + def __contains__(cls, item): + return item in {MetricDescriptorType.GAUGE_INT64, + MetricDescriptorType.GAUGE_DOUBLE, + MetricDescriptorType.GAUGE_DISTRIBUTION, + MetricDescriptorType.CUMULATIVE_INT64, + MetricDescriptorType.CUMULATIVE_DOUBLE, + MetricDescriptorType.CUMULATIVE_DISTRIBUTION} + + +@six.add_metaclass(_MetricDescriptorTypeMeta) +class MetricDescriptorType(object): + """The kind of metric. It describes how the data is reported. + + MetricDescriptorType is an enum of valid MetricDescriptor type values. See + opencensus-proto for details: + + https://github.com/census-instrumentation/opencensus-proto/blob/24333298e36590ea0716598caacc8959fc393c48/src/opencensus/proto/metrics/v1/metrics.proto#L73 # noqa + + A gauge is an instantaneous measurement of a value. + + A cumulative measurement is a value accumulated over a time interval. In a + time series, cumulative measurements should have the same start time and + increasing end times, until an event resets the cumulative value to zero + and sets a new start time for the following points. + + """ + # Integer gauge. The value can go both up and down. + GAUGE_INT64 = 1 + + # Floating point gauge. The value can go both up and down. + GAUGE_DOUBLE = 2 + + # Distribution gauge measurement. The count and sum can go both up and + # down. Recorded values are always >= 0. + # Used in scenarios like a snapshot of time the current items in a queue + # have spent there. + GAUGE_DISTRIBUTION = 3 + + # Integer cumulative measurement. The value cannot decrease, if resets then + # the start_time should also be reset. + CUMULATIVE_INT64 = 4 + + # Floating point cumulative measurement. The value cannot decrease, if + # resets then the start_time should also be reset. Recorded values are + # always >= 0. + CUMULATIVE_DOUBLE = 5 + + # Distribution cumulative measurement. The count and sum cannot decrease, + # if resets then the start_time should also be reset. + CUMULATIVE_DISTRIBUTION = 6 + + # Some frameworks implemented Histograms as a summary of observations + # (usually things like request durations and response sizes). While it also + # provides a total count of observations and a sum of all observed values, + # it calculates configurable percentiles over a sliding time window. This + # is not recommended, since it cannot be aggregated. + SUMMARY = 7 + + +class MetricDescriptor(object): + """Defines a metric type and its schema. + + This class implements the spec for v1 MetricDescriptors, as of + opencensus-proto release v0.0.2. See opencensus-proto for details: + + https://github.com/census-instrumentation/opencensus-proto/blob/24333298e36590ea0716598caacc8959fc393c48/src/opencensus/proto/metrics/v1/metrics.proto#L53 # noqa + + :type name: str + :param name: The metric type, including its DNS name prefix. It must be + unique. + + :type description: str + :param description: A detailed description of the metric, which can be used + in documentation. + + :type unit: str + :param unit: The unit in which the metric value is reported. Follows the + format described by http://unitsofmeasure.org/ucum.html. + + :type type_: int + :param unit: The unit in which the metric value is reported. The + MetricDescriptorType class enumerates valid options. + + :type label_keys: list(:class: '~opencensus.metrics.label_key.LabelKey') + :param label_keys: The label keys associated with the metric descriptor. + """ + def __init__(self, name, description, unit, type_, label_keys): + if type_ not in MetricDescriptorType: + raise ValueError("Invalid type") + + if not label_keys: + raise ValueError("label_keys must not be empty or null") + + if any(key is None for key in label_keys): + raise ValueError("label_keys must not contain null keys") + + self._name = name + self._description = description + self._unit = unit + self._type = type_ + self._label_keys = label_keys + + @property + def name(self): + return self._name + + @property + def description(self): + return self._description + + @property + def unit(self): + return self._unit + + @property + def type(self): + return self._type + + @property + def label_keys(self): + return self._label_keys diff --git a/tests/unit/metrics/export/__init__.py b/tests/unit/metrics/export/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/unit/metrics/export/test_metric_descriptor.py b/tests/unit/metrics/export/test_metric_descriptor.py new file mode 100644 index 000000000..8b114a50d --- /dev/null +++ b/tests/unit/metrics/export/test_metric_descriptor.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +# Copyright 2018, OpenCensus Authors +# +# 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. + +import unittest + +from opencensus.metrics.export.metric_descriptor import MetricDescriptor +from opencensus.metrics.export.metric_descriptor import MetricDescriptorType +from opencensus.metrics.label_key import LabelKey + + +NAME = 'metric' +DESCRIPTION = 'Metric description' +UNIT = '0.738.[ft_i].[lbf_av]/s' +LABEL_KEY1 = LabelKey('key1', 'key description one') +LABEL_KEY2 = LabelKey('值', '测试用键') +LABEL_KEYS = (LABEL_KEY1, LABEL_KEY2) + + +class TestMetricDescriptor(unittest.TestCase): + + def test_init(self): + metric_descriptor = MetricDescriptor(NAME, DESCRIPTION, UNIT, + MetricDescriptorType.GAUGE_DOUBLE, + (LABEL_KEY1, LABEL_KEY2)) + + self.assertEqual(metric_descriptor.name, NAME) + self.assertEqual(metric_descriptor.description, DESCRIPTION) + self.assertEqual(metric_descriptor.unit, UNIT) + self.assertEqual(metric_descriptor.type, + MetricDescriptorType.GAUGE_DOUBLE) + self.assertEqual(metric_descriptor.label_keys, LABEL_KEYS) + + def test_bogus_type(self): + with self.assertRaises(ValueError): + MetricDescriptor(NAME, DESCRIPTION, UNIT, 0, (LABEL_KEY1,)) + + def test_null_label_keys(self): + with self.assertRaises(ValueError): + MetricDescriptor(NAME, DESCRIPTION, UNIT, + MetricDescriptorType.GAUGE_DOUBLE, None) + + def test_null_label_key_values(self): + with self.assertRaises(ValueError): + MetricDescriptor(NAME, DESCRIPTION, UNIT, + MetricDescriptorType.GAUGE_DOUBLE, (None,))