def test_exemplars_with_hash_in_label_values(self): families = text_string_to_metric_families("""# TYPE a histogram # HELP a help a_bucket{le="1.0",foo="bar # "} 0 # {a="b",foo="bar # bar"} 0.5 a_bucket{le="2.0",foo="bar # "} 2 # {a="c",foo="bar # bar"} 0.5 a_bucket{le="+Inf",foo="bar # "} 3 # {a="d",foo="bar # bar"} 4 # EOF """) hfm = HistogramMetricFamily("a", "help") hfm.add_sample("a_bucket", { "le": "1.0", "foo": "bar # " }, 0.0, None, Exemplar({ "a": "b", "foo": "bar # bar" }, 0.5)) hfm.add_sample("a_bucket", { "le": "2.0", "foo": "bar # " }, 2.0, None, Exemplar({ "a": "c", "foo": "bar # bar" }, 0.5)) hfm.add_sample("a_bucket", { "le": "+Inf", "foo": "bar # " }, 3.0, None, Exemplar({ "a": "d", "foo": "bar # bar" }, 4)) self.assertEqual([hfm], list(families))
def test_fallback_to_state_machine_label_parsing(self): from unittest.mock import patch from prometheus_client.openmetrics.parser import _parse_sample parse_sample_function = "prometheus_client.openmetrics.parser._parse_sample" parse_labels_function = "prometheus_client.openmetrics.parser._parse_labels" parse_remaining_function = "prometheus_client.openmetrics.parser._parse_remaining_text" state_machine_function = "prometheus_client.openmetrics.parser._parse_labels_with_state_machine" parse_sample_return_value = Sample("a_total", {"foo": "foo # bar"}, 1) with patch(parse_sample_function, return_value=parse_sample_return_value) as mock: families = text_string_to_metric_families("""# TYPE a counter # HELP a help a_total{foo="foo # bar"} 1 # EOF """) a = CounterMetricFamily("a", "help", labels=["foo"]) a.add_metric(["foo # bar"], 1) self.assertEqual([a], list(families)) mock.assert_called_once_with('a_total{foo="foo # bar"} 1') # First fallback case state_machine_return_values = [{"foo": "foo # bar"}, len('foo="foo # bar"}')] parse_remaining_values = [1, None, None] with patch(parse_labels_function) as mock1: with patch(state_machine_function, return_value=state_machine_return_values) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_total{foo="foo # bar"} 1') s = Sample("a_total", {"foo": "foo # bar"}, 1) self.assertEqual(s, sample) mock1.assert_not_called() mock2.assert_called_once_with('foo="foo # bar"} 1') mock3.assert_called_once_with('1') # Second fallback case state_machine_return_values = [{"le": "1.0"}, len('le="1.0"}')] parse_remaining_values = [0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)] with patch(parse_labels_function) as mock1: with patch(state_machine_function, return_value=state_machine_return_values) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_bucket{le="1.0"} 0 123 # {a="b"} 0.5') s = Sample("a_bucket", {"le": "1.0"}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) self.assertEqual(s, sample) mock1.assert_not_called() mock2.assert_called_once_with('le="1.0"} 0 123 # {a="b"} 0.5') mock3.assert_called_once_with('0 123 # {a="b"} 0.5') # No need to fallback case parse_labels_return_values = {"foo": "foo#bar"} parse_remaining_values = [1, None, None] with patch(parse_labels_function, return_value=parse_labels_return_values) as mock1: with patch(state_machine_function) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_total{foo="foo#bar"} 1') s = Sample("a_total", {"foo": "foo#bar"}, 1) self.assertEqual(s, sample) mock1.assert_called_once_with('foo="foo#bar"') mock2.assert_not_called() mock3.assert_called_once_with('1')
def collect(self): metric = Metric("hh", "help", 'histogram') # This is not sane, but it covers all the cases. metric.add_sample("hh_bucket", {"le": "1"}, 0, None, Exemplar({'a': 'b'}, 0.5)) metric.add_sample("hh_bucket", {"le": "2"}, 0, None, Exemplar({'le': '7'}, 0.5, 12)) metric.add_sample("hh_bucket", {"le": "3"}, 0, 123, Exemplar({'a': 'b'}, 2.5, 12)) metric.add_sample("hh_bucket", {"le": "4"}, 0, None, Exemplar({'a': '\n"\\'}, 3.5)) metric.add_sample("hh_bucket", {"le": "+Inf"}, 0, None, None) yield metric
def test_gaugehistogram_exemplars(self): families = text_string_to_metric_families("""# TYPE a gaugehistogram # HELP a help a_bucket{le="1.0"} 0 123 # {a="b"} 0.5 a_bucket{le="2.0"} 2 123 # {a="c"} 0.5 a_bucket{le="+Inf"} 3 123 # {a="d"} 4 123 # EOF """) hfm = GaugeHistogramMetricFamily("a", "help") hfm.add_sample("a_bucket", {"le": "1.0"}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) hfm.add_sample("a_bucket", {"le": "2.0"}, 2.0, Timestamp(123, 0), Exemplar({"a": "c"}, 0.5)), hfm.add_sample("a_bucket", {"le": "+Inf"}, 3.0, Timestamp(123, 0), Exemplar({"a": "d"}, 4, Timestamp(123, 0))) self.assertEqual([hfm], list(families))
def test_histogram_exemplars(self): families = text_string_to_metric_families("""# TYPE a histogram # HELP a help a_bucket{le="1"} 0 # {a="b"} 0.5 a_bucket{le="2"} 2 # {a="c"} 0.5 a_bucket{le="+Inf"} 3 # {a="1234567890123456789012345678901234567890123456789012345678"} 4 123 # EOF """) hfm = HistogramMetricFamily("a", "help") hfm.add_sample("a_bucket", {"le": "1"}, 0.0, None, Exemplar({"a": "b"}, 0.5)) hfm.add_sample("a_bucket", {"le": "2"}, 2.0, None, Exemplar({"a": "c"}, 0.5)), hfm.add_sample("a_bucket", {"le": "+Inf"}, 3.0, None, Exemplar({"a": "1234567890123456789012345678901234567890123456789012345678"}, 4, Timestamp(123, 0))) self.assertEqual([hfm], list(families))
def test_counter_exemplars_empty_brackets(self): families = text_string_to_metric_families("""# TYPE a counter # HELP a help a_total{} 0 123 # {a="b"} 0.5 # EOF """) cfm = CounterMetricFamily("a", "help") cfm.add_sample("a_total", {}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) self.assertEqual([cfm], list(families))
def collect(self): metric = Metric("hh", "help", 'histogram') # This is not sane, but it covers all the cases. metric.add_sample("hh_count", {}, 0, None, Exemplar({'a': 'b'}, 0.5)) yield metric
def collect(self): metric = Metric("cc", "A counter", 'counter') metric.add_sample("cc_total", {}, 1, None, None) metric.add_sample("cc_created", {}, 123.456, None, Exemplar({'a': 'b'}, 1.0, 123.456)) yield metric