From c988ac9c5a29760b87d68ca01e5fa0d7114d0471 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Wed, 28 Jun 2023 10:56:04 -0700 Subject: [PATCH 1/7] Autovacuum collector and test Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 85 +++++++++++++++++++ collector/pg_stat_activity_autovacuum_test.go | 62 ++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 collector/pg_stat_activity_autovacuum.go create mode 100644 collector/pg_stat_activity_autovacuum_test.go diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go new file mode 100644 index 000000000..3ed37ed5b --- /dev/null +++ b/collector/pg_stat_activity_autovacuum.go @@ -0,0 +1,85 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collector + +import ( + "context" + + "github.com/go-kit/log" + "github.com/prometheus/client_golang/prometheus" +) + +const statActivityAutovacuumSubsystem = "stat_activity_autovacuum" + +func init() { + registerCollector(statActivityAutovacuumSubsystem, defaultDisabled, NewPGStatActivityAutovacuumCollector) +} + +type PGStatActivityAutovacuumCollector struct { + log log.Logger +} + +func NewPGStatActivityAutovacuumCollector(config collectorConfig) (Collector, error) { + return &PGStatActivityAutovacuumCollector{log: config.logger}, nil +} + +var ( + statActivityAutovacuumAgeInSeconds = prometheus.NewDesc( + prometheus.BuildFQName(namespace, statActivityAutovacuumSubsystem, "age_in_seconds"), + "The age of the vacuum process in seconds", + []string{"relname"}, + prometheus.Labels{}, + ) + + statActivityAutovacuumQuery = ` + SELECT + SPLIT_PART(query, '.', 2) AS relname, + EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) AS age_in_seconds + FROM + pg_catalog.pg_stat_activity + WHERE + query like 'autovacuum:%' AND + EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) > 300 + ` +) + +func (PGStatActivityAutovacuumCollector) Update(ctx context.Context, instance *instance, ch chan<- prometheus.Metric) error { + db := instance.getDB() + rows, err := db.QueryContext(ctx, + statActivityAutovacuumQuery) + + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + var relname string + var ageInSeconds float64 + + if err := rows.Scan(&relname, &ageInSeconds); err != nil { + return err + } + + ch <- prometheus.MustNewConstMetric( + statActivityAutovacuumAgeInSeconds, + prometheus.GaugeValue, + ageInSeconds, relname, + ) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} diff --git a/collector/pg_stat_activity_autovacuum_test.go b/collector/pg_stat_activity_autovacuum_test.go new file mode 100644 index 000000000..a6fcdbcad --- /dev/null +++ b/collector/pg_stat_activity_autovacuum_test.go @@ -0,0 +1,62 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package collector + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + "github.com/smartystreets/goconvey/convey" +) + +func TestPGStatActivityAutovacuumCollector(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("Error opening a stub db connection: %s", err) + } + defer db.Close() + inst := &instance{db: db} + columns := []string{ + "relname", + "timestamp_seconds", + } + rows := sqlmock.NewRows(columns). + AddRow("test", 3600) + + mock.ExpectQuery(sanitizeQuery(statActivityAutovacuumQuery)).WillReturnRows(rows) + + ch := make(chan prometheus.Metric) + go func() { + defer close(ch) + c := PGStatActivityAutovacuumCollector{} + + if err := c.Update(context.Background(), inst, ch); err != nil { + t.Errorf("Error calling PGStatActivityAutovacuumCollector.Update: %s", err) + } + }() + expected := []MetricResult{ + {labels: labelMap{"relname": "test"}, value: 3600, metricType: dto.MetricType_GAUGE}, + } + convey.Convey("Metrics comparison", t, func() { + for _, expect := range expected { + m := readMetric(<-ch) + convey.So(expect, convey.ShouldResemble, m) + } + }) + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled exceptions: %s", err) + } +} From eb57d1d7b933912bc8eaec470c5a483886bcdb74 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Thu, 29 Jun 2023 12:50:10 -0700 Subject: [PATCH 2/7] Update collector/pg_stat_activity_autovacuum.go Co-authored-by: Joe Adams Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index 3ed37ed5b..a24ae3c0f 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -49,7 +49,7 @@ var ( FROM pg_catalog.pg_stat_activity WHERE - query like 'autovacuum:%' AND + query like 'autovacuum:%' AND EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) > 300 ` ) From 10d5fcfba288c7656da114e0d609047167f52d85 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Thu, 29 Jun 2023 12:50:23 -0700 Subject: [PATCH 3/7] Update collector/pg_stat_activity_autovacuum.go Co-authored-by: Joe Adams Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index a24ae3c0f..d2c63c1de 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -44,8 +44,8 @@ var ( statActivityAutovacuumQuery = ` SELECT - SPLIT_PART(query, '.', 2) AS relname, - EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) AS age_in_seconds + SPLIT_PART(query, '.', 2) AS relname, + EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) AS age_in_seconds FROM pg_catalog.pg_stat_activity WHERE From 3aa5b16bfb9f65058105e2cf1ba4c1ffd5d52825 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Thu, 29 Jun 2023 14:50:02 -0700 Subject: [PATCH 4/7] Use timestamp seconds Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index d2c63c1de..f5291f77b 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -36,7 +36,7 @@ func NewPGStatActivityAutovacuumCollector(config collectorConfig) (Collector, er var ( statActivityAutovacuumAgeInSeconds = prometheus.NewDesc( - prometheus.BuildFQName(namespace, statActivityAutovacuumSubsystem, "age_in_seconds"), + prometheus.BuildFQName(namespace, statActivityAutovacuumSubsystem, "timestamp_seconds"), "The age of the vacuum process in seconds", []string{"relname"}, prometheus.Labels{}, @@ -45,7 +45,7 @@ var ( statActivityAutovacuumQuery = ` SELECT SPLIT_PART(query, '.', 2) AS relname, - EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) AS age_in_seconds + EXTRACT(xact_start) AS timestamp_seconds FROM pg_catalog.pg_stat_activity WHERE From 655cc414ea4966fdee5a0192dac793fde29fa756 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Thu, 29 Jun 2023 14:50:52 -0700 Subject: [PATCH 5/7] query formating Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index f5291f77b..3cd2f3993 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -37,19 +37,19 @@ func NewPGStatActivityAutovacuumCollector(config collectorConfig) (Collector, er var ( statActivityAutovacuumAgeInSeconds = prometheus.NewDesc( prometheus.BuildFQName(namespace, statActivityAutovacuumSubsystem, "timestamp_seconds"), - "The age of the vacuum process in seconds", + "Start timestamp of the vacuum process in seconds", []string{"relname"}, prometheus.Labels{}, ) statActivityAutovacuumQuery = ` SELECT - SPLIT_PART(query, '.', 2) AS relname, - EXTRACT(xact_start) AS timestamp_seconds + SPLIT_PART(query, '.', 2) AS relname, + EXTRACT(xact_start) AS timestamp_seconds FROM pg_catalog.pg_stat_activity WHERE - query like 'autovacuum:%' AND + query like 'autovacuum:%' AND EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) > 300 ` ) From 29f4f4aafe7b7cee987044141933bbb568e81478 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Thu, 29 Jun 2023 15:58:35 -0700 Subject: [PATCH 6/7] SQL format Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index 3cd2f3993..4c5f244a2 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -49,7 +49,7 @@ var ( FROM pg_catalog.pg_stat_activity WHERE - query like 'autovacuum:%' AND + query LIKE 'autovacuum:%' AND EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) > 300 ` ) From 50e235b56e2283e5383897f98fe6dc0423008a68 Mon Sep 17 00:00:00 2001 From: Felix Yuan Date: Fri, 14 Jul 2023 09:36:18 -0700 Subject: [PATCH 7/7] Loosen autovacuum query Signed-off-by: Felix Yuan --- collector/pg_stat_activity_autovacuum.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collector/pg_stat_activity_autovacuum.go b/collector/pg_stat_activity_autovacuum.go index 4c5f244a2..5e2d2d2ca 100644 --- a/collector/pg_stat_activity_autovacuum.go +++ b/collector/pg_stat_activity_autovacuum.go @@ -49,8 +49,7 @@ var ( FROM pg_catalog.pg_stat_activity WHERE - query LIKE 'autovacuum:%' AND - EXTRACT(EPOCH FROM (clock_timestamp() - xact_start)) > 300 + query LIKE 'autovacuum:%' ` )