mirror of
https://github.com/prometheus-community/postgres_exporter
synced 2025-04-21 06:25:32 +00:00
Rework postgres_mixin dashboard
Rework the postgres_mixing dashboard to be more composable. The goal is for this to be more maintainable long term. I don't know jsonnet very well, but following other projects, this appears to be in line. This replaces the postgres-overview.json dashboard with an overview.json dashboard with the same panels. While the dashboard does not match perfectly, it does include the same data but with the correct metrics. Signed-off-by: Joe Adams <github@joeadams.io>
This commit is contained in:
parent
31ef4ed5a2
commit
5d10f23241
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@
|
|||||||
/.metrics.*.removed
|
/.metrics.*.removed
|
||||||
/tools/src
|
/tools/src
|
||||||
/vendor
|
/vendor
|
||||||
|
vendor/
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
_config+:: {
|
_config+:: {
|
||||||
postgresExporterSelector: '',
|
postgresExporterSelector: '',
|
||||||
|
|
||||||
|
dashboardNamePrefix: 'Postgres Exporter / ',
|
||||||
|
dashboardTags: ['postgres-exporter-mixin'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
3
postgres_mixin/dashboards.jsonnet
Normal file
3
postgres_mixin/dashboards.jsonnet
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
local dashboards = (import 'mixin.libsonnet').grafanaDashboards;
|
||||||
|
|
||||||
|
{ [name]: dashboards[name] for name in std.objectFields(dashboards)}
|
@ -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+:: {
|
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]),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
postgres_mixin/dashboards/g.libsonnet
Normal file
1
postgres_mixin/dashboards/g.libsonnet
Normal file
@ -0,0 +1 @@
|
|||||||
|
import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet'
|
30
postgres_mixin/dashboards/panels.libsonnet
Normal file
30
postgres_mixin/dashboards/panels.libsonnet
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
223
postgres_mixin/dashboards/queries.libsonnet
Normal file
223
postgres_mixin/dashboards/queries.libsonnet
Normal file
@ -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'),
|
||||||
|
|
||||||
|
}
|
7
postgres_mixin/dashboards/variables.libsonnet
Normal file
7
postgres_mixin/dashboards/variables.libsonnet
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
local g = import './g.libsonnet';
|
||||||
|
local var = g.dashboard.variable;
|
||||||
|
|
||||||
|
{
|
||||||
|
datasource:
|
||||||
|
var.datasource.new('datasource', 'prometheus')
|
||||||
|
}
|
15
postgres_mixin/jsonnetfile.json
Normal file
15
postgres_mixin/jsonnetfile.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"source": {
|
||||||
|
"git": {
|
||||||
|
"remote": "https://github.com/grafana/grafonnet.git",
|
||||||
|
"subdir": "gen/grafonnet-latest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"version": "main"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"legacyImports": true
|
||||||
|
}
|
46
postgres_mixin/jsonnetfile.lock.json
Normal file
46
postgres_mixin/jsonnetfile.lock.json
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user