Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions prometheus_client/openmetrics/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,7 @@ def build_metric(name, documentation, typ, unit, samples):
if parts[1] == 'HELP':
if documentation is not None:
raise ValueError("More than one HELP for metric: " + line)
if len(parts) == 4:
documentation = _unescape_help(parts[3])
elif len(parts) == 3:
raise ValueError("Invalid line: " + line)
documentation = _unescape_help(parts[3])
elif parts[1] == 'TYPE':
if typ is not None:
raise ValueError("More than one TYPE for metric: " + line)
Expand Down
6 changes: 6 additions & 0 deletions tests/openmetrics/test_exposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ def test_counter_total(self):
self.assertEqual(b'# HELP cc A counter\n# TYPE cc counter\ncc_total 1.0\ncc_created 123.456\n# EOF\n',
generate_latest(self.registry))

def test_counter_unit(self):
c = Counter('cc_seconds', 'A counter', registry=self.registry, unit="seconds")
c.inc()
self.assertEqual(b'# HELP cc_seconds A counter\n# TYPE cc_seconds counter\n# UNIT cc_seconds seconds\ncc_seconds_total 1.0\ncc_seconds_created 123.456\n# EOF\n',
generate_latest(self.registry))

def test_gauge(self):
g = Gauge('gg', 'A gauge', registry=self.registry)
g.set(17)
Expand Down
38 changes: 36 additions & 2 deletions tests/openmetrics/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,16 @@ def test_counter_exemplars(self):
# 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 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))
Expand Down Expand Up @@ -409,11 +419,15 @@ def test_escaping(self):
# HELP a he\\n\\\\l\\tp
a_total{foo="b\\"a\\nr"} 1
a_total{foo="b\\\\a\\z"} 2
a_total{foo="b\\"a\\nr # "} 3
a_total{foo="b\\\\a\\z # "} 4
# EOF
""")
metric_family = CounterMetricFamily("a", "he\n\\l\\tp", labels=["foo"])
metric_family.add_metric(["b\"a\nr"], 1)
metric_family.add_metric(["b\\a\\z"], 2)
metric_family.add_metric(["b\"a\nr # "], 3)
metric_family.add_metric(["b\\a\\z # "], 4)
self.assertEqual([metric_family], list(families))

def test_null_byte(self):
Expand Down Expand Up @@ -591,6 +605,10 @@ def test_roundtrip(self):
foo_count 17.0
foo_sum 324789.3
foo_created 1.520430000123e+09
# HELP bar histogram Testing with labels
# TYPE bar histogram
bar_bucket{a="b",le="+Inf"} 0.0
bar_bucket{a="c",le="+Inf"} 0.0
# EOF
"""
families = list(text_string_to_metric_families(text))
Expand Down Expand Up @@ -628,9 +646,14 @@ def test_invalid_input(self):
('a{a="1",b="2",} 1\n# EOF\n'),
# Invalid labels.
('a{1="1"} 1\n# EOF\n'),
('a{1="1"}1\n# EOF\n'),
('a{a="1",a="1"} 1\n# EOF\n'),
('a{a="1"b} 1\n# EOF\n'),
('a{1=" # "} 1\n# EOF\n'),
('a{a=" # ",a=" # "} 1\n# EOF\n'),
('a{a=" # "}1\n# EOF\n'),
('a{a=" # ",b=}1\n# EOF\n'),
('a{a=" # "b}1\n# EOF\n'),
# Missing value.
('a\n# EOF\n'),
('a \n# EOF\n'),
Expand Down Expand Up @@ -667,6 +690,8 @@ def test_invalid_input(self):
('# HELP a x\n# HELP a x\n# EOF\n'),
('# TYPE a untyped\n# TYPE a untyped\n# EOF\n'),
('# UNIT a_s s\n# UNIT a_s s\n# EOF\n'),
# Bad metadata.
('# FOO a x\n# EOF\n'),
# Bad metric names.
('0a 1\n# EOF\n'),
('a.b 1\n# EOF\n'),
Expand Down Expand Up @@ -706,6 +731,10 @@ def test_invalid_input(self):
'{a="23456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"} 1 1\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 1 # {} 0x1p-3\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 1 # {} 1 0x1p-3\n# EOF\n'),
('# TYPE a counter\na_total 1 1 # {id="a"} \n# EOF\n'),
('# TYPE a counter\na_total 1 1 # id="a"} 1\n# EOF\n'),
('# TYPE a counter\na_total 1 1 #id=" # "} 1\n# EOF\n'),
('# TYPE a counter\na_total 1 1 id=" # "} 1\n# EOF\n'),
# Exemplars on unallowed samples.
('# TYPE a histogram\na_sum 1 # {a="b"} 0.5\n# EOF\n'),
('# TYPE a gaugehistogram\na_sum 1 # {a="b"} 0.5\n# EOF\n'),
Expand Down Expand Up @@ -750,13 +779,18 @@ def test_invalid_input(self):
('# TYPE a summary\na_sum -1\n# EOF\n'),
('# TYPE a summary\na_count -1\n# EOF\n'),
('# TYPE a summary\na{quantile="0.5"} -1\n# EOF\n'),
# Bad info and stateset values.
('# TYPE a info\na_info{foo="bar"} 2\n# EOF\n'),
('# TYPE a stateset\na{a="bar"} 2\n# EOF\n'),
# Bad histograms.
('# TYPE a histogram\na_sum 1\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 0\n#a_sum 0\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 0\n#a_count 0\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 0\na_sum 0\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 0\na_count 0\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="-1"} 0\na_bucket{le="+Inf"} 0\na_sum 0\na_count 0\n# EOF\n'),
('# TYPE a gaugehistogram\na_gsum 1\n# EOF\n'),
('# TYPE a gaugehistogram\na_bucket{le="+Inf"} 0\na_gsum 0\n# EOF\n'),
('# TYPE a gaugehistogram\na_bucket{le="+Inf"} 0\na_gcount 0\n# EOF\n'),
('# TYPE a gaugehistogram\na_bucket{le="+Inf"} 1\na_gsum -1\na_gcount 1\n# EOF\n'),
('# TYPE a histogram\na_count 1\na_bucket{le="+Inf"} 0\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+Inf"} 0\na_count 1\n# EOF\n'),
('# TYPE a histogram\na_bucket{le="+INF"} 0\n# EOF\n'),
Expand Down