determine influxdb version on each request if required

When determining influxdb version, the code relies on results of
SHOW DIAGNOSTICS. It is unknown when version banner appeared in
the output of the query, so in case we can't find it there the
version is assumed to be < 0.10.

However, it is incorrect to assume that any error means that
the version is < 0.10. Sometimes error means that influxdb is not
ready to serve connections yet. Ignoring these errors leads to
incorrect state of the application.

Try determining version of influxdb on application startup.
If it fails, retry the attempt on each request.

Change-Id: I813201e0410150cb9c81117232ac3986423e7503
Story: 2001313
Task: 5867
This commit is contained in:
Boris Bobrov 2017-12-05 17:24:43 +01:00 committed by Boris Bobrov
parent ec5a0f2607
commit 6e13c33c83
1 changed files with 47 additions and 21 deletions

View File

@ -43,43 +43,69 @@ class MetricsRepository(metrics_repository.AbstractMetricsRepository):
self.conf.influxdb.ip_address, self.conf.influxdb.port,
self.conf.influxdb.user, self.conf.influxdb.password,
self.conf.influxdb.database_name)
self._init_serie_builders()
self._version = None
self._init_version()
except Exception as ex:
LOG.exception(ex)
raise exceptions.RepositoryException(ex)
def _init_serie_builders(self):
self._serie_builders_version_map = {
'to_0.11.0': (self._build_serie_dimension_values_to_v0_11_0,
self._build_serie_metric_list_to_v0_11_0),
'from_0.11.0': (self._build_serie_dimension_values_from_v0_11_0,
self._build_serie_metric_list_from_v0_11_0)}
def _build_serie_dimension_values(self, *args, **kwargs):
if self._version:
f = self._serie_builders_version_map[self._version][0]
return f(*args, **kwargs)
else:
self._init_version()
if self._version:
f = self._serie_builders_version_map[self._version][0]
return f(*args, **kwargs)
LOG.error('influxdb is not available, giving up')
raise exceptions.RepositoryException('Repository not available')
def _build_serie_metric_list(self, *args, **kwargs):
if self._version:
f = self._serie_builders_version_map[self._version][1]
return f(*args, **kwargs)
else:
self._init_version()
if self._version:
f = self._serie_builders_version_map[self._version][1]
return f(*args, **kwargs)
LOG.error('influxdb is not available, giving up')
raise exceptions.RepositoryException('Repository not available')
def _init_version(self):
'''Initializes functions for serie builders that are specific to different versions
of InfluxDB.
In InfluxDB v0.11.0 the SHOW SERIES output changed. See,
https://github.com/influxdata/influxdb/blob/master/CHANGELOG.md#v0110-2016-03-22
'''
try:
influxdb_version = self._get_influxdb_version()
if influxdb_version < version.StrictVersion('0.11.0'):
self._init_serie_builders_to_v0_11_0()
self._version = 'to_0.11.0'
LOG.info('Initialize InfluxDB serie builders < v0.11.0')
else:
self._init_serie_builders_from_v0_11_0()
self._version = 'from_0.11.0'
LOG.info('Initialize InfluxDB serie builders >= v0.11.0')
except (requests.exceptions.ConnectionError,
requests.exceptions.ConnectTimeout):
# these errors mean that the backend is not ready yet, we shall try
# to build series on each request
LOG.warning('influxdb is not ready yet')
except Exception as ex:
LOG.exception(ex)
# Initialize the serie builders to v0_11_0. Not sure when SHOW DIAGNOSTICS added
# support for a version string so to address backward compatibility initialize
# InfluxDB serie builders < v0.11.0
self._init_serie_builders_to_v0_11_0()
def _init_serie_builders_to_v0_11_0(self):
'''Initialize function for InfluxDB serie builders < v0.11.0
'''
LOG.info('Initialize InfluxDB serie builders < v0.11.0')
self._build_serie_dimension_values = self._build_serie_dimension_values_to_v0_11_0
self._build_serie_metric_list = self._build_serie_metric_list_to_v0_11_0
def _init_serie_builders_from_v0_11_0(self):
'''Initialize function for InfluxDB serie builders >= v0.11.0.
In InfluxDB v0.11.0 the SHOW SERIES output changed. See,
https://github.com/influxdata/influxdb/blob/master/CHANGELOG.md#v0110-2016-03-22
'''
LOG.info('Initialize InfluxDB serie builders >= v0.11.0')
self._build_serie_dimension_values = self._build_serie_dimension_values_from_v0_11_0
self._build_serie_metric_list = self._build_serie_metric_list_from_v0_11_0
self._version = 'to_0.11.0'
LOG.info('Initialize InfluxDB serie builders < v0.11.0')
def _get_influxdb_version(self):
'''If Version found in the result set, return the InfluxDB Version,