diff --git a/bundles/grafana/dashboard-rows/postgresql.py b/bundles/grafana/dashboard-rows/postgresql.py new file mode 100644 index 0000000..99045ec --- /dev/null +++ b/bundles/grafana/dashboard-rows/postgresql.py @@ -0,0 +1,586 @@ +def dashboard_row_postgresql(panel_id, node): + queries_transactions = [] + queries_rows = [] + queries_conflicts = [] + queries_blocks = [] + queries_buffers = [] + + for measurement in [ + 'commit', + 'rollback', + ]: + queries_transactions.append({ + 'groupBy': [ + {'type': 'time', 'params': ['$__interval']}, + {'type': 'fill', 'params': ['linear']}, + ], + 'orderByTime': "ASC", + 'policy': "default", + 'query': f"""from(bucket: "telegraf") + |> range(start: v.timeRangeStart, stop: v.timeRangeStop) + |> filter(fn: (r) => + r["_measurement"] == "postgresql" and + r["_field"] == "xact_{measurement}" and + r["host"] == "{node.name}" + ) + |> derivative(unit: 1s) + |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) + |> yield(name: "{measurement}")""", + 'resultFormat': 'time_series', + 'select': [[ + {'type': 'field', 'params': ['value']}, + {'type': 'mean', 'params': []}, + ]], + "tags": [] + }) + + for measurement in [ + 'deleted', + 'fetched', + 'inserted', + 'returned', + 'updated', + ]: + queries_rows.append({ + 'groupBy': [ + {'type': 'time', 'params': ['$__interval']}, + {'type': 'fill', 'params': ['linear']}, + ], + 'orderByTime': "ASC", + 'policy': "default", + 'query': f"""from(bucket: "telegraf") + |> range(start: v.timeRangeStart, stop: v.timeRangeStop) + |> filter(fn: (r) => + r["_measurement"] == "postgresql" and + r["_field"] == "tup_{measurement}" and + r["host"] == "{node.name}" + ) + |> derivative(unit: 1s) + |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) + |> yield(name: "{measurement}")""", + 'resultFormat': 'time_series', + 'select': [[ + {'type': 'field', 'params': ['value']}, + {'type': 'mean', 'params': []}, + ]], + "tags": [] + }) + + for measurement in [ + 'conflicts', + 'deadlocks', + ]: + queries_conflicts.append({ + 'groupBy': [ + {'type': 'time', 'params': ['$__interval']}, + {'type': 'fill', 'params': ['linear']}, + ], + 'orderByTime': "ASC", + 'policy': "default", + 'query': f"""from(bucket: "telegraf") + |> range(start: v.timeRangeStart, stop: v.timeRangeStop) + |> filter(fn: (r) => + r["_measurement"] == "postgresql" and + r["_field"] == "{measurement}" and + r["host"] == "{node.name}" + ) + |> derivative(unit: 1s) + |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) + |> yield(name: "{measurement}")""", + 'resultFormat': 'time_series', + 'select': [[ + {'type': 'field', 'params': ['value']}, + {'type': 'mean', 'params': []}, + ]], + "tags": [] + }) + + for measurement in [ + 'read', + 'hit', + ]: + queries_blocks.append({ + 'groupBy': [ + {'type': 'time', 'params': ['$__interval']}, + {'type': 'fill', 'params': ['linear']}, + ], + 'orderByTime': "ASC", + 'policy': "default", + 'query': f"""from(bucket: "telegraf") + |> range(start: v.timeRangeStart, stop: v.timeRangeStop) + |> filter(fn: (r) => + r["_measurement"] == "postgresql" and + r["_field"] == "blks_{measurement}" and + r["host"] == "{node.name}" + ) + |> derivative(unit: 1s) + |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) + |> yield(name: "{measurement}")""", + 'resultFormat': 'time_series', + 'select': [[ + {'type': 'field', 'params': ['value']}, + {'type': 'mean', 'params': []}, + ]], + "tags": [] + }) + + for measurement in [ + 'alloc', + 'backend', + 'backend_fsync', + 'checkpoint', + 'clean' + ]: + queries_buffers.append({ + 'groupBy': [ + {'type': 'time', 'params': ['$__interval']}, + {'type': 'fill', 'params': ['linear']}, + ], + 'orderByTime': "ASC", + 'policy': "default", + 'query': f"""from(bucket: "telegraf") + |> range(start: v.timeRangeStart, stop: v.timeRangeStop) + |> filter(fn: (r) => + r["_measurement"] == "postgresql" and + r["_field"] == "buffers_{measurement}" and + r["host"] == "{node.name}" + ) + |> derivative(unit: 1s) + |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false) + |> yield(name: "{measurement}")""", + 'resultFormat': 'time_series', + 'select': [[ + {'type': 'field', 'params': ['value']}, + {'type': 'mean', 'params': []}, + ]], + "tags": [] + }) + + return { + 'title': 'postgresql', + 'collapse': False, + 'editable': False, + 'height': '250px', + 'panels': [ + { + 'aliasColors': {}, + 'bars': False, + 'dashLength': 10, + 'dashes': False, + 'datasource': None, + 'fieldConfig': { + 'defaults': { + 'displayName': '${__field.name} ${__field.labels.db}' + }, + 'overrides': [] + }, + 'fill': 1, + 'fillGradient': 0, + 'hiddenSeries': False, + 'id': next(panel_id), + 'legend': { + 'alignAsTable': False, + 'avg': False, + 'current': False, + 'max': False, + 'min': False, + 'rightSide': False, + 'show': True, + 'total': False, + 'values': False + }, + 'lines': True, + 'linewidth': 1, + 'NonePointMode': 'None', + 'options': { + 'alertThreshold': True + }, + 'percentage': False, + 'pluginVersion': '7.5.5', + 'pointradius': 2, + 'points': False, + 'renderer': 'flot', + 'seriesOverrides': [], + 'spaceLength': 10, + 'span': 6, + 'stack': True, + 'steppedLine': False, + 'targets': queries_transactions, + 'thresholds': [], + 'timeRegions': [], + 'title': 'postgresql transactions per second', + 'tooltip': { + 'shared': True, + 'sort': 0, + 'value_type': 'individual' + }, + 'type': 'graph', + 'xaxis': { + 'buckets': None, + 'mode': 'time', + 'name': None, + 'show': True, + 'values': [] + }, + 'yaxes': [ + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': 0, + 'show': True, + 'decimals': 0, + }, + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': None, + 'show': False, + } + ], + 'yaxis': { + 'align': False, + 'alignLevel': None + } + }, + { + 'aliasColors': {}, + 'bars': False, + 'dashLength': 10, + 'dashes': False, + 'datasource': None, + 'fieldConfig': { + 'defaults': { + 'displayName': '${__field.name} ${__field.labels.db}' + }, + 'overrides': [] + }, + 'fill': 1, + 'fillGradient': 0, + 'hiddenSeries': False, + 'id': next(panel_id), + 'legend': { + 'alignAsTable': False, + 'avg': False, + 'current': False, + 'max': False, + 'min': False, + 'rightSide': False, + 'show': True, + 'total': False, + 'values': False + }, + 'lines': True, + 'linewidth': 1, + 'NonePointMode': 'None', + 'options': { + 'alertThreshold': True + }, + 'percentage': False, + 'pluginVersion': '7.5.5', + 'pointradius': 2, + 'points': False, + 'renderer': 'flot', + 'seriesOverrides': [], + 'spaceLength': 10, + 'span': 6, + 'stack': True, + 'steppedLine': False, + 'targets': queries_rows, + 'thresholds': [], + 'timeRegions': [], + 'title': 'postgresql rows per second', + 'tooltip': { + 'shared': True, + 'sort': 0, + 'value_type': 'individual' + }, + 'type': 'graph', + 'xaxis': { + 'buckets': None, + 'mode': 'time', + 'name': None, + 'show': True, + 'values': [] + }, + 'yaxes': [ + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': 0, + 'show': True, + 'decimals': 0, + }, + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': None, + 'show': False, + } + ], + 'yaxis': { + 'align': False, + 'alignLevel': None + } + }, + { + 'aliasColors': {}, + 'bars': False, + 'dashLength': 10, + 'dashes': False, + 'datasource': None, + 'fieldConfig': { + 'defaults': { + 'displayName': '${__field.name} ${__field.labels.db}' + }, + 'overrides': [] + }, + 'fill': 1, + 'fillGradient': 0, + 'hiddenSeries': False, + 'id': next(panel_id), + 'legend': { + 'alignAsTable': False, + 'avg': False, + 'current': False, + 'max': False, + 'min': False, + 'rightSide': False, + 'show': True, + 'total': False, + 'values': False + }, + 'lines': True, + 'linewidth': 1, + 'NonePointMode': 'None', + 'options': { + 'alertThreshold': True + }, + 'percentage': False, + 'pluginVersion': '7.5.5', + 'pointradius': 2, + 'points': False, + 'renderer': 'flot', + 'seriesOverrides': [], + 'spaceLength': 10, + 'span': 4, + 'stack': True, + 'steppedLine': False, + 'targets': queries_conflicts, + 'thresholds': [], + 'timeRegions': [], + 'title': 'postgresql conflicts/deadlocks', + 'tooltip': { + 'shared': True, + 'sort': 0, + 'value_type': 'individual' + }, + 'type': 'graph', + 'xaxis': { + 'buckets': None, + 'mode': 'time', + 'name': None, + 'show': True, + 'values': [] + }, + 'yaxes': [ + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': 0, + 'show': True, + 'decimals': 0, + }, + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': None, + 'show': False, + } + ], + 'yaxis': { + 'align': False, + 'alignLevel': None + } + }, + { + 'aliasColors': {}, + 'bars': False, + 'dashLength': 10, + 'dashes': False, + 'datasource': None, + 'fieldConfig': { + 'defaults': { + 'displayName': '${__field.name} ${__field.labels.db}' + }, + 'overrides': [] + }, + 'fill': 1, + 'fillGradient': 0, + 'hiddenSeries': False, + 'id': next(panel_id), + 'legend': { + 'alignAsTable': False, + 'avg': False, + 'current': False, + 'max': False, + 'min': False, + 'rightSide': False, + 'show': True, + 'total': False, + 'values': False + }, + 'lines': True, + 'linewidth': 1, + 'NonePointMode': 'None', + 'options': { + 'alertThreshold': True + }, + 'percentage': False, + 'pluginVersion': '7.5.5', + 'pointradius': 2, + 'points': False, + 'renderer': 'flot', + 'seriesOverrides': [], + 'spaceLength': 10, + 'span': 4, + 'stack': True, + 'steppedLine': False, + 'targets': queries_blocks, + 'thresholds': [], + 'timeRegions': [], + 'title': 'postgresql blocks read per second', + 'tooltip': { + 'shared': True, + 'sort': 0, + 'value_type': 'individual' + }, + 'type': 'graph', + 'xaxis': { + 'buckets': None, + 'mode': 'time', + 'name': None, + 'show': True, + 'values': [] + }, + 'yaxes': [ + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': 0, + 'show': True, + 'decimals': 0, + }, + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': None, + 'show': False, + } + ], + 'yaxis': { + 'align': False, + 'alignLevel': None + } + }, + { + 'aliasColors': {}, + 'bars': False, + 'dashLength': 10, + 'dashes': False, + 'datasource': None, + 'fieldConfig': { + 'defaults': { + 'displayName': '${__field.name}' + }, + 'overrides': [] + }, + 'fill': 1, + 'fillGradient': 0, + 'hiddenSeries': False, + 'id': next(panel_id), + 'legend': { + 'alignAsTable': False, + 'avg': False, + 'current': False, + 'max': False, + 'min': False, + 'rightSide': False, + 'show': True, + 'total': False, + 'values': False + }, + 'lines': True, + 'linewidth': 1, + 'NonePointMode': 'None', + 'options': { + 'alertThreshold': True + }, + 'percentage': False, + 'pluginVersion': '7.5.5', + 'pointradius': 2, + 'points': False, + 'renderer': 'flot', + 'seriesOverrides': [], + 'spaceLength': 10, + 'span': 4, + 'stack': True, + 'steppedLine': False, + 'targets': queries_buffers, + 'thresholds': [], + 'timeRegions': [], + 'title': 'postgresql buffers', + 'tooltip': { + 'shared': True, + 'sort': 0, + 'value_type': 'individual' + }, + 'type': 'graph', + 'xaxis': { + 'buckets': None, + 'mode': 'time', + 'name': None, + 'show': True, + 'values': [] + }, + 'yaxes': [ + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': 0, + 'show': True, + 'decimals': 0, + }, + { + 'format': 'short', + 'label': None, + 'logBase': 1, + 'max': None, + 'min': None, + 'show': False, + } + ], + 'yaxis': { + 'align': False, + 'alignLevel': None + } + }, + ], + } diff --git a/bundles/grafana/items.py b/bundles/grafana/items.py index 7304e1c..5df725c 100644 --- a/bundles/grafana/items.py +++ b/bundles/grafana/items.py @@ -98,6 +98,10 @@ for rnode in repo.nodes: dashboard['rows'].append(dashboard_row_postfix(panel_id, rnode)) dashboard['tags'].add('postfix') + if rnode.has_bundle('postgresql'): + dashboard['rows'].append(dashboard_row_postgresql(panel_id, rnode)) + dashboard['tags'].add('postgresql') + files[f'/var/lib/grafana/dashboards/{rnode.name}.json'] = { # use metadata_to_json, because this supports sets 'content': metadata_to_json(dashboard), diff --git a/bundles/postgresql/metadata.py b/bundles/postgresql/metadata.py index 1d1410c..1b3ed3b 100644 --- a/bundles/postgresql/metadata.py +++ b/bundles/postgresql/metadata.py @@ -30,6 +30,33 @@ defaults = { }, } +if node.has_bundle('telegraf'): + defaults['telegraf'] = { + 'input_plugins': { + 'builtin': { + 'postgresql': [{ + 'address': repo.vault.password_for(f'{node.name} postgresql telegraf').format_into('postgres://telegraf:{}@localhost:5432/telegraf?sslmode=disable'), + 'ignored_databases': [ + 'template0', + 'template1', + ], + }], + }, + }, + } + defaults['postgresql'].update({ + 'roles': { + 'telegraf': { + 'password': repo.vault.password_for(f'{node.name} postgresql telegraf'), + }, + }, + 'databases': { + 'telegraf': { + 'owner': 'telegraf', + }, + }, + }) + if node.has_bundle('zfs'): defaults['zfs'] = { 'datasets': {