diff --git a/.gitignore b/.gitignore index e6ae827a2..ca521e138 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ /.metrics.*.removed /tools/src /vendor +vendor/ diff --git a/postgres_mixin/config.libsonnet b/postgres_mixin/config.libsonnet index d7bd7ac1b..c168ab095 100644 --- a/postgres_mixin/config.libsonnet +++ b/postgres_mixin/config.libsonnet @@ -1,5 +1,8 @@ { _config+:: { postgresExporterSelector: '', + + dashboardNamePrefix: 'Postgres Exporter / ', + dashboardTags: ['postgres-exporter-mixin'], }, } diff --git a/postgres_mixin/dashboards.jsonnet b/postgres_mixin/dashboards.jsonnet new file mode 100644 index 000000000..d606bd6c1 --- /dev/null +++ b/postgres_mixin/dashboards.jsonnet @@ -0,0 +1,3 @@ +local dashboards = (import 'mixin.libsonnet').grafanaDashboards; + +{ [name]: dashboards[name] for name in std.objectFields(dashboards)} diff --git a/postgres_mixin/dashboards/dashboards.libsonnet b/postgres_mixin/dashboards/dashboards.libsonnet index d55f1ef5c..ed85b4db3 100644 --- a/postgres_mixin/dashboards/dashboards.libsonnet +++ b/postgres_mixin/dashboards/dashboards.libsonnet @@ -1,5 +1,41 @@ +local g = import 'g.libsonnet'; + +local dashboard = g.dashboard; +local row = g.panel.row; + +local panels = import './panels.libsonnet'; +local variables = import './variables.libsonnet'; +local queries = import './queries.libsonnet'; + +// import config +local c = import '../config.libsonnet'; + { grafanaDashboards+:: { - 'postgres-overview.json': (import 'postgres-overview.json'), - }, + 'overview.json': + dashboard.new('%s Overview' % $._config.dashboardNamePrefix) + + dashboard.withTags($._config.dashboardTags) + + dashboard.withRefresh('1m') + + dashboard.time.withFrom(value='now-1h') + + dashboard.graphTooltip.withSharedCrosshair() + + dashboard.withVariables([ + variables.datasource, + ]) + + dashboard.withPanels( + g.util.grid.makeGrid([ + row.new('Overview') + + row.withPanels([ + panels.stat.qps('QPS', queries.qps), + panels.timeSeries.ratio1('Cache Hit Ratio', queries.cacheHitRatio), + panels.timeSeries.base('Active Connections', queries.activeConnections) + ]), + row.new('server') + + row.withPanels([ + panels.timeSeries.base('Conflicts/Deadlocks', [queries.conflicts, queries.deadlocks]), + panels.timeSeries.base('Buffers', [queries.buffersAlloc, queries.buffersBackendFsync, queries.buffersBackend, queries.buffersClean, queries.buffersCheckpoint]), + panels.timeSeries.base('Rows', [queries.databaseTupFetched, queries.databaseTupReturned, queries.databaseTupInserted, queries.databaseTupUpdated, queries.databaseTupDeleted]), + ]), + ]) + ) + } } diff --git a/postgres_mixin/dashboards/g.libsonnet b/postgres_mixin/dashboards/g.libsonnet new file mode 100644 index 000000000..69aac8300 --- /dev/null +++ b/postgres_mixin/dashboards/g.libsonnet @@ -0,0 +1 @@ +import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet' diff --git a/postgres_mixin/dashboards/panels.libsonnet b/postgres_mixin/dashboards/panels.libsonnet new file mode 100644 index 000000000..bea0e9bb1 --- /dev/null +++ b/postgres_mixin/dashboards/panels.libsonnet @@ -0,0 +1,30 @@ +local g = import 'g.libsonnet'; + +{ + stat: { + local stat = g.panel.stat, + + base(title, targets): + stat.new(title) + +stat.queryOptions.withTargets(targets), + + qps: self.base, + }, + + timeSeries: { + local timeSeries = g.panel.timeSeries, + + base(title, targets): + timeSeries.new(title) + +timeSeries.queryOptions.withTargets(targets), + + ratio(title, targets): + self.base(title, targets) + + timeSeries.standardOptions.withUnit('percentunit'), + + ratio1(title, targets): + self.ratio(title, targets) + + timeSeries.standardOptions.withUnit('percentunit') + + timeSeries.standardOptions.withMax(1) + } +} diff --git a/postgres_mixin/dashboards/postgres-overview.json b/postgres_mixin/dashboards/postgres-overview.json deleted file mode 100644 index 9bf41be6a..000000000 --- a/postgres_mixin/dashboards/postgres-overview.json +++ /dev/null @@ -1,1412 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "description": "Performance metrics for Postgres", - "editable": true, - "gnetId": 455, - "graphTooltip": 0, - "id": 1, - "iteration": 1603191461722, - "links": [], - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 20, - "x": 0, - "y": 0 - }, - "hiddenSeries": false, - "id": 1, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "max": true, - "min": true, - "rightSide": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.1", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "fetched", - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_tup_fetched{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "fetched", - "measurement": "postgresql", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tup_fetched" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 120, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "fetched", - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_tup_returned{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "returned", - "measurement": "postgresql", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tup_fetched" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 120, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "fetched", - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_tup_inserted{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "inserted", - "measurement": "postgresql", - "policy": "default", - "refId": "C", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tup_fetched" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 120, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "fetched", - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_tup_updated{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "updated", - "measurement": "postgresql", - "policy": "default", - "refId": "D", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tup_fetched" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 120, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "fetched", - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_tup_deleted{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "deleted", - "measurement": "postgresql", - "policy": "default", - "refId": "E", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tup_fetched" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 120, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Rows", - "tooltip": { - "msResolution": true, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "cacheTimeout": null, - "colorBackground": false, - "colorValue": false, - "colors": [ - "rgba(245, 54, 54, 0.9)", - "rgba(237, 129, 40, 0.89)", - "rgba(50, 172, 45, 0.97)" - ], - "datasource": "$datasource", - "decimals": 0, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "format": "none", - "gauge": { - "maxValue": 100, - "minValue": 0, - "show": false, - "thresholdLabels": false, - "thresholdMarkers": true - }, - "gridPos": { - "h": 3, - "w": 4, - "x": 20, - "y": 0 - }, - "height": "55px", - "id": 11, - "interval": null, - "isNew": true, - "links": [], - "mappingType": 1, - "mappingTypes": [ - { - "name": "value to text", - "value": 1 - }, - { - "name": "range to text", - "value": 2 - } - ], - "maxDataPoints": 100, - "nullPointMode": "connected", - "nullText": null, - "postfix": "", - "postfixFontSize": "50%", - "prefix": "", - "prefixFontSize": "50%", - "rangeMaps": [ - { - "from": "null", - "text": "N/A", - "to": "null" - } - ], - "sparkline": { - "fillColor": "rgba(31, 118, 189, 0.18)", - "full": true, - "lineColor": "rgb(31, 120, 193)", - "show": true - }, - "tableColumn": "", - "targets": [ - { - "dsType": "prometheus", - "expr": "sum(irate(pg_stat_database_xact_commit{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])) + sum(irate(pg_stat_database_xact_rollback{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "measurement": "postgresql", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "xact_commit" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "10s" - ], - "type": "non_negative_derivative" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": "", - "title": "QPS", - "transparent": true, - "type": "singlestat", - "valueFontSize": "80%", - "valueMaps": [ - { - "op": "=", - "text": "N/A", - "value": "null" - } - ], - "valueName": "avg" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "decimals": 1, - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 7 - }, - "hiddenSeries": false, - "id": 2, - "isNew": true, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.1", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "Buffers Allocated", - "dsType": "prometheus", - "expr": "irate(pg_stat_bgwriter_buffers_alloc{job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "buffers_alloc", - "measurement": "postgresql", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "buffers_alloc" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "Buffers Allocated", - "dsType": "prometheus", - "expr": "irate(pg_stat_bgwriter_buffers_backend_fsync{job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "buffers_backend_fsync", - "measurement": "postgresql", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "buffers_alloc" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "Buffers Allocated", - "dsType": "prometheus", - "expr": "irate(pg_stat_bgwriter_buffers_backend{job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "buffers_backend", - "measurement": "postgresql", - "policy": "default", - "refId": "C", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "buffers_alloc" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "Buffers Allocated", - "dsType": "prometheus", - "expr": "irate(pg_stat_bgwriter_buffers_clean{job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "buffers_clean", - "measurement": "postgresql", - "policy": "default", - "refId": "D", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "buffers_alloc" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "Buffers Allocated", - "dsType": "prometheus", - "expr": "irate(pg_stat_bgwriter_buffers_checkpoint{job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "buffers_checkpoint", - "measurement": "postgresql", - "policy": "default", - "refId": "E", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "buffers_alloc" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Buffers", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 7 - }, - "hiddenSeries": false, - "id": 3, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.1", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "conflicts", - "dsType": "prometheus", - "expr": "sum(rate(pg_stat_database_deadlocks{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "deadlocks", - "measurement": "postgresql", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "conflicts" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "deadlocks", - "dsType": "prometheus", - "expr": "sum(rate(pg_stat_database_conflicts{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval]))", - "format": "time_series", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "intervalFactor": 2, - "legendFormat": "conflicts", - "measurement": "postgresql", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "deadlocks" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 240, - "tags": [ - { - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Conflicts/Deadlocks", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 12, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": true, - "pluginVersion": "7.2.1", - "pointradius": 1, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "sum by (datname) (rate(pg_stat_database_blks_hit{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])) / (sum by (datname)(rate(pg_stat_database_blks_hit{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])) + sum by (datname)(rate(pg_stat_database_blks_read{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}[$__rate_interval])))", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{datname}} - cache hit rate", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Cache hit ratio", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": {}, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 14 - }, - "hiddenSeries": false, - "id": 13, - "isNew": true, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.1", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "pg_stat_database_numbackends{datname=~\"$db\",job=~\"$job\",instance=~\"$instance\"}", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{datname}} - {{__name__}}", - "refId": "A", - "step": 240 - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Number of active connections", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [ - "postgres" - ], - "templating": { - "list": [ - { - "hide": 0, - "includeAll": false, - "label": "Data Source", - "multi": false, - "name": "datasource", - "options": [], - "query": "prometheus", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "type": "datasource" - }, - { - "allValue": ".+", - "datasource": "$datasource", - "definition": "label_values(pg_up, job)", - "hide": 0, - "includeAll": true, - "label": "job", - "multi": true, - "name": "job", - "options": [], - "query": "label_values(pg_up, job)", - "refresh": 0, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "datasource": "$datasource", - "definition": "", - "hide": 0, - "includeAll": true, - "label": "instance", - "multi": true, - "name": "instance", - "options": [], - "query": "label_values(up{job=~\"$job\"},instance)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allValue": ".+", - "datasource": "$datasource", - "definition": "label_values(pg_stat_database_tup_fetched{instance=~\"$instance\",datname!~\"template.*|postgres\"},datname)", - "hide": 0, - "includeAll": true, - "label": "db", - "multi": false, - "name": "db", - "options": [], - "query": "label_values(pg_stat_database_tup_fetched{instance=~\"$instance\",datname!~\"template.*|postgres\"},datname)", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "browser", - "title": "Postgres Overview", - "uid": "wGgaPlciz", - "version": 5 -} diff --git a/postgres_mixin/dashboards/queries.libsonnet b/postgres_mixin/dashboards/queries.libsonnet new file mode 100644 index 000000000..dcc33d920 --- /dev/null +++ b/postgres_mixin/dashboards/queries.libsonnet @@ -0,0 +1,223 @@ +local g = import './g.libsonnet'; +local prometheusQuery = g.query.prometheus; + +local variables = import './variables.libsonnet'; + +{ + /* + General overview queries + */ + + qps: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_xact_commit{}[$__rate_interval] + ) + ) + + + sum( + irate( + pg_stat_database_xact_rollback{}[$__rate_interval] + ) + ) + ||| + ), + + cacheHitRatio: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum by (datname) ( + rate( + pg_stat_database_blks_hit{} + [$__rate_interval]) + ) / ( + sum by (datname) ( + rate( + pg_stat_database_blks_hit{} + [$__rate_interval]) + ) + sum by (datname) ( + rate( + pg_stat_database_blks_read{} + [$__rate_interval]) + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat(||| + {{datname}} + |||), + + activeConnections: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + pg_stat_database_numbackends{} + ||| + ) + + prometheusQuery.withLegendFormat(||| + {{datname}} + |||), + + deadlocks: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + rate( + pg_stat_database_deadlocks{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat(||| + deadlocks + |||), + + conflicts: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + rate( + pg_stat_database_conflicts{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat(||| + conflicts + |||), + + /* ---------------------- + Buffers + ---------------------- */ + + buffersAlloc: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + irate( + pg_stat_bgwriter_buffers_alloc_total{}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('allocated'), + + buffersBackendFsync: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + irate( + pg_stat_bgwriter_buffers_backend_fsync_total{}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('backend fsyncs'), + + buffersBackend: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + irate( + pg_stat_bgwriter_buffers_backend_total{}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('backend'), + + buffersClean: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + irate( + pg_stat_bgwriter_buffers_clean_total{}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('clean'), + + buffersCheckpoint: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + irate( + pg_stat_bgwriter_buffers_checkpoint_total{}[$__rate_interval] + ) + ||| + ) + + prometheusQuery.withLegendFormat('checkpoint'), + + /* ---------------------- + Database Tups + ---------------------- */ + + databaseTupFetched: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_tup_fetched{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat('fetched'), + + databaseTupReturned: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_tup_returned{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat('returned'), + + databaseTupInserted: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_tup_inserted{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat('inserted'), + + databaseTupUpdated: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_tup_updated{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat('updated'), + + databaseTupDeleted: + prometheusQuery.new( + '$' + variables.datasource.name, + ||| + sum( + irate( + pg_stat_database_tup_deleted{}[$__rate_interval] + ) + ) + ||| + ) + + prometheusQuery.withLegendFormat('deleted'), + +} diff --git a/postgres_mixin/dashboards/variables.libsonnet b/postgres_mixin/dashboards/variables.libsonnet new file mode 100644 index 000000000..15a22469a --- /dev/null +++ b/postgres_mixin/dashboards/variables.libsonnet @@ -0,0 +1,7 @@ +local g = import './g.libsonnet'; +local var = g.dashboard.variable; + +{ + datasource: + var.datasource.new('datasource', 'prometheus') +} diff --git a/postgres_mixin/jsonnetfile.json b/postgres_mixin/jsonnetfile.json new file mode 100644 index 000000000..2414c8671 --- /dev/null +++ b/postgres_mixin/jsonnetfile.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "dependencies": [ + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-latest" + } + }, + "version": "main" + } + ], + "legacyImports": true +} diff --git a/postgres_mixin/jsonnetfile.lock.json b/postgres_mixin/jsonnetfile.lock.json new file mode 100644 index 000000000..4114629fe --- /dev/null +++ b/postgres_mixin/jsonnetfile.lock.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "dependencies": [ + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-latest" + } + }, + "version": "f86c6b155b8ea527d36cd7194b2cb42dac437166", + "sum": "sVzVlSLbxPkAurwO19YERigLMmRfVsViMcWC0gkTTqU=" + }, + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet.git", + "subdir": "gen/grafonnet-v10.0.0" + } + }, + "version": "f86c6b155b8ea527d36cd7194b2cb42dac437166", + "sum": "brWLY/BpeCL2ThiWlLtLcs4KwgMvouGtPrKAagBnG8g=" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/docsonnet.git", + "subdir": "doc-util" + } + }, + "version": "7c865ec0606f2b68c0f6b2721f101e6a99cd2593", + "sum": "zjjufxN4yAIevldYEERiZEp27vK0BJKj1VvZcVtWiOo=" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/xtd.git", + "subdir": "" + } + }, + "version": "0256a910ac71f0f842696d7bca0bf01ea77eb654", + "sum": "zBOpb1oTNvXdq9RF6yzTHill5r1YTJLBBoqyx4JYtAg=" + } + ], + "legacyImports": false +}