import psycopg2
from psycopg2 import extensions
from psycopg2.extras import DictCursor
+from psycopg2 import OperationalError
from base import SimpleService
FROM (
SELECT
client_addr, client_hostname, state,
- ('x' || lpad(split_part(sent_location, '/', 1), 8, '0'))::bit(32)::bigint AS sent_xlog,
- ('x' || lpad(split_part(replay_location, '/', 1), 8, '0'))::bit(32)::bigint AS replay_xlog,
- ('x' || lpad(split_part(sent_location, '/', 2), 8, '0'))::bit(32)::bigint AS sent_offset,
- ('x' || lpad(split_part(replay_location, '/', 2), 8, '0'))::bit(32)::bigint AS replay_offset
+ ('x' || lpad(split_part(sent_location::text, '/', 1), 8, '0'))::bit(32)::bigint AS sent_xlog,
+ ('x' || lpad(split_part(replay_location::text, '/', 1), 8, '0'))::bit(32)::bigint AS replay_xlog,
+ ('x' || lpad(split_part(sent_location::text, '/', 2), 8, '0'))::bit(32)::bigint AS sent_offset,
+ ('x' || lpad(split_part(replay_location::text, '/', 2), 8, '0'))::bit(32)::bigint AS replay_offset
FROM pg_stat_replication
) AS s;
"""
self.table_stats = configuration.pop('table_stats', True)
self.index_stats = configuration.pop('index_stats', True)
self.configuration = configuration
- self.connection = None
+ self.connection = False
self.is_superuser = False
self.data = {}
self.databases = set()
params.update(self.configuration)
if not self.connection:
- self.connection = psycopg2.connect(**params)
- self.connection.set_isolation_level(extensions.ISOLATION_LEVEL_AUTOCOMMIT)
- self.connection.set_session(readonly=True)
+ try:
+ self.connection = psycopg2.connect(**params)
+ self.connection.set_isolation_level(extensions.ISOLATION_LEVEL_AUTOCOMMIT)
+ self.connection.set_session(readonly=True)
+ except OperationalError:
+ return False
+ return True
def check(self):
try:
self._create_definitions()
return True
except Exception as e:
- self.error(e)
+ self.error(str(e))
return False
def _discover_databases(self, cursor):
def _add_database_stat_chart(self, chart_template_name, database_name):
chart_template = CHARTS[chart_template_name]
- chart_name = "{}_{}".format(database_name, chart_template_name)
+ chart_name = "{0}_{1}".format(database_name, chart_template_name)
if chart_name not in self.order:
self.order.insert(0, chart_name)
name, title, units, family, context, chart_type = chart_template['options']
self.definitions[chart_name]['lines'] = []
for line in deepcopy(chart_template['lines']):
- line[0] = "{}_{}".format(database_name, line[0])
+ line[0] = "{0}_{1}".format(database_name, line[0])
self.definitions[chart_name]['lines'].append(line)
def _add_database_lock_chart(self, database_name):
- chart_name = "{}_locks".format(database_name)
+ chart_name = "{0}_locks".format(database_name)
if chart_name not in self.order:
self.order.insert(-1, chart_name)
self.definitions[chart_name] = dict(
)
for lock_type in LOCK_TYPES:
- lock_id = "{}_{}".format(database_name, lock_type)
+ lock_id = "{0}_{1}".format(database_name, lock_type)
label = re.sub("([a-z])([A-Z])", "\g<1> \g<2>", lock_type)
self.definitions[chart_name]['lines'].append([lock_id, label, 'absolute'])
def _get_data(self):
- self._connect()
-
- cursor = self.connection.cursor(cursor_factory=DictCursor)
- self.add_stats(cursor)
-
- cursor.close()
- return self.data
+ if self._connect():
+ cursor = self.connection.cursor(cursor_factory=DictCursor)
+ try:
+ self.add_stats(cursor)
+ except OperationalError:
+ if self.connection.closed == 2:
+ self.connection = False
+ cursor.close()
+ return None
+ else:
+ cursor.close()
+ return self.data
+ else:
+ return None
def add_stats(self, cursor):
self.add_database_stats(cursor)
cursor.execute(DATABASE)
for row in cursor:
database_name = row.get('database_name')
- self.data["{}_{}".format(database_name, 'db_stat_xact_commit')] = int(row.get('xact_commit', 0))
- self.data["{}_{}".format(database_name, 'db_stat_xact_rollback')] = int(row.get('xact_rollback', 0))
- self.data["{}_{}".format(database_name, 'db_stat_blks_read')] = int(row.get('blks_read', 0))
- self.data["{}_{}".format(database_name, 'db_stat_blks_hit')] = int(row.get('blks_hit', 0))
- self.data["{}_{}".format(database_name, 'db_stat_tup_returned')] = int(row.get('tup_returned', 0))
- self.data["{}_{}".format(database_name, 'db_stat_tup_fetched')] = int(row.get('tup_fetched', 0))
- self.data["{}_{}".format(database_name, 'db_stat_tup_inserted')] = int(row.get('tup_inserted', 0))
- self.data["{}_{}".format(database_name, 'db_stat_tup_updated')] = int(row.get('tup_updated', 0))
- self.data["{}_{}".format(database_name, 'db_stat_tup_deleted')] = int(row.get('tup_deleted', 0))
- self.data["{}_{}".format(database_name, 'db_stat_conflicts')] = int(row.get('conflicts', 0))
- self.data["{}_{}".format(database_name, 'db_stat_connections')] = int(row.get('connections', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_xact_commit')] = int(row.get('xact_commit', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_xact_rollback')] = int(row.get('xact_rollback', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_blks_read')] = int(row.get('blks_read', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_blks_hit')] = int(row.get('blks_hit', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_tup_returned')] = int(row.get('tup_returned', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_tup_fetched')] = int(row.get('tup_fetched', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_tup_inserted')] = int(row.get('tup_inserted', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_tup_updated')] = int(row.get('tup_updated', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_tup_deleted')] = int(row.get('tup_deleted', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_conflicts')] = int(row.get('conflicts', 0))
+ self.data["{0}_{1}".format(database_name, 'db_stat_connections')] = int(row.get('connections', 0))
def add_backend_stats(self, cursor):
cursor.execute(BACKENDS)
# zero out all current lock values
for database_name in self.databases:
for lock_type in LOCK_TYPES:
- self.data["{}_{}".format(database_name, lock_type)] = 0
+ self.data["{0}_{1}".format(database_name, lock_type)] = 0
# populate those that have current locks
for row in cursor:
database_name, lock_type, lock_count = row
- self.data["{}_{}".format(database_name, lock_type)] = lock_count
+ self.data["{0}_{1}".format(database_name, lock_type)] = lock_count
def add_wal_stats(self, cursor):
cursor.execute(ARCHIVE)