Skip to content

Commit 1bd08b7

Browse files
committed
Use rust to improve reading .db file performance
Signed-off-by: Chris Marchbanks <[email protected]>
1 parent b0a6f12 commit 1bd08b7

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

prometheus_client/multiprocess.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
from .samples import Sample
1111
from .utils import floatToGoString
1212

13+
_speedups = False
14+
try:
15+
import prometheus_client_python_speedups
16+
_speedups = True
17+
except:
18+
pass
19+
1320
try: # Python3
1421
FileNotFoundError
1522
except NameError: # Python >= 2.5
@@ -155,6 +162,14 @@ def _accumulate_metrics(metrics, accumulate):
155162

156163
def collect(self):
157164
files = glob.glob(os.path.join(self._path, '*.db'))
165+
if _speedups:
166+
metrics = prometheus_client_python_speedups.merge(files)
167+
native_metrics = []
168+
for metric in metrics:
169+
native_metric = Metric(metric.name, metric.documentation, metric.typ)
170+
native_metric.samples = [Sample(sample.name, sample.labels, sample.value) for sample in metric.samples]
171+
native_metrics.append(native_metric)
172+
return native_metrics
158173
return self.merge(files, accumulate=True)
159174

160175

tests/test_multiprocess.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import unittest
66
import warnings
77

8+
import pytest
9+
810
from prometheus_client import mmap_dict, values
911
from prometheus_client.core import (
1012
CollectorRegistry, Counter, Gauge, Histogram, Sample, Summary,
1113
)
14+
import prometheus_client.multiprocess as multiprocess
1215
from prometheus_client.multiprocess import (
1316
mark_process_dead, MultiProcessCollector,
1417
)
@@ -398,6 +401,61 @@ def test_remove_clear_warning(self):
398401
assert "Clearing labels has not been implemented" in str(w[-1].message)
399402

400403

404+
@pytest.fixture
405+
def tempdir():
406+
tempdir = tempfile.mkdtemp()
407+
os.environ['PROMETHEUS_MULTIPROC_DIR'] = tempdir
408+
values.ValueClass = MultiProcessValue(lambda: 123)
409+
yield tempdir
410+
del os.environ['PROMETHEUS_MULTIPROC_DIR']
411+
shutil.rmtree(tempdir)
412+
values.ValueClass = MutexValue
413+
414+
415+
@pytest.fixture
416+
def registry() -> CollectorRegistry:
417+
return CollectorRegistry()
418+
419+
420+
@pytest.fixture
421+
def collector(tempdir, registry) -> MultiProcessCollector:
422+
return MultiProcessCollector(registry)
423+
424+
425+
@pytest.fixture
426+
def no_speedup():
427+
tmp = multiprocess._speedups
428+
multiprocess._speedups = False
429+
yield tmp
430+
multiprocess._speedups = tmp
431+
432+
433+
def setup_benchmark():
434+
labels = {i: i for i in 'abcd'}
435+
for pid in range(1000):
436+
values.ValueClass = MultiProcessValue(lambda: pid)
437+
438+
c = Counter('c', 'help', labelnames=labels.keys(), registry=None)
439+
g = Gauge('g', 'help', labelnames=labels.keys(), registry=None)
440+
h = Histogram('h', 'help', labelnames=labels.keys(), registry=None)
441+
442+
c.labels(**labels).inc(1)
443+
g.labels(**labels).set(1)
444+
h.labels(**labels).observe(1)
445+
446+
447+
def test_native_collect_performance(benchmark, collector, no_speedup):
448+
setup_benchmark()
449+
benchmark(collector.collect)
450+
451+
452+
def test_speedup_collect_performance(benchmark, collector):
453+
if not multiprocess._speedups:
454+
pytest.skip("prometheus_client_python_speedups not installed")
455+
setup_benchmark()
456+
benchmark(collector.collect)
457+
458+
401459
class TestMmapedDict(unittest.TestCase):
402460
def setUp(self):
403461
fd, self.tempfile = tempfile.mkstemp()

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ envlist = coverage-clean,py{3.9,3.10,3.11,3.12,3.13,py3.9,3.9-nooptionals},cover
55
deps =
66
coverage
77
pytest
8+
pytest-benchmark
89
attrs
910
{py3.9,pypy3.9}: twisted
1011
# NOTE: Pinned due to https://github.com/prometheus/client_python/issues/1020
1112
py3.9: asgiref==3.7
1213
pypy3.9: asgiref==3.7
14+
py3.13: prometheus_client_python_speedups==0.1.0
1315
commands = coverage run --parallel -m pytest {posargs}
1416

1517
[testenv:py3.9-nooptionals]

0 commit comments

Comments
 (0)