Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion prometheus_client/multiprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import glob
import json
import os
import re
import warnings

from .metrics import Gauge
Expand All @@ -15,6 +16,11 @@
except NameError: # Python >= 2.5
FileNotFoundError = IOError

# Names of the files written by MultiProcessValue: the metric type, the
# multiprocess mode for gauges, then the process identifier.
_MULTIPROC_FILE_RE = re.compile(r'(?:counter|histogram|summary|gauge_(?:{}))_.+\.db'.format(
'|'.join(sorted(Gauge._MULTIPROC_MODES))))


class MultiProcessCollector:
"""Collector for files for multi-process mode."""
Expand Down Expand Up @@ -167,7 +173,12 @@ def _accumulate_metrics(metrics, accumulate):
return metrics.values()

def collect(self):
files = glob.glob(os.path.join(self._path, '*.db'))
# Only read files written by this library, so other .db files in the
# directory (for example a SQLite database) are not parsed as metrics.
files = [
f for f in glob.glob(os.path.join(self._path, '*.db'))
if _MULTIPROC_FILE_RE.fullmatch(os.path.basename(f))
]
return self.merge(files, accumulate=True)


Expand Down
22 changes: 22 additions & 0 deletions tests/test_multiprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,28 @@ def test_missing_gauge_file_during_merge(self):
os.path.join(self.tempdir, 'gauge_livesum_9999999.db'),
]))

def test_collect_ignores_foreign_db_files(self):
pid = 0
values.ValueClass = MultiProcessValue(lambda: pid)
c = Counter('c', 'help', registry=None)
g = Gauge('g', 'help', registry=None, multiprocess_mode='livesum')
c.inc(1)
g.set(2)
# Process identifiers do not have to be integers.
pid = 'worker_1'
c.inc(1)
g.set(3)

# Other .db files in the directory, some named like metric files.
# None of them can be parsed as a metric file.
sqlite_header = b'SQLite format 3\x00' + b'\x00' * 4080
for name in ('app.db', 'cache_0.db', 'counter.db', 'gauge_unknown_0.db'):
with open(os.path.join(self.tempdir, name), 'wb') as f:
f.write(sqlite_header)

self.assertEqual(2, self.registry.get_sample_value('c_total'))
self.assertEqual(5, self.registry.get_sample_value('g'))

def test_remove_clear_warning(self):
os.environ['PROMETHEUS_MULTIPROC_DIR'] = self.tempdir
with warnings.catch_warnings(record=True) as w:
Expand Down