From a6d3f5f753340d89b1b4692dc8276e941fb46084 Mon Sep 17 00:00:00 2001 From: Ilya Anashkin Date: Fri, 23 Sep 2022 16:32:19 +0300 Subject: [PATCH 1/2] Improve cyclomatic v.1 --- after.txt | Bin 0 -> 4922 bytes prometheus_client/exposition.py | 35 ++++++++++++------------ prometheus_client/metrics_core.py | 21 +++++++++----- prometheus_client/openmetrics/parser.py | 27 ++++++++++-------- 4 files changed, 48 insertions(+), 35 deletions(-) create mode 100644 after.txt diff --git a/after.txt b/after.txt new file mode 100644 index 0000000000000000000000000000000000000000..b51ecf44ac87929c9493aac7762ef9ee7d3c186e GIT binary patch literal 4922 zcmbuDTW=ay6ovP5rTzy$I#Pqo&6mE_j+{Ic$x0&iCDI53HYi{yki_nfZ@a#;=fGSJ z_1G1H8HSmC*4}IF%i*8DSGKmLEo@?2o9gqMZ7j2q&26S{54!rr#yT76uC)#Iony;Z z_GCZXPj-~Q20C8Yx&3NAon6b$gPz&S%2HKt?Pj3!umpl zU-u!_#D@q^6qR{?w$b+#mKb*|_2nJDVJQm?V&Oiw@I%L^l8y69j2+F{F3Ru^Yu^K7 zumoQ)pUJnBUheeUS}Fp45$$PZr7Qi~v+fS-O~Tqotvc3AA5YdZ+WbUYWcchD<< zJrRXP$Y3HqQ9Op>m>K?zLWXa5v2goQ0WassRmeJZwuo~_IszrCucIvTcO7sO?{Xfb ze0P?rkv&wk%09-NB!+1vxt)pqDYj$fJ8Xk$7wib?_Q3RD4rhV`v0xd zjB~2SO3@(a$@eW6n!nIpvF5~z@=m@V2d&rpVkfMQ{+qA>Uw)xRQfru>B8yjn#kN#jW|0+oso~QK+Q@74E zNNw5A7*Uz!oQbh@mb{0dswO@ZBN}rs+5>T0ohDYxCYU4QO|DXEXr`GoD!RB{%&R60 zehV4E%vR@)Tw)J{&v(k4rB>V8XC2?`{V8zHEPSuuUzantQq4>Xz`HN{^vQCnYbc|R zh{&C)N;=o?EB9X(tnnYrR|w3%kc+ZQRJ; zm+X!r4^8$)=#{y_^b!RJOfKutFBr9Z6rT zJCQXqAkHV9aL=(M-2j|sjor=77*@tCuM8>1S+3!91|L+ z6OQCPip3)PxmE7n;f`BGROIKsyK8jq-em?>7m6{B9R+OR_u z$gp@0yFOXQy?L|#OugCf2tMbQZz{Ix^}8jE%*jkrTl-z#qMDqM@^ryJNBj?Pq`RoH zut`Tc))}bX(#C$#HTK8F|C0QwSC*-s9qaBlx{vvW-tc693B_2olvRGq|HT-FihCsc m{M+TRd<-goQtbEtKb`2g3n4p^a=Uu>^&%I$y4u%gRMfu$nC`j& literal 0 HcmV?d00001 diff --git a/prometheus_client/exposition.py b/prometheus_client/exposition.py index 345b247d..c5e9aeae 100644 --- a/prometheus_client/exposition.py +++ b/prometheus_client/exposition.py @@ -175,6 +175,22 @@ class TmpServer(ThreadingWSGIServer): start_http_server = start_wsgi_server +def _convert_into_prometheus_format(mname, mtype): + # Munging from OpenMetrics into Prometheus format. + if mtype == 'counter': + mname = mname + '_total' + elif mtype == 'info': + mname = mname + '_info' + mtype = 'gauge' + elif mtype == 'stateset': + mtype = 'gauge' + elif mtype == 'gaugehistogram': + # A gauge histogram is really a gauge, + # but this captures the structure better. + mtype = 'histogram' + elif mtype == 'unknown': + mtype = 'untyped' + return mname, mtype def generate_latest(registry: CollectorRegistry = REGISTRY) -> bytes: """Returns the metrics from the registry in latest text format as a string.""" @@ -196,23 +212,8 @@ def sample_line(line): output = [] for metric in registry.collect(): try: - mname = metric.name - mtype = metric.type - # Munging from OpenMetrics into Prometheus format. - if mtype == 'counter': - mname = mname + '_total' - elif mtype == 'info': - mname = mname + '_info' - mtype = 'gauge' - elif mtype == 'stateset': - mtype = 'gauge' - elif mtype == 'gaugehistogram': - # A gauge histogram is really a gauge, - # but this captures the structure better. - mtype = 'histogram' - elif mtype == 'unknown': - mtype = 'untyped' - + mname, mtype = _convert_into_prometheus_format(metric.name, metric.type) + output.append('# HELP {} {}\n'.format( mname, metric.documentation.replace('\\', r'\\').replace('\n', r'\n'))) output.append(f'# TYPE {mname} {mtype}\n') diff --git a/prometheus_client/metrics_core.py b/prometheus_client/metrics_core.py index 77b3e446..f1af4cfa 100644 --- a/prometheus_client/metrics_core.py +++ b/prometheus_client/metrics_core.py @@ -121,10 +121,12 @@ def __init__(self, if name.endswith('_total'): name = name[:-6] Metric.__init__(self, name, documentation, 'counter', unit) - if labels is not None and value is not None: - raise ValueError('Can only specify at most one of value and labels.') + if labels is None: labels = [] + elif value is not None: + raise ValueError('Can only specify at most one of value and labels.') + self._labelnames = tuple(labels) if value is not None: self.add_metric([], value, created) @@ -196,10 +198,12 @@ def __init__(self, Metric.__init__(self, name, documentation, 'summary', unit) if (sum_value is None) != (count_value is None): raise ValueError('count_value and sum_value must be provided together.') - if labels is not None and count_value is not None: - raise ValueError('Can only specify at most one of value and labels.') - if labels is None: + + if (labels is None): labels = [] + elif count_value is not None: + raise ValueError('Can only specify at most one of value and labels.') + self._labelnames = tuple(labels) # The and clause is necessary only for typing, the above ValueError will raise if only one is set. if count_value is not None and sum_value is not None: @@ -238,12 +242,15 @@ def __init__(self, unit: str = '', ): Metric.__init__(self, name, documentation, 'histogram', unit) + if sum_value is not None and buckets is None: raise ValueError('sum value cannot be provided without buckets.') - if labels is not None and buckets is not None: - raise ValueError('Can only specify at most one of buckets and labels.') + if labels is None: labels = [] + elif buckets is not None: + raise ValueError('Can only specify at most one of buckets and labels.') + self._labelnames = tuple(labels) if buckets is not None: self.add_metric([], buckets, sum_value) diff --git a/prometheus_client/openmetrics/parser.py b/prometheus_client/openmetrics/parser.py index fc25f080..d05b9581 100644 --- a/prometheus_client/openmetrics/parser.py +++ b/prometheus_client/openmetrics/parser.py @@ -390,17 +390,22 @@ def _check_histogram(samples, name): def do_checks(): if bucket != float('+Inf'): raise ValueError("+Inf bucket missing: " + name) - if count is not None and value != count: - raise ValueError("Count does not match +Inf value: " + name) - if has_sum and count is None: - raise ValueError("_count must be present if _sum is present: " + name) - if has_gsum and count is None: - raise ValueError("_gcount must be present if _gsum is present: " + name) - if not (has_sum or has_gsum) and count is not None: - raise ValueError("_sum/_gsum must be present if _count is present: " + name) - if has_negative_buckets and has_sum: - raise ValueError("Cannot have _sum with negative buckets: " + name) - if not has_negative_buckets and has_negative_gsum: + + if count is not None: + if value != count: + raise ValueError("Count does not match +Inf value: " + name) + if not (has_sum or has_gsum): + raise ValueError("_sum/_gsum must be present if _count is present: " + name) + else: + if has_sum: + raise ValueError("_count must be present if _sum is present: " + name) + if has_gsum: + raise ValueError("_gcount must be present if _gsum is present: " + name) + + if has_negative_buckets: + if has_sum: + raise ValueError("Cannot have _sum with negative buckets: " + name) + elif has_negative_gsum: raise ValueError("Cannot have negative _gsum with non-negative buckets: " + name) for s in samples: From 6425401c2595b3b3aa655e806902e8c84a6c9757 Mon Sep 17 00:00:00 2001 From: Ilya Anashkin Date: Fri, 23 Sep 2022 16:54:16 +0300 Subject: [PATCH 2/2] Improve cyclomatic v.2 --- after.txt | Bin 4922 -> 0 bytes prometheus_client/exposition.py | 34 ++++++++++++------------ prometheus_client/openmetrics/parser.py | 27 ++++++++----------- prometheus_client/registry.py | 5 ++-- 4 files changed, 30 insertions(+), 36 deletions(-) delete mode 100644 after.txt diff --git a/after.txt b/after.txt deleted file mode 100644 index b51ecf44ac87929c9493aac7762ef9ee7d3c186e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4922 zcmbuDTW=ay6ovP5rTzy$I#Pqo&6mE_j+{Ic$x0&iCDI53HYi{yki_nfZ@a#;=fGSJ z_1G1H8HSmC*4}IF%i*8DSGKmLEo@?2o9gqMZ7j2q&26S{54!rr#yT76uC)#Iony;Z z_GCZXPj-~Q20C8Yx&3NAon6b$gPz&S%2HKt?Pj3!umpl zU-u!_#D@q^6qR{?w$b+#mKb*|_2nJDVJQm?V&Oiw@I%L^l8y69j2+F{F3Ru^Yu^K7 zumoQ)pUJnBUheeUS}Fp45$$PZr7Qi~v+fS-O~Tqotvc3AA5YdZ+WbUYWcchD<< zJrRXP$Y3HqQ9Op>m>K?zLWXa5v2goQ0WassRmeJZwuo~_IszrCucIvTcO7sO?{Xfb ze0P?rkv&wk%09-NB!+1vxt)pqDYj$fJ8Xk$7wib?_Q3RD4rhV`v0xd zjB~2SO3@(a$@eW6n!nIpvF5~z@=m@V2d&rpVkfMQ{+qA>Uw)xRQfru>B8yjn#kN#jW|0+oso~QK+Q@74E zNNw5A7*Uz!oQbh@mb{0dswO@ZBN}rs+5>T0ohDYxCYU4QO|DXEXr`GoD!RB{%&R60 zehV4E%vR@)Tw)J{&v(k4rB>V8XC2?`{V8zHEPSuuUzantQq4>Xz`HN{^vQCnYbc|R zh{&C)N;=o?EB9X(tnnYrR|w3%kc+ZQRJ; zm+X!r4^8$)=#{y_^b!RJOfKutFBr9Z6rT zJCQXqAkHV9aL=(M-2j|sjor=77*@tCuM8>1S+3!91|L+ z6OQCPip3)PxmE7n;f`BGROIKsyK8jq-em?>7m6{B9R+OR_u z$gp@0yFOXQy?L|#OugCf2tMbQZz{Ix^}8jE%*jkrTl-z#qMDqM@^ryJNBj?Pq`RoH zut`Tc))}bX(#C$#HTK8F|C0QwSC*-s9qaBlx{vvW-tc693B_2olvRGq|HT-FihCsc m{M+TRd<-goQtbEtKb`2g3n4p^a=Uu>^&%I$y4u%gRMfu$nC`j& diff --git a/prometheus_client/exposition.py b/prometheus_client/exposition.py index c5e9aeae..c676d51c 100644 --- a/prometheus_client/exposition.py +++ b/prometheus_client/exposition.py @@ -175,22 +175,6 @@ class TmpServer(ThreadingWSGIServer): start_http_server = start_wsgi_server -def _convert_into_prometheus_format(mname, mtype): - # Munging from OpenMetrics into Prometheus format. - if mtype == 'counter': - mname = mname + '_total' - elif mtype == 'info': - mname = mname + '_info' - mtype = 'gauge' - elif mtype == 'stateset': - mtype = 'gauge' - elif mtype == 'gaugehistogram': - # A gauge histogram is really a gauge, - # but this captures the structure better. - mtype = 'histogram' - elif mtype == 'unknown': - mtype = 'untyped' - return mname, mtype def generate_latest(registry: CollectorRegistry = REGISTRY) -> bytes: """Returns the metrics from the registry in latest text format as a string.""" @@ -212,7 +196,23 @@ def sample_line(line): output = [] for metric in registry.collect(): try: - mname, mtype = _convert_into_prometheus_format(metric.name, metric.type) + mname = metric.name + mtype = metric.type + + # Munging from OpenMetrics into Prometheus format. + if mtype == 'counter': + mname = mname + '_total' + elif mtype == 'info': + mname = mname + '_info' + mtype = 'gauge' + elif mtype == 'stateset': + mtype = 'gauge' + elif mtype == 'gaugehistogram': + # A gauge histogram is really a gauge, + # but this captures the structure better. + mtype = 'histogram' + elif mtype == 'unknown': + mtype = 'untyped' output.append('# HELP {} {}\n'.format( mname, metric.documentation.replace('\\', r'\\').replace('\n', r'\n'))) diff --git a/prometheus_client/openmetrics/parser.py b/prometheus_client/openmetrics/parser.py index d05b9581..fc25f080 100644 --- a/prometheus_client/openmetrics/parser.py +++ b/prometheus_client/openmetrics/parser.py @@ -390,22 +390,17 @@ def _check_histogram(samples, name): def do_checks(): if bucket != float('+Inf'): raise ValueError("+Inf bucket missing: " + name) - - if count is not None: - if value != count: - raise ValueError("Count does not match +Inf value: " + name) - if not (has_sum or has_gsum): - raise ValueError("_sum/_gsum must be present if _count is present: " + name) - else: - if has_sum: - raise ValueError("_count must be present if _sum is present: " + name) - if has_gsum: - raise ValueError("_gcount must be present if _gsum is present: " + name) - - if has_negative_buckets: - if has_sum: - raise ValueError("Cannot have _sum with negative buckets: " + name) - elif has_negative_gsum: + if count is not None and value != count: + raise ValueError("Count does not match +Inf value: " + name) + if has_sum and count is None: + raise ValueError("_count must be present if _sum is present: " + name) + if has_gsum and count is None: + raise ValueError("_gcount must be present if _gsum is present: " + name) + if not (has_sum or has_gsum) and count is not None: + raise ValueError("_sum/_gsum must be present if _count is present: " + name) + if has_negative_buckets and has_sum: + raise ValueError("Cannot have _sum with negative buckets: " + name) + if not has_negative_buckets and has_negative_gsum: raise ValueError("Cannot have negative _gsum with non-negative buckets: " + name) for s in samples: diff --git a/prometheus_client/registry.py b/prometheus_client/registry.py index 694e4bd8..e580f86e 100644 --- a/prometheus_client/registry.py +++ b/prometheus_client/registry.py @@ -63,10 +63,9 @@ def _get_names(self, collector): except AttributeError: pass # Otherwise, if auto describe is enabled use the collect function. - if not desc_func and self._auto_describe: - desc_func = collector.collect - if not desc_func: + if self._auto_describe: + desc_func = collector.collect return [] result = []