Skip to content

Commit 50c1761

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

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-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: 53 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,56 @@ 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+
@pytest.fixture
415+
def registry() -> CollectorRegistry:
416+
return CollectorRegistry()
417+
418+
@pytest.fixture
419+
def collector(tempdir, registry) -> MultiProcessCollector:
420+
return MultiProcessCollector(registry)
421+
422+
@pytest.fixture
423+
def no_speedup():
424+
tmp = multiprocess._speedups
425+
multiprocess._speedups = False
426+
yield tmp
427+
multiprocess._speedups = tmp
428+
429+
def setup_benchmark():
430+
labels = {i: i for i in 'abcd'}
431+
for pid in range(1000):
432+
values.ValueClass = MultiProcessValue(lambda: pid)
433+
434+
c = Counter('c', 'help', labelnames=labels.keys(), registry=None)
435+
g = Gauge('g', 'help', labelnames=labels.keys(), registry=None)
436+
h = Histogram('h', 'help', labelnames=labels.keys(), registry=None)
437+
438+
c.labels(**labels).inc(1)
439+
g.labels(**labels).set(1)
440+
h.labels(**labels).observe(1)
441+
442+
443+
def test_native_collect_performance(benchmark, collector, no_speedup):
444+
setup_benchmark()
445+
benchmark(collector.collect)
446+
447+
def test_speedup_collect_performance(benchmark, collector):
448+
if not multiprocess._speedups:
449+
pytest.skip("prometheus_client_python_speedups not installed")
450+
setup_benchmark()
451+
benchmark(collector.collect)
452+
453+
401454
class TestMmapedDict(unittest.TestCase):
402455
def setUp(self):
403456
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)