about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/prometheus_client/bridge
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/prometheus_client/bridge')
-rw-r--r--.venv/lib/python3.12/site-packages/prometheus_client/bridge/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/prometheus_client/bridge/graphite.py94
2 files changed, 94 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/prometheus_client/bridge/__init__.py b/.venv/lib/python3.12/site-packages/prometheus_client/bridge/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/prometheus_client/bridge/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/prometheus_client/bridge/graphite.py b/.venv/lib/python3.12/site-packages/prometheus_client/bridge/graphite.py
new file mode 100644
index 00000000..8cadbedc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/prometheus_client/bridge/graphite.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+import logging
+import re
+import socket
+import threading
+import time
+from timeit import default_timer
+from typing import Callable, Tuple
+
+from ..registry import CollectorRegistry, REGISTRY
+
+# Roughly, have to keep to what works as a file name.
+# We also remove periods, so labels can be distinguished.
+
+_INVALID_GRAPHITE_CHARS = re.compile(r"[^a-zA-Z0-9_-]")
+
+
+def _sanitize(s):
+    return _INVALID_GRAPHITE_CHARS.sub('_', s)
+
+
+class _RegularPush(threading.Thread):
+    def __init__(self, pusher, interval, prefix):
+        super().__init__()
+        self._pusher = pusher
+        self._interval = interval
+        self._prefix = prefix
+
+    def run(self):
+        wait_until = default_timer()
+        while True:
+            while True:
+                now = default_timer()
+                if now >= wait_until:
+                    # May need to skip some pushes.
+                    while wait_until < now:
+                        wait_until += self._interval
+                    break
+                # time.sleep can return early.
+                time.sleep(wait_until - now)
+            try:
+                self._pusher.push(prefix=self._prefix)
+            except OSError:
+                logging.exception("Push failed")
+
+
+class GraphiteBridge:
+    def __init__(self,
+                 address: Tuple[str, int],
+                 registry: CollectorRegistry = REGISTRY,
+                 timeout_seconds: float = 30,
+                 _timer: Callable[[], float] = time.time,
+                 tags: bool = False,
+                 ):
+        self._address = address
+        self._registry = registry
+        self._tags = tags
+        self._timeout = timeout_seconds
+        self._timer = _timer
+
+    def push(self, prefix: str = '') -> None:
+        now = int(self._timer())
+        output = []
+
+        prefixstr = ''
+        if prefix:
+            prefixstr = prefix + '.'
+
+        for metric in self._registry.collect():
+            for s in metric.samples:
+                if s.labels:
+                    if self._tags:
+                        sep = ';'
+                        fmt = '{0}={1}'
+                    else:
+                        sep = '.'
+                        fmt = '{0}.{1}'
+                    labelstr = sep + sep.join(
+                        [fmt.format(
+                            _sanitize(k), _sanitize(v))
+                            for k, v in sorted(s.labels.items())])
+                else:
+                    labelstr = ''
+                output.append(f'{prefixstr}{_sanitize(s.name)}{labelstr} {float(s.value)} {now}\n')
+
+        conn = socket.create_connection(self._address, self._timeout)
+        conn.sendall(''.join(output).encode('ascii'))
+        conn.close()
+
+    def start(self, interval: float = 60.0, prefix: str = '') -> None:
+        t = _RegularPush(self, interval, prefix)
+        t.daemon = True
+        t.start()