class PrometheusMetricsExporterWire(WaitMixin, Wire): """ .. wire:: harness.wires.opentelemetry.ext.prometheus.PrometheusMetricsExporterWire :type: output :runtime: python :config: harness.metrics.Prometheus :requirements: opentelemetry-ext-prometheus==0.5b0 """ _config: metrics_pb2.Prometheus _controller: PushController def configure(self, value: metrics_pb2.Prometheus): assert isinstance(value, metrics_pb2.Prometheus), type(value) self._config = value async def __aenter__(self): meter = metrics.get_meter(__name__) exporter = PrometheusMetricsExporter(self._config.prefix) self._controller = PushController(meter, exporter, 5) start_http_server(self._config.bind.port, self._config.bind.host) _log.info( "%s started: addr=%s:%d", self.__class__.__name__, self._config.bind.host, self._config.bind.port, ) def close(self): super().close() if not self._controller.finished.is_set(): self._controller.shutdown()
def test_push_controller(self): meter = mock.Mock() exporter = mock.Mock() controller = PushController(meter, exporter, 5.0) meter.collect.assert_not_called() exporter.export.assert_not_called() controller.shutdown() self.assertTrue(controller.finished.isSet()) exporter.shutdown.assert_any_call()
def test_push_controller(self): meter = mock.Mock() exporter = mock.Mock() controller = PushController(meter, exporter, 5.0) meter.collect.assert_not_called() exporter.export.assert_not_called() controller.shutdown() self.assertTrue(controller.finished.isSet()) # shutdown should flush the meter self.assertEqual(meter.collect.call_count, 1) self.assertEqual(exporter.export.call_count, 1)
class TestStateless(unittest.TestCase): def setUp(self): self.meter = metrics.MeterProvider(stateful=False).get_meter(__name__) self.exporter = InMemoryMetricsExporter() self.controller = PushController(self.meter, self.exporter, 30) def tearDown(self): self.controller.shutdown() def test_label_keys(self): test_counter = self.meter.create_metric( name="test_counter", description="description", unit="By", value_type=int, metric_type=Counter, ) counter_view = View( test_counter, SumAggregator, label_keys=["environment"], view_config=ViewConfig.LABEL_KEYS, ) self.meter.register_view(counter_view) test_counter.add(6, {"environment": "production", "customer_id": 123}) test_counter.add(5, {"environment": "production", "customer_id": 247}) self.controller.tick() metric_data = self.exporter.get_exported_metrics() self.assertEqual(len(metric_data), 1) self.assertEqual(metric_data[0].labels, (("environment", "production"), )) self.assertEqual(metric_data[0].aggregator.checkpoint, 11) def test_ungrouped(self): test_counter = self.meter.create_metric( name="test_counter", description="description", unit="By", value_type=int, metric_type=Counter, ) counter_view = View( test_counter, SumAggregator, label_keys=["environment"], view_config=ViewConfig.UNGROUPED, ) self.meter.register_view(counter_view) test_counter.add(6, {"environment": "production", "customer_id": 123}) test_counter.add(5, {"environment": "production", "customer_id": 247}) self.controller.tick() metric_data = self.exporter.get_exported_metrics() data_set = set() for data in metric_data: data_set.add((data.labels, data.aggregator.checkpoint)) self.assertEqual(len(metric_data), 2) label1 = (("customer_id", 123), ("environment", "production")) label2 = (("customer_id", 247), ("environment", "production")) self.assertTrue((label1, 6) in data_set) self.assertTrue((label2, 5) in data_set) def test_multiple_views(self): test_counter = self.meter.create_metric( name="test_counter", description="description", unit="By", value_type=int, metric_type=Counter, ) counter_view = View( test_counter, SumAggregator, label_keys=["environment"], view_config=ViewConfig.UNGROUPED, ) mmsc_view = View( test_counter, MinMaxSumCountAggregator, label_keys=["environment"], view_config=ViewConfig.LABEL_KEYS, ) self.meter.register_view(counter_view) self.meter.register_view(mmsc_view) test_counter.add(6, {"environment": "production", "customer_id": 123}) test_counter.add(5, {"environment": "production", "customer_id": 247}) self.controller.tick() metric_data = self.exporter.get_exported_metrics() sum_set = set() mmsc_set = set() for data in metric_data: if isinstance(data.aggregator, SumAggregator): tup = (data.labels, data.aggregator.checkpoint) sum_set.add(tup) elif isinstance(data.aggregator, MinMaxSumCountAggregator): mmsc_set.add(data) self.assertEqual(data.labels, (("environment", "production"), )) self.assertEqual(data.aggregator.checkpoint.sum, 11) # we have to assert this way because order is unknown self.assertEqual(len(sum_set), 2) self.assertEqual(len(mmsc_set), 1) label1 = (("customer_id", 123), ("environment", "production")) label2 = (("customer_id", 247), ("environment", "production")) self.assertTrue((label1, 6) in sum_set) self.assertTrue((label2, 5) in sum_set)