]> arthur.barton.de Git - netdata.git/blobdiff - python.d/postgres.chart.py
isc_dhcpd_plugin: python 2.6 compatibility fix
[netdata.git] / python.d / postgres.chart.py
index cd99bdfc9d2cb3fe90db24ef6e73ef3b85eba447..eb3224bf0b3da471664c583e83052858ec7e1283 100644 (file)
@@ -7,8 +7,8 @@ from copy import deepcopy
 
 import psycopg2
 from psycopg2 import extensions
-from psycopg2._psycopg import DatabaseError
 from psycopg2.extras import DictCursor
+from psycopg2 import OperationalError
 
 from base import SimpleService
 
@@ -89,10 +89,10 @@ SELECT
 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;
 """
@@ -194,7 +194,7 @@ class Service(SimpleService):
         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()
@@ -203,18 +203,24 @@ class Service(SimpleService):
         params = dict(user='postgres',
                       database=None,
                       password=None,
-                      host='localhost',
+                      host=None,
                       port=5432)
         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._connect()
+            if not self._connect():
+                self.error('Can\'t connect to %s' % str(self.configuration))
+                return False
             cursor = self.connection.cursor()
             self._discover_databases(cursor)
             self._check_if_superuser(cursor)
@@ -222,10 +228,8 @@ class Service(SimpleService):
 
             self._create_definitions()
             return True
-        except DatabaseError:
-            return False
         except Exception as e:
-            self.error(e)
+            self.error(str(e))
             return False
 
     def _discover_databases(self, cursor):
@@ -251,7 +255,7 @@ class Service(SimpleService):
 
     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']
@@ -268,11 +272,11 @@ class Service(SimpleService):
 
             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(
@@ -289,18 +293,24 @@ class Service(SimpleService):
             )
 
             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:
+                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)
@@ -321,17 +331,17 @@ class Service(SimpleService):
         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)
@@ -358,12 +368,12 @@ class Service(SimpleService):
         # 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)