From 187ac5ab1239b2ac09f194bc19b3366551a0fe19 Mon Sep 17 00:00:00 2001 From: Mikhail Grigorev Date: Fri, 5 Jul 2024 18:48:33 +0500 Subject: [PATCH] Added support detect synchronous mode in Patroni configuration (#27) Co-authored-by: Mikhail Grigorev --- deploy/grafana/pgSCV_Patroni.json | 97 +++++++++++++++++++++++++--- internal/collector/patroni_common.go | 16 +++++ 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/deploy/grafana/pgSCV_Patroni.json b/deploy/grafana/pgSCV_Patroni.json index ac23141..c935bcd 100644 --- a/deploy/grafana/pgSCV_Patroni.json +++ b/deploy/grafana/pgSCV_Patroni.json @@ -1394,6 +1394,87 @@ ], "title": "Max lag on failover", "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_VICTORIAMETRICS}" + }, + "description": "Is 1 if synchronous mode is active, 0 if inactive.\n\nSee docs https://patroni.readthedocs.io/en/latest/replication_modes.html#synchronous-mode for more info.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "index": 0, + "text": "INACTIVE" + }, + "1": { + "index": 1, + "text": "ACTIVE" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 4, + "x": 20, + "y": 12 + }, + "id": 69, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_VICTORIAMETRICS}" + }, + "editorMode": "code", + "expr": "patroni_sync_standby{instance=\"$instance\",service_id=\"$patroni\",scope=\"$scope\"}", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Synchronous mode", + "type": "stat" } ], "title": "Patroni settings", @@ -1452,7 +1533,7 @@ "h": 5, "w": 4, "x": 0, - "y": 17 + "y": 18 }, "id": 52, "options": { @@ -1540,7 +1621,7 @@ "h": 5, "w": 4, "x": 4, - "y": 17 + "y": 18 }, "id": 56, "options": { @@ -1622,7 +1703,7 @@ "h": 5, "w": 4, "x": 8, - "y": 17 + "y": 18 }, "id": 50, "options": { @@ -1690,7 +1771,7 @@ "h": 5, "w": 4, "x": 12, - "y": 17 + "y": 18 }, "id": 55, "options": { @@ -1757,7 +1838,7 @@ "h": 5, "w": 4, "x": 16, - "y": 17 + "y": 18 }, "id": 53, "options": { @@ -1839,7 +1920,7 @@ "h": 5, "w": 4, "x": 20, - "y": 17 + "y": 18 }, "id": 54, "options": { @@ -1921,7 +2002,7 @@ "h": 5, "w": 4, "x": 0, - "y": 22 + "y": 23 }, "id": 51, "options": { @@ -2490,6 +2571,6 @@ "timezone": "", "title": "pgSCV: Patroni", "uid": "aim7Ue3th", - "version": 19, + "version": 20, "weekStart": "" } \ No newline at end of file diff --git a/internal/collector/patroni_common.go b/internal/collector/patroni_common.go index bc9cd7d..d2f5f8a 100644 --- a/internal/collector/patroni_common.go +++ b/internal/collector/patroni_common.go @@ -41,6 +41,7 @@ type patroniCommonCollector struct { maximumLagOnFailover typedDesc retryTimeout typedDesc ttl typedDesc + syncStandby typedDesc } // NewPatroniCommonCollector returns a new Collector exposing Patroni common info. @@ -212,6 +213,12 @@ func NewPatroniCommonCollector(constLabels labels, settings model.CollectorSetti varLabels, constLabels, settings.Filters, ), + syncStandby: newBuiltinTypedDesc( + descOpts{"patroni", "", "sync_standby", "Value is 1 if synchronous mode is active, 0 if inactive.", 0}, + prometheus.GaugeValue, + varLabels, constLabels, + settings.Filters, + ), }, nil } @@ -263,6 +270,7 @@ func (c *patroniCommonCollector) Update(config Config, ch chan<- prometheus.Metr ch <- c.pendingRestart.newConstMetric(info.pendingRestart, info.scope) ch <- c.pause.newConstMetric(info.pause, info.scope) ch <- c.inArchiveRecovery.newConstMetric(info.inArchiveRecovery, info.scope) + ch <- c.syncStandby.newConstMetric(info.syncStandby, info.scope) // Request and parse config. respConfig, err := requestApiPatroniConfig(c.client, config.BaseURL) @@ -333,6 +341,7 @@ type apiPatroniResponse struct { ReplicationState string `json:"replication_state"` PendingRestart bool `json:"pending_restart"` Pause bool `json:"pause"` + SyncStandby bool `json:"sync_standby"` } // patroniInfo implements metrics values extracted from the response of '/patroni' endpoint. @@ -359,6 +368,7 @@ type patroniInfo struct { pendingRestart float64 pause float64 inArchiveRecovery float64 + syncStandby float64 } // apiPatroniResponse implements API response returned by '/config' endpoint. @@ -521,6 +531,11 @@ func parsePatroniResponse(resp *apiPatroniResponse) (*patroniInfo, error) { inArchiveRecovery = 1 } + var syncStandby float64 + if resp.SyncStandby { + syncStandby = 1 + } + return &patroniInfo{ name: resp.Patroni.Name, scope: resp.Patroni.Scope, @@ -544,6 +559,7 @@ func parsePatroniResponse(resp *apiPatroniResponse) (*patroniInfo, error) { pendingRestart: pendingRestart, pause: pause, inArchiveRecovery: inArchiveRecovery, + syncStandby: syncStandby, }, nil }