async def test_prometheus_exporter(serve_instance): exporter = MetricExporterActor.remote(PrometheusExporter) collector = MetricClient( exporter, push_interval=2, default_labels={"default": "label"}) counter = collector.new_counter(name="my_counter", label_names=("a", )) measure = collector.new_measure( name="my_measure", description="help", label_names=("ray", "lang")) measure = measure.labels(lang="C++") counter.labels(a="1").add() measure.labels(ray="").record(0) measure.labels(ray="").record(42) await collector._push_to_exporter_once() metric_stored = await exporter.inspect_metrics.remote() metric_stored = metric_stored.decode() fragments = [ "# HELP my_counter_total", "# TYPE my_counter_total counter", 'my_counter_total{a="1",default="label"} 1.0', "# TYPE my_counter_created gauge", 'my_counter_created{a="1",default="label"}', "# HELP my_measure help", "# TYPE my_measure gauge", 'my_measure{default="label",lang="C++",ray=""} 42.0' ] for fragment in fragments: assert fragment in metric_stored
async def test_in_memory_exporter(serve_instance): exporter = MetricExporterActor.remote(InMemoryExporter) collector = MetricClient( exporter, push_interval=2, default_labels={"default": "label"}) counter = collector.new_counter(name="my_counter", label_names=("a", )) measure = collector.new_measure( name="my_measure", description="help", label_names=("ray", "lang")) measure = measure.labels(lang="C++") counter.labels(a="1").add() measure.labels(ray="").record(0) measure.labels(ray="").record(42) await collector._push_to_exporter_once() metric_stored = await exporter.inspect_metrics.remote() assert metric_stored == [{ "info": { "name": "my_counter", "type": "MetricType.COUNTER", "default": "label", "a": "1" }, "value": 1 }, { "info": { "name": "my_measure", "type": "MetricType.MEASURE", "default": "label", "lang": "C++", "ray": "" }, "value": 42 }]
async def test_prometheus_conflicting_labels(serve_instance): exporter = MetricExporterActor.remote(PrometheusExporter) collector_a = MetricClient(exporter, push_interval=2, default_labels={"default": "a"}) collector_b = MetricClient(exporter, push_interval=2, default_labels={"default": "b"}) for collector in [collector_a, collector_b]: counter = collector.new_counter("num") counter.add() await collector._push_to_exporter_once() metric_stored = (await exporter.inspect_metrics.remote()).decode() fragments = ['num_total{default="a"}', 'num_total{default="b"}'] for fragment in fragments: assert fragment in metric_stored