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_push_controller_suppress_instrumentation(self): meter = mock.Mock() exporter = mock.Mock() exporter.export = lambda x: self.assertIsNotNone( get_value("suppress_instrumentation")) with mock.patch( "opentelemetry.context._RUNTIME_CONTEXT") as context_patch: controller = PushController(meter, exporter, 30.0) controller.tick() self.assertEqual(context_patch.attach.called, True) self.assertEqual(context_patch.detach.called, True) self.assertEqual(get_value("suppress_instrumentation"), None)
def test_export(self): channel = grpc.insecure_channel(self.address) transport = metric_service_grpc_transport.MetricServiceGrpcTransport( channel=channel ) client = MagicMock(wraps=MetricServiceClient(transport=transport)) exporter = CloudMonitoringMetricsExporter( self.project_id, client=client ) meter_provider = metrics.MeterProvider( resource=Resource.create( { "cloud.account.id": "some_account_id", "cloud.provider": "gcp", "cloud.zone": "us-east1-b", "host.id": 654321, "gcp.resource_type": "gce_instance", } ) ) meter = meter_provider.get_meter(__name__) counter = meter.create_counter( # TODO: remove "opentelemetry/" prefix which is a hack # https://github.com/GoogleCloudPlatform/opentelemetry-operations-python/issues/84 name="opentelemetry/name", description="desc", unit="1", value_type=int, ) # interval doesn't matter, we don't start the thread and just run # tick() instead controller = PushController(meter, exporter, 10) counter.add(10, {"env": "test"}) with patch( "opentelemetry.exporter.cloud_monitoring.logger" ) as mock_logger: controller.tick() # run tox tests with `-- -log-cli-level=0` to see mock calls made logger.debug(client.create_time_series.mock_calls) mock_logger.warning.assert_not_called() mock_logger.error.assert_not_called()
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)