from prometheus_client import parser
import requests
url = "http://localhost:12345/metrics"
text = requests.get(url).text
bytes_lines = []
for line in text.splitlines():
if line.startswith("traefik_router_requests_bytes_total"):
print(line)
bytes_lines.append(line)
traefik_router_requests_bytes_total{code="200",method="GET",protocol="http",router="prometheus@internal",service="prometheus@internal"} 0 traefik_router_requests_bytes_total{code="200",method="GET",protocol="http",router="route_api@file",service="api@internal"} 0 traefik_router_requests_bytes_total{code="200",method="GET",protocol="http",router="router__2F@file",service="service__2F@file"} 0 traefik_router_requests_bytes_total{code="200",method="GET",protocol="http",router="router__2Fuser_2Ftest_2F@file",service="service__2Fuser_2Ftest_2F@file"} 0 traefik_router_requests_bytes_total{code="200",method="GET",protocol="sse",router="router__2F@file",service="service__2F@file"} 0 traefik_router_requests_bytes_total{code="200",method="POST",protocol="http",router="router__2Fuser_2Ftest_2F@file",service="service__2Fuser_2Ftest_2F@file"} 10 traefik_router_requests_bytes_total{code="204",method="PUT",protocol="http",router="router__2Fuser_2Ftest_2F@file",service="service__2Fuser_2Ftest_2F@file"} 2287 traefik_router_requests_bytes_total{code="302",method="GET",protocol="http",router="router__2F@file",service="service__2F@file"} 0 traefik_router_requests_bytes_total{code="302",method="GET",protocol="http",router="router__2Fuser_2Ftest_2F@file",service="service__2Fuser_2Ftest_2F@file"} 0 traefik_router_requests_bytes_total{code="302",method="POST",protocol="http",router="router__2F@file",service="service__2F@file"} 91
metrics = list(parser.text_string_to_metric_families("\n".join(bytes_lines)))
from itertools import chain
from collections import defaultdict
sums = defaultdict(int)
for sample in chain(*[m.samples for m in metrics]):
sums[sample.labels['router']] += sample.value
sums
defaultdict(int, {'prometheus@internal': 0.0, 'route_api@file': 0.0, 'router__2F@file': 91.0, 'router__2Fuser_2Ftest_2F@file': 2297.0})
# We could use prometheus_client.parser.text_string_to_metric_families for this
# but this is likely quicker for what we need
import re
import requests
router_pat = re.compile(r'\brouter="([^"]+)"')
metric_name = "traefik_router_requests_bytes_total"
def fetch_router_bytes(url):
"""Fetch bytes per router via prometheus metrics"""
# TODO: async, auth
text = requests.get(url).text
prefix = metric_name + "{"
router_bytes = {}
for line in text.splitlines():
if not line.startswith(prefix):
continue
# metric_name, _, rest = line.partition("{")
labels, _, value_str = line.rpartition("}")
router_match = router_pat.search(labels)
if not router_match:
continue
router_name = router_match.group(1)
try:
value = float(value_str.strip())
except Exception:
continue
# there will be multiple samples per router
# e.g. by http status code, method, etc.
if router_name not in router_bytes:
router_bytes[router_name] = 0
router_bytes[router_name] += value
return router_bytes
def changed_since_before(before, after):
for key, value in after.items():
if key not in before:
yield key
elif value != before[key]:
yield key
before = fetch_router_bytes(url)
{'prometheus@internal': 0.0, 'route_api@file': 0.0, 'router__2F@file': 91.0, 'router__2Fuser_2Ftest_2F@file': 2297.0}
# go do something
after = fetch_router_bytes(url)
after
{'router__2Fuser_2Ftest_2F@file': 3437.0, 'prometheus@internal': 0.0, 'route_api@file': 0.0, 'router__2F@file': 91.0}
set(changed_since_before(before, after))
{'router__2Fuser_2Ftest_2F@file'}