def test_unregister_observer(self): meter = metrics.MeterProvider().get_meter(__name__) callback = mock.Mock() observer = meter.register_observer(callback, "name", "desc", "unit", int, metrics.ValueObserver) meter.unregister_observer(observer) self.assertEqual(len(meter.observers), 0)
def test_create_metric(self): resource = mock.Mock(spec=resources.Resource) meter_provider = metrics.MeterProvider(resource=resource) meter = meter_provider.get_meter(__name__) counter = meter.create_metric("name", "desc", "unit", int, metrics.Counter, ()) self.assertIsInstance(counter, metrics.Counter) self.assertEqual(counter.value_type, int) self.assertEqual(counter.name, "name") self.assertIs(counter.meter.resource, resource)
def test_bind(self): meter = metrics.MeterProvider().get_meter(__name__) metric_types = [metrics.Counter, metrics.ValueRecorder] labels = {"key": "value"} key_labels = tuple(sorted(labels.items())) for _type in metric_types: metric = _type("name", "desc", "unit", int, meter, ("key", )) bound_instrument = metric.bind(labels) self.assertEqual(metric.bound_instruments.get(key_labels), bound_instrument)
def test_shutdown(self): controller = Mock() exporter = Mock() meter_provider = metrics.MeterProvider() # pylint: disable=protected-access meter_provider._controllers = [controller] meter_provider._exporters = [exporter] meter_provider.shutdown() self.assertEqual(controller.shutdown.call_count, 1) self.assertEqual(exporter.shutdown.call_count, 1) self.assertIsNone(meter_provider._atexit_handler)
def test_observe(self): meter = metrics.MeterProvider().get_meter(__name__) observer = metrics.UpDownSumObserver(None, "name", "desc", "unit", int, meter, ("key", ), True) labels = {"key": "value"} key_labels = tuple(sorted(labels.items())) values = (37, 42, 14, 30) for val in values: observer.observe(val, labels) self.assertEqual(observer.aggregators[key_labels].current, values[-1])
def test_bind(self): meter = metrics.MeterProvider().get_meter(__name__) metric_types = [metrics.Counter, metrics.Measure] for _type in metric_types: metric = _type("name", "desc", "unit", int, meter, ("key",)) kvp = {"key": "value"} label_set = meter.get_label_set(kvp) bound_instrument = metric.bind(label_set) self.assertEqual( metric.bound_instruments.get(label_set), bound_instrument )
def test_collect_metrics(self): meter = metrics.MeterProvider().get_meter(__name__) processor_mock = mock.Mock() meter.processor = processor_mock counter = meter.create_metric("name", "desc", "unit", float, metrics.Counter) labels = {"key1": "value1"} meter.register_view(View(counter, SumAggregator)) counter.add(1.0, labels) meter.collect() self.assertTrue(processor_mock.process.called)
def test_run_exception(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) callback = mock.Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.Observer(callback, "name", "desc", "unit", int, meter, (), True) self.assertFalse(observer.run()) self.assertTrue(logger_mock.warning.called)
def test_create_updowncounter(self): meter = metrics.MeterProvider().get_meter(__name__) updowncounter = meter.create_updowncounter( "name", "desc", "unit", float, ) self.assertIsInstance(updowncounter, metrics.UpDownCounter) self.assertEqual(updowncounter.value_type, float) self.assertEqual(updowncounter.name, "name")
def test_set(self): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Gauge("name", "desc", "unit", int, meter, ("key", )) kvp = {"key": "value"} label_set = meter.get_label_set(kvp) handle = metric.get_handle(label_set) metric.set(3, label_set) self.assertEqual(handle.aggregator.current, 3) metric.set(2, label_set) # TODO: Fix once other aggregators implemented self.assertEqual(handle.aggregator.current, 5)
def test_start_pipeline(self): exporter = Mock() meter_provider = metrics.MeterProvider() meter = meter_provider.get_meter(__name__) # pylint: disable=protected-access meter_provider.start_pipeline(meter, exporter, 6) try: self.assertEqual(len(meter_provider._exporters), 1) self.assertEqual(len(meter_provider._controllers), 1) finally: meter_provider.shutdown()
def test_histogram_stateless(self): # Use the meter type provided by the SDK package meter = metrics.MeterProvider(stateful=False).get_meter(__name__) exporter = InMemoryMetricsExporter() controller = PushController(meter, exporter, 30) requests_size = meter.create_metric( name="requests_size", description="size of requests", unit="1", value_type=int, metric_type=ValueRecorder, ) size_view = View( requests_size, HistogramAggregator, aggregator_config={"bounds": [20, 40, 60, 80, 100]}, label_keys=["environment"], view_config=ViewConfig.LABEL_KEYS, ) meter.register_view(size_view) # Since this is using the HistogramAggregator, the bucket counts will be reflected # with each record requests_size.record(25, {"environment": "staging", "test": "value"}) requests_size.record(1, {"environment": "staging", "test": "value2"}) requests_size.record(200, {"environment": "staging", "test": "value3"}) controller.tick() metrics_list = exporter.get_exported_metrics() self.assertEqual(len(metrics_list), 1) checkpoint = metrics_list[0].aggregator.checkpoint self.assertEqual( tuple(checkpoint.items()), ((20, 1), (40, 1), (60, 0), (80, 0), (100, 0), (inf, 1)), ) exporter.clear() requests_size.record(25, {"environment": "staging", "test": "value"}) requests_size.record(1, {"environment": "staging", "test": "value2"}) requests_size.record(200, {"environment": "staging", "test": "value3"}) controller.tick() metrics_list = exporter.get_exported_metrics() self.assertEqual(len(metrics_list), 1) checkpoint = metrics_list[0].aggregator.checkpoint self.assertEqual( tuple(checkpoint.items()), ((20, 1), (40, 1), (60, 0), (80, 0), (100, 0), (inf, 1)), )
def test_record_batch(self): meter = metrics.MeterProvider().get_meter(__name__) label_keys = ("key1",) counter = metrics.Counter( "name", "desc", "unit", float, meter, label_keys ) kvp = {"key1": "value1"} label_set = meter.get_label_set(kvp) record_tuples = [(counter, 1.0)] meter.record_batch(label_set, record_tuples) self.assertEqual(counter.bind(label_set).aggregator.current, 1.0)
def test_invalid_metric(self): meter = metrics.MeterProvider().get_meter(__name__) metric = meter.create_metric("tesname", "testdesc", "unit", int, TestMetric) kvp = {"environment": "staging"} label_set = meter.get_label_set(kvp) record = MetricRecord(None, label_set, metric) collector = CustomCollector("testprefix") collector.add_metrics_data([record]) collector.collect() self.assertLogs("opentelemetry.ext.prometheus", level="WARNING")
def test_record(self): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Measure("name", "desc", "unit", int, meter, ("key",)) labels = {"key": "value"} bound_measure = metric.bind(labels) values = (37, 42, 7) for val in values: metric.record(val, labels) self.assertEqual( bound_measure.aggregator.current, (min(values), max(values), sum(values), len(values)), )
def test_add_non_decreasing_float_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", float, meter, ("key", )) labels = {"key": "value"} bound_counter = metric.bind(labels) metric.add(3.3, labels) metric.add(0.0, labels) metric.add(0.1, labels) metric.add(-0.1, labels) self.assertEqual(bound_counter.aggregator.current, 3.4) self.assertEqual(logger_mock.warning.call_count, 1)
def test_collect_disabled_metric(self): meter = metrics.MeterProvider().get_meter(__name__) batcher_mock = mock.Mock() meter.batcher = batcher_mock label_keys = ("key1", ) counter = metrics.Counter("name", "desc", "unit", float, meter, label_keys, False) labels = {"key1": "value1"} counter.add(1.0, labels) meter.metrics.add(counter) meter.collect() self.assertFalse(batcher_mock.process.called)
def test_add_non_decreasing_int_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", int, meter) labels = {"key": "value"} counter_v = View(metric, SumAggregator) meter.register_view(counter_v) bound_counter = metric.bind(labels) metric.add(3, labels) metric.add(0, labels) metric.add(-1, labels) self.assertEqual(bound_counter.view_datas.pop().aggregator.current, 3) self.assertEqual(logger_mock.warning.call_count, 1)
def test_create_valuerecorder(self): meter = metrics.MeterProvider().get_meter(__name__) valuerecorder = meter.create_valuerecorder( "name", "desc", "unit", float, ) self.assertIsInstance(valuerecorder, metrics.ValueRecorder) self.assertEqual(valuerecorder.value_type, float) self.assertEqual(valuerecorder.name, "name") self.assertEqual(valuerecorder.meter, meter)
def test_record_batch_exists(self): meter = metrics.MeterProvider().get_meter(__name__) label_keys = ("key1", ) labels = {"key1": "value1"} counter = metrics.Counter("name", "desc", "unit", float, meter, label_keys) counter.add(1.0, labels) bound_counter = counter.bind(labels) record_tuples = [(counter, 1.0)] meter.record_batch(labels, record_tuples) self.assertEqual(counter.bind(labels), bound_counter) self.assertEqual(bound_counter.aggregator.current, 2.0)
def test_record_batch_multiple(self): meter = metrics.MeterProvider().get_meter(__name__) label_keys = ("key1", "key2", "key3") labels = {"key1": "value1", "key2": "value2", "key3": "value3"} counter = metrics.Counter("name", "desc", "unit", float, meter, label_keys) valuerecorder = metrics.ValueRecorder("name", "desc", "unit", float, meter, label_keys) record_tuples = [(counter, 1.0), (valuerecorder, 3.0)] meter.record_batch(labels, record_tuples) self.assertEqual(counter.bind(labels).aggregator.current, 1.0) self.assertEqual( valuerecorder.bind(labels).aggregator.current, (3.0, 3.0, 3.0, 1))
def test_collect_observers(self): meter = metrics.MeterProvider().get_meter(__name__) processor_mock = Mock() meter.processor = processor_mock def callback(observer): self.assertIsInstance(observer, metrics_api.Observer) observer.observe(45, {}) meter.register_valueobserver(callback, "name", "desc", "unit", int, (), True) meter.collect() self.assertTrue(processor_mock.process.called)
def test_record(self): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Measure("name", "desc", "unit", int, meter, ("key", )) kvp = {"key": "value"} label_set = meter.get_label_set(kvp) handle = metric.get_handle(label_set) values = (37, 42, 7) for val in values: metric.record(val, label_set) self.assertEqual( handle.aggregator.current, (min(values), max(values), sum(values), len(values)), )
def test_collect(self): meter = metrics.MeterProvider().get_meter(__name__) batcher_mock = mock.Mock() meter.batcher = batcher_mock label_keys = ("key1", ) counter = metrics.Counter("name", "desc", "unit", float, meter, label_keys) kvp = {"key1": "value1"} label_set = meter.get_label_set(kvp) counter.add(label_set, 1.0) meter.metrics.add(counter) meter.collect() self.assertTrue(batcher_mock.process.called)
def test_record_batch_exists(self): meter = metrics.MeterProvider().get_meter(__name__) label_keys = ("key1", ) kvp = {"key1": "value1"} label_set = meter.get_label_set(kvp) counter = metrics.Counter("name", "desc", "unit", float, meter, label_keys) counter.add(1.0, label_set) handle = counter.get_handle(label_set) record_tuples = [(counter, 1.0)] meter.record_batch(label_set, record_tuples) self.assertEqual(counter.get_handle(label_set), handle) self.assertEqual(handle.aggregator.current, 2.0)
def test_finished_collection_stateless(self): meter = metrics.MeterProvider().get_meter(__name__) batcher = Batcher(False) aggregator = SumAggregator() metric = metrics.Counter("available memory", "available memory", "bytes", int, meter) aggregator.update(1.0) labels = () _batch_map = {} _batch_map[(metric, SumAggregator, tuple(), labels)] = aggregator batcher._batch_map = _batch_map batcher.finished_collection() self.assertEqual(len(batcher._batch_map), 0)
def setUp(self): set_meter_provider(metrics.MeterProvider()) self._meter = get_meter_provider().get_meter(__name__) self._test_metric = self._meter.create_counter( "testname", "testdesc", "unit", int, ) labels = {"environment": "staging"} self._labels_key = get_dict_as_key(labels) self._mock_registry_register = mock.Mock() self._registry_register_patch = mock.patch( "prometheus_client.core.REGISTRY.register", side_effect=self._mock_registry_register, )
def test_record(self): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.ValueRecorder("name", "desc", "unit", int, meter) labels = {"key": "value"} measure_v = View(metric, MinMaxSumCountAggregator) bound_valuerecorder = metric.bind(labels) meter.register_view(measure_v) values = (37, 42, 7) for val in values: metric.record(val, labels) self.assertEqual( bound_valuerecorder.view_datas.pop().aggregator.current, (min(values), max(values), sum(values), len(values)), )
def test_bind(self): meter = metrics.MeterProvider().get_meter(__name__) metric_types = [ metrics.Counter, metrics.UpDownCounter, metrics.ValueRecorder, ] labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) for _type in metric_types: metric = _type("name", "desc", "unit", int, meter) bound_instrument = metric.bind(labels) self.assertEqual(metric.bound_instruments.get(key_labels), bound_instrument)
def test_finished_collection_stateful(self): meter_provider = metrics.MeterProvider() meter = meter_provider.get_meter(__name__) processor = Processor(True, meter_provider.resource) aggregator = SumAggregator() metric = metrics.Counter("available memory", "available memory", "bytes", int, meter) aggregator.update(1.0) labels = () _batch_map = {} _batch_map[(metric, SumAggregator, tuple(), labels)] = aggregator processor._batch_map = _batch_map processor.finished_collection() self.assertEqual(len(processor._batch_map), 1)