From f5f191a58ca0c163172353decc22617b356f8cfa Mon Sep 17 00:00:00 2001 From: Valentin Kuznetsov Date: Wed, 30 Aug 2017 19:18:27 +0300 Subject: [PATCH] initialize pid variable in master process --- prometheus_client/core.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/prometheus_client/core.py b/prometheus_client/core.py index 8e51ba25..7f60747d 100644 --- a/prometheus_client/core.py +++ b/prometheus_client/core.py @@ -395,6 +395,14 @@ def close(self): def _MultiProcessValue(_pidFunc=os.getpid): files = {} values = [] + + # 1. use dict instead of nonlocal keyword to support python 2.7 + # 2. pid needs to be evaluated here in a master process + # because some metrics can be initialized before fork and inhereted by childs + # as a result childs don't have a way to detect that files were opened + # by another process and will write to them. + pid = {'value': _pidFunc()} + # Use a single global lock when in multi-processing mode # as we presume this means there is no threading going on. # This avoids the need to also have mutexes in __MmapDict. @@ -413,7 +421,6 @@ def __init__(self, typ, metric_name, name, labelnames, labelvalues, multiprocess def __reset(self): - self._pid = _pidFunc() typ, metric_name, name, labelnames, labelvalues, multiprocess_mode = self._params if typ == 'gauge': file_prefix = typ + '_' + multiprocess_mode @@ -421,14 +428,17 @@ def __reset(self): file_prefix = typ if file_prefix not in files: filename = os.path.join( - os.environ['prometheus_multiproc_dir'], '{0}_{1}.db'.format(file_prefix, self._pid)) + os.environ['prometheus_multiproc_dir'], '{0}_{1}.db'.format(file_prefix, pid['value'])) files[file_prefix] = _MmapedDict(filename) self._file = files[file_prefix] self._key = json.dumps((metric_name, name, labelnames, labelvalues)) self._value = self._file.read_value(self._key) def __check_for_pid_change(self): - if self._pid != _pidFunc(): + actual_pid = _pidFunc() + + if pid['value'] != actual_pid: + pid['value'] = actual_pid # There has been a fork(), reset all the values. for f in files.values(): f.close()