postgres plugin improvements
Costa Tsaousis (ktsaou) committed
Oct 30, 2016 at 02:05 UTC
66c57eb5b35d456cc0f7a61eeddba6e8441b9e74
6 files changed
+123
-99
conf.d/Makefile.am
+1
@@ -41,6 +41,7 @@ dist_pythonconfig_DATA = \
41
python.d/nginx_log.conf \
42
python.d/phpfpm.conf \
43
python.d/postfix.conf \
44
+ python.d/postgres.conf \
45
python.d/redis.conf \
46
python.d/retroshare.conf \
47
python.d/sensors.conf \
conf.d/python.d/postgres.conf
+35
-12
@@ -55,22 +55,45 @@
55
# retries: 5 # the JOB's number of restoration attempts
56
#
57
# A single connection is required in order to pull statistics.
58
+#
59
# Connections can be configured with the following options:
59
-# name : example_database_job_name
60
-# database : example_db_name
61
-# user : example_user
62
-# password : example_pass
63
-# host: localhost
64
-# port: 5432
60
+#
61
+# database : 'example_db_name'
62
+# user : 'example_user'
63
+# password : 'example_pass'
64
+# host : 'localhost'
65
+# port : 5432
66
#
67
# Additionally, the following options allow selective disabling of charts
68
#
68
-# table_stats: false
69
-# index_stats: false
69
+# table_stats : false
70
+# index_stats : false
71
+#
72
# ----------------------------------------------------------------------
73
72
-# Attempt to connect via the Unix socket as the postgres user.
73
-unix_socket_superuser:
74
- name : postgres
75
- database : postgres
74
+socket:
75
+ name : 'local'
76
+ user : 'postgres'
77
+ database : 'postgres'
78
+
79
+tcp:
80
+ name : 'local'
81
+ database : 'postgres'
82
+ user : 'postgres'
83
+ host : 'localhost'
84
+ port : 5432
85
+
86
+tcpipv4:
87
+ name : 'local'
88
+ database : 'postgres'
89
+ user : 'postgres'
90
+ host : '127.0.0.1'
91
+ port : 5432
92
+
93
+tcpipv6:
94
+ name : 'local'
95
+ database : 'postgres'
96
+ user : 'postgres'
97
+ host : '::1'
98
+ port : 5432
99
python.d/Makefile.am
+1
@@ -22,6 +22,7 @@ dist_python_SCRIPTS = \
22
nginx_log.chart.py \
23
phpfpm.chart.py \
24
postfix.chart.py \
25
+ postgres.chart.py \
26
redis.chart.py \
27
retroshare.chart.py \
28
sensors.chart.py \
python.d/postgres.chart.py
+69
-84
@@ -113,74 +113,74 @@ ORDER = ['db_stat_transactions', 'db_stat_tuple_read', 'db_stat_tuple_returned',
113
114
CHARTS = {
115
'db_stat_transactions': {
116
- 'options': [None, ' Transactions', 'Count', ' database statistics', '.db_stat_transactions', 'line'],
116
+ 'options': [None, 'Transactions on db', 'transactions/s', 'db statistics', 'postgres.db_stat_transactions', 'line'],
117
'lines': [
118
- ['db_stat_xact_commit', 'Committed', 'absolute'],
119
- ['db_stat_xact_rollback', 'Rolled Back', 'absolute']
118
+ ['db_stat_xact_commit', 'committed', 'incremental'],
119
+ ['db_stat_xact_rollback', 'rolled back', 'incremental']
120
]},
121
'db_stat_connections': {
122
- 'options': [None, ' Connections', 'Count', ' database statistics', '.db_stat_connections', 'line'],
122
+ 'options': [None, 'Current connections to db', 'count', 'db statistics', 'postgres.db_stat_connections', 'line'],
123
'lines': [
124
- ['db_stat_connections', 'Connections', 'absolute']
124
+ ['db_stat_connections', 'connections', 'absolute']
125
]},
126
'db_stat_tuple_read': {
127
- 'options': [None, ' Tuple read', 'Count', ' database statistics', '.db_stat_tuple_read', 'line'],
127
+ 'options': [None, 'Tuple reads from db', 'reads/s', 'db statistics', 'postgres.db_stat_tuple_read', 'line'],
128
'lines': [
129
- ['db_stat_blks_read', 'Disk', 'absolute'],
130
- ['db_stat_blks_hit', 'Cache', 'absolute']
129
+ ['db_stat_blks_read', 'disk', 'incremental'],
130
+ ['db_stat_blks_hit', 'cache', 'incremental']
131
]},
132
'db_stat_tuple_returned': {
133
- 'options': [None, ' Tuple returned', 'Count', ' database statistics', '.db_stat_tuple_returned', 'line'],
133
+ 'options': [None, 'Tuples returned from db', 'tuples/s', 'db statistics', 'postgres.db_stat_tuple_returned', 'line'],
134
'lines': [
135
- ['db_stat_tup_returned', 'Sequential', 'absolute'],
136
- ['db_stat_tup_fetched', 'Bitmap', 'absolute']
135
+ ['db_stat_tup_returned', 'sequential', 'incremental'],
136
+ ['db_stat_tup_fetched', 'bitmap', 'incremental']
137
]},
138
'db_stat_tuple_write': {
139
- 'options': [None, ' Tuple write', 'Count', ' database statistics', '.db_stat_tuple_write', 'line'],
139
+ 'options': [None, 'Tuples written to db', 'writes/s', 'db statistics', 'postgres.db_stat_tuple_write', 'line'],
140
'lines': [
141
- ['db_stat_tup_inserted', 'Inserted', 'absolute'],
142
- ['db_stat_tup_updated', 'Updated', 'absolute'],
143
- ['db_stat_tup_deleted', 'Deleted', 'absolute'],
144
- ['db_stat_conflicts', 'Conflicts', 'absolute']
141
+ ['db_stat_tup_inserted', 'inserted', 'incremental'],
142
+ ['db_stat_tup_updated', 'updated', 'incremental'],
143
+ ['db_stat_tup_deleted', 'deleted', 'incremental'],
144
+ ['db_stat_conflicts', 'conflicts', 'incremental']
145
]},
146
'backend_process': {
147
- 'options': [None, 'Backend processes', 'Count', 'Backend processes', 'postgres.backend_process', 'line'],
147
+ 'options': [None, 'Current Backend Processes', 'processes', 'backend processes', 'postgres.backend_process', 'line'],
148
'lines': [
149
- ['backend_process_active', 'Active', 'absolute'],
150
- ['backend_process_idle', 'Idle', 'absolute']
149
+ ['backend_process_active', 'active', 'absolute'],
150
+ ['backend_process_idle', 'idle', 'absolute']
151
]},
152
'index_count': {
153
- 'options': [None, 'Total index', 'Count', 'Index', 'postgres.index_count', 'line'],
153
+ 'options': [None, 'Total indexes', 'index', 'indexes', 'postgres.index_count', 'line'],
154
'lines': [
155
- ['index_count', 'Total index', 'absolute']
155
+ ['index_count', 'total', 'absolute']
156
]},
157
'index_size': {
158
- 'options': [None, 'Index size', 'MB', 'Index', 'postgres.index_size', 'line'],
158
+ 'options': [None, 'Indexes size', 'MB', 'indexes', 'postgres.index_size', 'line'],
159
'lines': [
160
- ['index_size', 'Size', 'absolute', 1, 1024 * 1024]
160
+ ['index_size', 'size', 'absolute', 1, 1024 * 1024]
161
]},
162
'table_count': {
163
- 'options': [None, 'Total table', 'Count', 'Table', 'postgres.table_count', 'line'],
163
+ 'options': [None, 'Total Tables', 'tables', 'tables', 'postgres.table_count', 'line'],
164
'lines': [
165
- ['table_count', 'Total table', 'absolute']
165
+ ['table_count', 'total', 'absolute']
166
]},
167
'table_size': {
168
- 'options': [None, 'Table size', 'MB', 'Table', 'postgres.table_size', 'line'],
168
+ 'options': [None, 'Tables size', 'MB', 'tables', 'postgres.table_size', 'line'],
169
'lines': [
170
- ['table_size', 'Size', 'absolute', 1, 1024 * 1024]
170
+ ['table_size', 'size', 'absolute', 1, 1024 * 1024]
171
]},
172
'wal': {
173
- 'options': [None, 'WAL stats', 'Files', 'WAL', 'postgres.wal', 'line'],
173
+ 'options': [None, 'Write-Ahead Logging Statistics', 'files/s', 'write ahead log', 'postgres.wal', 'line'],
174
'lines': [
175
- ['wal_total', 'Total', 'absolute'],
176
- ['wal_ready', 'Ready', 'absolute'],
177
- ['wal_done', 'Done', 'absolute']
175
+ ['wal_total', 'total', 'incremental'],
176
+ ['wal_ready', 'ready', 'incremental'],
177
+ ['wal_done', 'done', 'incremental']
178
]},
179
'background_writer': {
180
- 'options': [None, 'Checkpoints', 'Count', 'Background Writer', 'postgres.background_writer', 'line'],
180
+ 'options': [None, 'Checkpoints', 'writes/s', 'background writer', 'postgres.background_writer', 'line'],
181
'lines': [
182
- ['background_writer_scheduled', 'Scheduled', 'absolute'],
183
- ['background_writer_requested', 'Requested', 'absolute']
182
+ ['background_writer_scheduled', 'scheduled', 'incremental'],
183
+ ['background_writer_requested', 'requested', 'incremental']
184
]}
185
}
186
@@ -196,7 +196,6 @@ class Service(SimpleService):
196
self.connection = None
197
self.is_superuser = False
198
self.data = {}
199
- self.old_data = {}
199
self.databases = set()
200
201
def _connect(self):
@@ -256,10 +255,10 @@ class Service(SimpleService):
255
self.definitions[chart_name] = {
256
'options': [
257
name,
259
- database_name + title,
258
+ title + ': ' + database_name,
259
units,
261
- database_name + family,
262
- database_name + context,
260
+ 'db ' + database_name,
261
+ context,
262
chart_type
263
]
264
}
@@ -272,22 +271,22 @@ class Service(SimpleService):
271
def _add_database_lock_chart(self, database_name):
272
chart_name = "{}_locks".format(database_name)
273
if chart_name not in self.order:
275
- self.order.insert(0, chart_name)
274
+ self.order.insert(-1, chart_name)
275
self.definitions[chart_name] = dict(
276
options=
277
[
278
None,
280
- database_name + ' locks',
281
- 'Count',
282
- database_name + ' database statistics',
283
- database_name + '.locks',
279
+ 'Locks on db: ' + database_name,
280
+ 'locks',
281
+ 'db ' + database_name,
282
+ 'postgres.db_locks',
283
'line'
284
],
285
lines=[]
286
)
287
288
for lock_type in LOCK_TYPES:
290
- lock_id = "{}_{}".format(database_name, lock_type.lower())
289
+ lock_id = "{}_{}".format(database_name, lock_type)
290
label = re.sub("([a-z])([A-Z])", "\g<1> \g<2>", lock_type)
291
self.definitions[chart_name]['lines'].append([lock_id, label, 'absolute'])
292
@@ -319,76 +318,62 @@ class Service(SimpleService):
318
cursor.execute(DATABASE)
319
for row in cursor:
320
database_name = row.get('database_name')
322
- self.add_derive_value('db_stat_xact_commit', prefix=database_name, value=int(row.get('xact_commit', 0)))
323
- self.add_derive_value('db_stat_xact_rollback', prefix=database_name, value=int(row.get('xact_rollback', 0)))
324
- self.add_derive_value('db_stat_blks_read', prefix=database_name, value=int(row.get('blks_read', 0)))
325
- self.add_derive_value('db_stat_blks_hit', prefix=database_name, value=int(row.get('blks_hit', 0)))
326
- self.add_derive_value('db_stat_tup_returned', prefix=database_name, value=int(row.get('tup_returned', 0)))
327
- self.add_derive_value('db_stat_tup_fetched', prefix=database_name, value=int(row.get('tup_fetched', 0)))
328
- self.add_derive_value('db_stat_tup_inserted', prefix=database_name, value=int(row.get('tup_inserted', 0)))
329
- self.add_derive_value('db_stat_tup_updated', prefix=database_name, value=int(row.get('tup_updated', 0)))
330
- self.add_derive_value('db_stat_tup_deleted', prefix=database_name, value=int(row.get('tup_deleted', 0)))
331
- self.add_derive_value('db_stat_conflicts', prefix=database_name, value=int(row.get('conflicts', 0)))
332
- conn_key = "{}_{}".format(database_name, 'db_stat_connections')
333
- self.data[conn_key] = int(row.get('connections', 0))
321
+ self.data["{}_{}".format(database_name, 'db_stat_xact_commit')] = int(row.get('xact_commit', 0))
322
+ self.data["{}_{}".format(database_name, 'db_stat_xact_rollback')] = int(row.get('xact_rollback', 0))
323
+ self.data["{}_{}".format(database_name, 'db_stat_blks_read')] = int(row.get('blks_read', 0))
324
+ self.data["{}_{}".format(database_name, 'db_stat_blks_hit')] = int(row.get('blks_hit', 0))
325
+ self.data["{}_{}".format(database_name, 'db_stat_tup_returned')] = int(row.get('tup_returned', 0))
326
+ self.data["{}_{}".format(database_name, 'db_stat_tup_fetched')] = int(row.get('tup_fetched', 0))
327
+ self.data["{}_{}".format(database_name, 'db_stat_tup_inserted')] = int(row.get('tup_inserted', 0))
328
+ self.data["{}_{}".format(database_name, 'db_stat_tup_updated')] = int(row.get('tup_updated', 0))
329
+ self.data["{}_{}".format(database_name, 'db_stat_tup_deleted')] = int(row.get('tup_deleted', 0))
330
+ self.data["{}_{}".format(database_name, 'db_stat_conflicts')] = int(row.get('conflicts', 0))
331
+ self.data["{}_{}".format(database_name, 'db_stat_connections')] = int(row.get('connections', 0))
332
333
def add_backend_stats(self, cursor):
334
cursor.execute(BACKENDS)
335
temp = cursor.fetchone()
336
337
self.data['backend_process_active'] = int(temp.get('backends_active', 0))
340
- self.data['backend_process_idle'] = int(temp.get('backends_idle', 0))
338
+ self.data['backend_process_idle'] = int(temp.get('backends_idle', 0))
339
340
def add_index_stats(self, cursor):
341
cursor.execute(INDEX_STATS)
342
temp = cursor.fetchone()
345
- self.data['index_count'] = int(temp.get('indexes', 0))
346
- self.data['index_size'] = int(temp.get('size_indexes', 0))
343
+ self.data['index_count'] = int(temp.get('indexes', 0))
344
+ self.data['index_size'] = int(temp.get('size_indexes', 0))
345
346
def add_table_stats(self, cursor):
347
cursor.execute(TABLE_STATS)
348
temp = cursor.fetchone()
351
- self.data['table_count'] = int(temp.get('relations', 0))
352
- self.data['table_size'] = int(temp.get('size_relations', 0))
349
+ self.data['table_count'] = int(temp.get('relations', 0))
350
+ self.data['table_size'] = int(temp.get('size_relations', 0))
351
352
def add_lock_stats(self, cursor):
353
cursor.execute(DATABASE_LOCKS)
356
- # First zero out all current lock values.
354
+
355
+ # zero out all current lock values
356
for database_name in self.databases:
357
for lock_type in LOCK_TYPES:
359
- lock_id = "{}_{}".format(database_name, lock_type.lower())
360
- self.data[lock_id] = 0
358
+ self.data["{}_{}".format(database_name, lock_type)] = 0
359
362
- # Now populate those that have current locks
360
+ # populate those that have current locks
361
for row in cursor:
362
database_name, lock_type, lock_count = row
365
- lock_id = "{}_{}".format(database_name, lock_type.lower())
366
- self.data[lock_id] = lock_count
363
+ self.data["{}_{}".format(database_name, lock_type)] = lock_count
364
365
def add_wal_stats(self, cursor):
366
cursor.execute(ARCHIVE)
367
temp = cursor.fetchone()
371
- self.add_derive_value('wal_total', int(temp.get('file_count', 0)))
372
- self.add_derive_value('wal_ready', int(temp.get('ready_count', 0)))
373
- self.add_derive_value('wal_done', int(temp.get('done_count', 0)))
368
+ self.data['wal_total'] = int(temp.get('file_count', 0))
369
+ self.data['wal_ready'] = int(temp.get('ready_count', 0))
370
+ self.data['wal_done'] = int(temp.get('done_count', 0))
371
372
def add_bgwriter_stats(self, cursor):
373
cursor.execute(BGWRITER)
374
temp = cursor.fetchone()
378
-
379
- self.add_derive_value('background_writer_scheduled', temp.get('checkpoints_timed', 0))
380
- self.add_derive_value('background_writer_requested', temp.get('checkpoints_requests', 0))
381
-
382
- def add_derive_value(self, key, value, prefix=None):
383
- if prefix:
384
- key = "{}_{}".format(prefix, key)
385
- if key not in self.old_data.keys():
386
- self.data[key] = 0
387
- else:
388
- self.data[key] = value - self.old_data[key]
389
-
390
- self.old_data[key] = value
391
-
375
+ self.data['background_writer_scheduled'] = temp.get('checkpoints_timed', 0)
376
+ self.data['background_writer_requested'] = temp.get('checkpoints_requests', 0)
377
378
'''
379
def add_replication_stats(self, cursor):
web/dashboard_info.js
+12
@@ -133,6 +133,12 @@ netdataDashboard.menu = {
133
info: undefined
134
},
135
136
+ 'fping': {
137
+ title: 'fping',
138
+ icon: '<i class="fa fa-exchange" aria-hidden="true"></i>',
139
+ info: undefined
140
+ },
141
+
142
'memcached': {
143
title: 'memcached',
144
icon: '<i class="fa fa-database" aria-hidden="true"></i>',
@@ -145,6 +151,12 @@ netdataDashboard.menu = {
151
info: undefined
152
},
153
154
+ 'postgres': {
155
+ title: 'Postgres',
156
+ icon: '<i class="fa fa-database" aria-hidden="true"></i>',
157
+ info: undefined
158
+ },
159
+
160
'redis': {
161
title: 'Redis',
162
icon: '<i class="fa fa-database" aria-hidden="true"></i>',
web/index.html
+5
-3
@@ -1050,6 +1050,8 @@
1050
1051
case 'apache':
1052
case 'exim':
1053
+ case 'fping':
1054
+ case 'ipfs':
1055
case 'memcached':
1056
case 'mysql':
1057
case 'named':
@@ -1057,12 +1059,12 @@
1059
case 'nut':
1060
case 'phpfpm':
1061
case 'postfix':
1062
+ case 'postgres':
1063
case 'redis':
1064
case 'retroshare':
1062
- case 'ipfs':
1065
case 'smawebbox':
1064
- case 'squid':
1066
case 'snmp':
1067
+ case 'squid':
1068
case 'tomcat':
1069
chart.menu = chart.type;
1070
chart.menu_pattern = tmp;
@@ -2546,7 +2548,7 @@
2548
});
2549
2550
NETDATA.requiredJs.push({
2549
- url: NETDATA.serverDefault + 'dashboard_info.js?v20161016-1',
2551
+ url: NETDATA.serverDefault + 'dashboard_info.js?v20161030-2',
2552
async: false,
2553
isAlreadyLoaded: function() { return false; }
2554
});