From a117a224a35c7236aae792519183aed26f026b7b Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 14:44:27 -0300 Subject: [PATCH 01/19] PMM-13141 Added feature compatibility version collector --- exporter/exporter.go | 11 ++ ...feature_compatibility_version_collector.go | 103 ++++++++++++++++++ ...re_compatibility_version_collector_test.go | 85 +++++++++++++++ main.go | 8 +- 4 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 exporter/feature_compatibility_version_collector.go create mode 100644 exporter/feature_compatibility_version_collector_test.go diff --git a/exporter/exporter.go b/exporter/exporter.go index 9a483f46a..704094897 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -70,6 +70,9 @@ type Opts struct { EnableCollStats bool EnableProfile bool EnableShards bool + EnableFCV bool // Feature Compatibility Version. + + FCVInterval time.Duration EnableOverrideDescendingIndex bool @@ -161,6 +164,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol e.opts.EnableCurrentopMetrics = true e.opts.EnableProfile = true e.opts.EnableShards = true + e.opts.EnableFCV = true } // arbiter only have isMaster privileges @@ -234,6 +238,11 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol registry.MustRegister(sc) } + if e.opts.EnableFCV { + fcvc := newFeatureCompatibilityCollector(ctx, client, e.opts.Logger, e.opts.FCVInterval) + registry.MustRegister(fcvc) + } + return registry } @@ -310,6 +319,8 @@ func (e *Exporter) Handler() http.Handler { requestOpts.EnableProfile = true case "shards": requestOpts.EnableShards = true + case "fcv": + requestOpts.EnableFCV = true } } diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go new file mode 100644 index 000000000..ca70b5c58 --- /dev/null +++ b/exporter/feature_compatibility_version_collector.go @@ -0,0 +1,103 @@ +// mongodb_exporter +// Copyright (C) 2017 Percona LLC +// +// 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 exporter + +import ( + "context" + "fmt" + "strconv" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/sirupsen/logrus" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" +) + +const ( + compatibilityModeOff = false // Only used in getDiagnosticData. +) + +type featureCompatibilityCollector struct { + ctx context.Context + base *baseCollector + + now func() time.Time + lock *sync.Mutex + scrapeInterval time.Duration + lastScrape time.Time + lastCollectedMetrics primitive.M +} + +// newProfileCollector creates a collector for being processed queries. +func newFeatureCompatibilityCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, scrapeInterval time.Duration) *featureCompatibilityCollector { + return &featureCompatibilityCollector{ + ctx: ctx, + base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "featureCompatibility"})), + lock: &sync.Mutex{}, + scrapeInterval: scrapeInterval, + lastScrape: time.Time{}, + lastCollectedMetrics: primitive.M{}, + now: func() time.Time { + return time.Now() + }, + } +} + +func (d *featureCompatibilityCollector) Describe(ch chan<- *prometheus.Desc) { + d.base.Describe(d.ctx, ch, d.collect) +} + +func (d *featureCompatibilityCollector) Collect(ch chan<- prometheus.Metric) { + d.base.Collect(ch) +} + +func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { + defer measureCollectTime(ch, "mongodb", "profile")() + + d.lock.Lock() + defer d.lock.Unlock() + + if d.lastScrape.Add(d.scrapeInterval).Before(d.now()) { + cmd := bson.D{{"getParameter", 1}, {"featureCompatibilityVersion", 1}} + res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) + + m := make(map[string]interface{}) + if err := res.Decode(&m); err != nil { + ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) + return + } + + d.lastScrape = d.now() + + rawValue := walkTo(m, []string{"featureCompatibilityVersion", "version"}) + if rawValue != nil { + version, err := strconv.ParseFloat(fmt.Sprintf("%v", rawValue), 64) + if err != nil { + ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) + return + } + d.lastCollectedMetrics = primitive.M{"featureCompatibilityVersion": version} + } + } + + labels := map[string]string{"last_scrape": d.lastScrape.Format(time.DateTime)} + for _, metric := range makeMetrics("fcv", d.lastCollectedMetrics, labels, compatibilityModeOff) { + ch <- metric + } +} diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go new file mode 100644 index 000000000..ec7f0fbff --- /dev/null +++ b/exporter/feature_compatibility_version_collector_test.go @@ -0,0 +1,85 @@ +// mongodb_exporter +// Copyright (C) 2017 Percona LLC +// +// 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 exporter + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/percona/mongodb_exporter/internal/tu" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func TestFCVCollector(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + client := tu.DefaultTestClient(ctx, t) + + database := client.Database("testdb") + database.Drop(ctx) //nolint:errcheck + defer database.Drop(ctx) //nolint:errcheck + + interval := 5 * time.Second + + c := newFeatureCompatibilityCollector(ctx, client, logrus.New(), interval) + c.now = func() time.Time { + return time.Date(2024, 06, 14, 00, 00, 00, 00, time.UTC) + } + + // The last \n at the end of this string is important + expected := strings.NewReader(` +# HELP mongodb_fcv_featureCompatibilityVersion fcv. +# TYPE mongodb_fcv_featureCompatibilityVersion untyped +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + + "\n") + + filter := []string{ + "mongodb_fcv_featureCompatibilityVersion", + } + err := testutil.CollectAndCompare(c, expected, filter...) + assert.NoError(t, err) + + // Less than 5 seconds, it should return the last scraped values. + c.now = func() time.Time { + return time.Date(2024, 06, 14, 00, 00, 04, 00, time.UTC) + } + + expected = strings.NewReader(` +# HELP mongodb_fcv_featureCompatibilityVersion fcv. +# TYPE mongodb_fcv_featureCompatibilityVersion untyped +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + + "\n") + err = testutil.CollectAndCompare(c, expected, filter...) + assert.NoError(t, err) + + // After more than 5 seconds there should be a new scrape. + c.now = func() time.Time { + return time.Date(2024, 06, 14, 00, 00, 06, 00, time.UTC) + } + expected = strings.NewReader(` +# HELP mongodb_fcv_featureCompatibilityVersion fcv. +# TYPE mongodb_fcv_featureCompatibilityVersion untyped +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} 4` + + "\n") + + err = testutil.CollectAndCompare(c, expected, filter...) + assert.NoError(t, err) +} diff --git a/main.go b/main.go index 3add06b94..60175362f 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ import ( "fmt" "regexp" "strings" + "time" "github.com/alecthomas/kong" "github.com/sirupsen/logrus" @@ -58,7 +59,10 @@ type GlobalFlags struct { EnableIndexStats bool `name:"collector.indexstats" help:"Enable collecting metrics from $indexStats"` EnableCollStats bool `name:"collector.collstats" help:"Enable collecting metrics from $collStats"` EnableProfile bool `name:"collector.profile" help:"Enable collecting metrics from profile"` - EnableShards bool `help:"Enable collecting metrics from sharded Mongo clusters about chunks" name:"collector.shards"` + EnableShards bool `name:"collector.shards" help:"Enable collecting metrics from sharded Mongo clusters about chunks"` + + EnableFCV bool `name:"collector.fcv" help:"Enable Feature Compatibility Version collector"` + FCVInterval time.Duration `help:"Feature Compatibility Version collector interval" name:"fcv-interval"` EnableOverrideDescendingIndex bool `name:"metrics.overridedescendingindex" help:"Enable descending index name override to replace -1 with _DESC"` @@ -157,7 +161,9 @@ func buildExporter(opts GlobalFlags, uri string, log *logrus.Logger) *exporter.E EnableCollStats: opts.EnableCollStats, EnableProfile: opts.EnableProfile, EnableShards: opts.EnableShards, + EnableFCV: opts.EnableFCV, + FCVInterval: opts.FCVInterval, EnableOverrideDescendingIndex: opts.EnableOverrideDescendingIndex, CollStatsLimit: opts.CollStatsLimit, From c101dbb683a12a976ff95427423ed7420ad253a2 Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 15:15:23 -0300 Subject: [PATCH 02/19] PMM-13141 Fixed testing mongo version --- docker-compose.yml | 26 +++++++++---------- ...re_compatibility_version_collector_test.go | 6 ++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 411c0964a..037b3beff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.8' services: mongo-1-1: container_name: "mongo-1-1" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_S1_PRIMARY_PORT:-17001}:27017" command: mongod --replSet rs1 --shardsvr --port 27017 --oplogSize 16 --bind_ip 0.0.0.0 @@ -15,7 +15,7 @@ services: mongo-1-2: container_name: "mongo-1-2" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_S1_SECONDARY1_PORT:-17002}:27017" command: mongod --replSet rs1 --shardsvr --port 27017 --oplogSize 16 --bind_ip 0.0.0.0 @@ -24,7 +24,7 @@ services: mongo-1-3: container_name: "mongo-1-3" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_S1_SECONDARY2_PORT:-17003}:27017" command: mongod --replSet rs1 --shardsvr --port 27017 --oplogSize 16 --bind_ip 0.0.0.0 @@ -33,7 +33,7 @@ services: mongo-1-arbiter: container_name: "mongo-1-arbiter" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_S1_ARBITER:-17011}:27017" command: mongod --replSet rs1 --shardsvr --port 27017 --oplogSize 16 @@ -42,7 +42,7 @@ services: mongo-rs1-setup: container_name: "mongo-rs1-setup" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} depends_on: - "mongo-1-1" - "mongo-1-2" @@ -114,7 +114,7 @@ services: mongo-rs2-setup: container_name: "mongo-rs2-setup" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} depends_on: - "mongo-2-1" - "mongo-2-2" @@ -138,7 +138,7 @@ services: # Config servers mongo-cnf-2: container_name: "mongo-cnf-2" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_CONFIGSVR1_PORT:-17007}:27017" command: mongod --dbpath /data/db --replSet cnf-serv --configsvr --port 27017 --oplogSize 16 @@ -147,7 +147,7 @@ services: mongo-cnf-3: container_name: "mongo-cnf-3" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_CONFIGSVR2_PORT:-17008}:27017" command: mongod --dbpath /data/db --replSet cnf-serv --configsvr --port 27017 --oplogSize 16 @@ -156,7 +156,7 @@ services: mongo-cnf-1: container_name: "mongo-cnf-1" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_CONFIGSVR3_PORT:-17009}:27017" command: mongod --dbpath /data/db --replSet cnf-serv --configsvr --port 27017 --oplogSize 16 @@ -168,7 +168,7 @@ services: mongo-cnf-setup: container_name: "mongo-cnf-setup" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} depends_on: - "mongo-cnf-1" - "mongo-cnf-2" @@ -188,7 +188,7 @@ services: mongos: container_name: "mongos" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_MONGOS_PORT:-17000}:27017" networks: @@ -204,7 +204,7 @@ services: mongo-shard-setup: container_name: "mongo-shard-setup" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} depends_on: - "mongos" networks: @@ -234,7 +234,7 @@ services: standalone: container_name: "standalone" - image: ${TEST_MONGODB_IMAGE:-mongo:4.2} + image: ${TEST_MONGODB_IMAGE:-mongo:4.4} ports: - "${TEST_MONGODB_STANDALONE_PORT:-27017}:27017" command: mongod --port 27017 --oplogSize 16 diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index ec7f0fbff..a7d7446b1 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -48,7 +48,7 @@ func TestFCVCollector(t *testing.T) { expected := strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` + "\n") filter := []string{ @@ -65,7 +65,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) @@ -77,7 +77,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4` + expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} 4` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} 4.2` + "\n") err = testutil.CollectAndCompare(c, expected, filter...) From 69e32bba6b7fe50ab366bd767687d9699fdce61d Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 15:22:36 -0300 Subject: [PATCH 03/19] PMM-13141 Ran format --- exporter/feature_compatibility_version_collector_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index a7d7446b1..a92d20c9a 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -21,10 +21,11 @@ import ( "testing" "time" - "github.com/percona/mongodb_exporter/internal/tu" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + + "github.com/percona/mongodb_exporter/internal/tu" ) func TestFCVCollector(t *testing.T) { @@ -41,7 +42,7 @@ func TestFCVCollector(t *testing.T) { c := newFeatureCompatibilityCollector(ctx, client, logrus.New(), interval) c.now = func() time.Time { - return time.Date(2024, 06, 14, 00, 00, 00, 00, time.UTC) + return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o0, 0o0, time.UTC) } // The last \n at the end of this string is important @@ -59,7 +60,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` // Less than 5 seconds, it should return the last scraped values. c.now = func() time.Time { - return time.Date(2024, 06, 14, 00, 00, 04, 00, time.UTC) + return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o4, 0o0, time.UTC) } expected = strings.NewReader(` @@ -72,7 +73,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` // After more than 5 seconds there should be a new scrape. c.now = func() time.Time { - return time.Date(2024, 06, 14, 00, 00, 06, 00, time.UTC) + return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o6, 0o0, time.UTC) } expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. From 44d36999cbdbdfd3742ebece4f864b841d4cdbed Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 15:26:19 -0300 Subject: [PATCH 04/19] PMM-13141 Fix for linters --- exporter/feature_compatibility_version_collector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go index ca70b5c58..82970bcfc 100644 --- a/exporter/feature_compatibility_version_collector.go +++ b/exporter/feature_compatibility_version_collector.go @@ -74,7 +74,7 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { defer d.lock.Unlock() if d.lastScrape.Add(d.scrapeInterval).Before(d.now()) { - cmd := bson.D{{"getParameter", 1}, {"featureCompatibilityVersion", 1}} + cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}} res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) m := make(map[string]interface{}) From a249557810063bb8b16314ef02c0295c8cd86055 Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 20:08:17 -0300 Subject: [PATCH 05/19] PMM-13141 Fixed tests for different mdb versions --- ...re_compatibility_version_collector_test.go | 23 +++++++++++++++---- go.mod | 1 + go.sum | 2 ++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index a92d20c9a..5a7795840 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -17,10 +17,12 @@ package exporter import ( "context" + "fmt" "strings" "testing" "time" + "github.com/hashicorp/go-version" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -45,17 +47,30 @@ func TestFCVCollector(t *testing.T) { return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o0, 0o0, time.UTC) } + sversion, _ := getMongoDBVersionInfo(t, "mongo-1-1") + + v, err := version.NewVersion(sversion) + var mversion string + + mmv := fmt.Sprintf("%d.%d", v.Segments()[0], v.Segments()[1]) + switch { + case mmv == "5.0": + mversion = "4.4" + case mmv == "4.4": + mversion = "4.2" + } + // The last \n at the end of this string is important expected := strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + mversion + "\n") filter := []string{ "mongodb_fcv_featureCompatibilityVersion", } - err := testutil.CollectAndCompare(c, expected, filter...) + err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) // Less than 5 seconds, it should return the last scraped values. @@ -66,7 +81,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) @@ -78,7 +93,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} 4.2` expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} 4.2` + +mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) diff --git a/go.mod b/go.mod index 5f3c5fde9..d037fa74d 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/go.sum b/go.sum index f28825300..71cf05bad 100644 --- a/go.sum +++ b/go.sum @@ -141,6 +141,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= From 31f4ef149326a421ce3bc2700cf6ed4327fcebfa Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 20:11:24 -0300 Subject: [PATCH 06/19] PMM-13141 Fix for linters --- go.mod | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d037fa74d..3c1fdec6c 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,8 @@ require ( go.mongodb.org/mongo-driver v1.15.0 ) +require github.com/hashicorp/go-version v1.7.0 + require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -25,7 +27,6 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kr/text v0.2.0 // indirect From 424e2c430b9bb8a37550d4c26332c69515ace4ae Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 20:15:51 -0300 Subject: [PATCH 07/19] PMM-13141 Trigger build From d8e17f22c829eb7c015aab0c99b899df8a4274d3 Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 20:18:53 -0300 Subject: [PATCH 08/19] PMM-13141 Fix for linters --- exporter/feature_compatibility_version_collector_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index 5a7795840..d1a221402 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/percona/mongodb_exporter/internal/tu" ) @@ -50,6 +51,7 @@ func TestFCVCollector(t *testing.T) { sversion, _ := getMongoDBVersionInfo(t, "mongo-1-1") v, err := version.NewVersion(sversion) + require.NoError(t, err) var mversion string mmv := fmt.Sprintf("%d.%d", v.Segments()[0], v.Segments()[1]) From 4dd88ab7021c0d6852f72c1aeb35a91dc5e05df1 Mon Sep 17 00:00:00 2001 From: Carlos Salguero Date: Mon, 17 Jun 2024 21:17:28 -0300 Subject: [PATCH 09/19] PMM-13141 Trigger build From 130fa2ae0f3421a2315e7042c0c85711d0730012 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Mon, 5 Aug 2024 15:30:58 +0300 Subject: [PATCH 10/19] PMM-13141 Removed scrape interval. --- exporter/exporter.go | 4 +-- ...feature_compatibility_version_collector.go | 36 +++++++++---------- ...re_compatibility_version_collector_test.go | 4 +-- main.go | 10 ++---- 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/exporter/exporter.go b/exporter/exporter.go index 704094897..f274e4ce2 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -72,8 +72,6 @@ type Opts struct { EnableShards bool EnableFCV bool // Feature Compatibility Version. - FCVInterval time.Duration - EnableOverrideDescendingIndex bool IndexStatsCollections []string @@ -239,7 +237,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol } if e.opts.EnableFCV { - fcvc := newFeatureCompatibilityCollector(ctx, client, e.opts.Logger, e.opts.FCVInterval) + fcvc := newFeatureCompatibilityCollector(ctx, client, e.opts.Logger) registry.MustRegister(fcvc) } diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go index 82970bcfc..5a54fb967 100644 --- a/exporter/feature_compatibility_version_collector.go +++ b/exporter/feature_compatibility_version_collector.go @@ -39,18 +39,16 @@ type featureCompatibilityCollector struct { now func() time.Time lock *sync.Mutex - scrapeInterval time.Duration lastScrape time.Time lastCollectedMetrics primitive.M } // newProfileCollector creates a collector for being processed queries. -func newFeatureCompatibilityCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, scrapeInterval time.Duration) *featureCompatibilityCollector { +func newFeatureCompatibilityCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger) *featureCompatibilityCollector { return &featureCompatibilityCollector{ ctx: ctx, base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "featureCompatibility"})), lock: &sync.Mutex{}, - scrapeInterval: scrapeInterval, lastScrape: time.Time{}, lastCollectedMetrics: primitive.M{}, now: func() time.Time { @@ -73,27 +71,25 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { d.lock.Lock() defer d.lock.Unlock() - if d.lastScrape.Add(d.scrapeInterval).Before(d.now()) { - cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}} - res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) + cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}} + res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) - m := make(map[string]interface{}) - if err := res.Decode(&m); err != nil { - ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) - return - } + m := make(map[string]interface{}) + if err := res.Decode(&m); err != nil { + ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) + return + } - d.lastScrape = d.now() + d.lastScrape = d.now() - rawValue := walkTo(m, []string{"featureCompatibilityVersion", "version"}) - if rawValue != nil { - version, err := strconv.ParseFloat(fmt.Sprintf("%v", rawValue), 64) - if err != nil { - ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) - return - } - d.lastCollectedMetrics = primitive.M{"featureCompatibilityVersion": version} + rawValue := walkTo(m, []string{"featureCompatibilityVersion", "version"}) + if rawValue != nil { + version, err := strconv.ParseFloat(fmt.Sprintf("%v", rawValue), 64) + if err != nil { + ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) + return } + d.lastCollectedMetrics = primitive.M{"featureCompatibilityVersion": version} } labels := map[string]string{"last_scrape": d.lastScrape.Format(time.DateTime)} diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index d1a221402..ea0e1e895 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -41,9 +41,7 @@ func TestFCVCollector(t *testing.T) { database.Drop(ctx) //nolint:errcheck defer database.Drop(ctx) //nolint:errcheck - interval := 5 * time.Second - - c := newFeatureCompatibilityCollector(ctx, client, logrus.New(), interval) + c := newFeatureCompatibilityCollector(ctx, client, logrus.New()) c.now = func() time.Time { return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o0, 0o0, time.UTC) } diff --git a/main.go b/main.go index 60175362f..a83b0847a 100644 --- a/main.go +++ b/main.go @@ -17,12 +17,10 @@ package main import ( "fmt" - "regexp" - "strings" - "time" - "github.com/alecthomas/kong" "github.com/sirupsen/logrus" + "regexp" + "strings" "github.com/percona/mongodb_exporter/exporter" ) @@ -61,8 +59,7 @@ type GlobalFlags struct { EnableProfile bool `name:"collector.profile" help:"Enable collecting metrics from profile"` EnableShards bool `name:"collector.shards" help:"Enable collecting metrics from sharded Mongo clusters about chunks"` - EnableFCV bool `name:"collector.fcv" help:"Enable Feature Compatibility Version collector"` - FCVInterval time.Duration `help:"Feature Compatibility Version collector interval" name:"fcv-interval"` + EnableFCV bool `name:"collector.fcv" help:"Enable Feature Compatibility Version collector"` EnableOverrideDescendingIndex bool `name:"metrics.overridedescendingindex" help:"Enable descending index name override to replace -1 with _DESC"` @@ -163,7 +160,6 @@ func buildExporter(opts GlobalFlags, uri string, log *logrus.Logger) *exporter.E EnableShards: opts.EnableShards, EnableFCV: opts.EnableFCV, - FCVInterval: opts.FCVInterval, EnableOverrideDescendingIndex: opts.EnableOverrideDescendingIndex, CollStatsLimit: opts.CollStatsLimit, From ba99506ef7cf8d93d2ebe098c785d8c3e9853fad Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Mon, 5 Aug 2024 15:45:08 +0300 Subject: [PATCH 11/19] PMM-13141 Removed last_scrape label. --- exporter/feature_compatibility_version_collector.go | 2 +- exporter/feature_compatibility_version_collector_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go index 5a54fb967..17b8128f7 100644 --- a/exporter/feature_compatibility_version_collector.go +++ b/exporter/feature_compatibility_version_collector.go @@ -92,7 +92,7 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { d.lastCollectedMetrics = primitive.M{"featureCompatibilityVersion": version} } - labels := map[string]string{"last_scrape": d.lastScrape.Format(time.DateTime)} + labels := map[string]string{} for _, metric := range makeMetrics("fcv", d.lastCollectedMetrics, labels, compatibilityModeOff) { ch <- metric } diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index ea0e1e895..eb3c009e5 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -64,7 +64,7 @@ func TestFCVCollector(t *testing.T) { expected := strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + mversion + +mongodb_fcv_featureCompatibilityVersion{} ` + mversion + "\n") filter := []string{ @@ -81,7 +81,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + m expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + mversion + +mongodb_fcv_featureCompatibilityVersion{} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) @@ -93,7 +93,7 @@ mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:00"} ` + m expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{last_scrape="2024-06-14 00:00:06"} ` + mversion + +mongodb_fcv_featureCompatibilityVersion{} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) From 5b6026b4e4cdf2cc1d7456e5929c5d4e9a0c8e38 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 7 Aug 2024 14:48:45 +0300 Subject: [PATCH 12/19] PMM-13141 Fix linters. --- main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index a83b0847a..fa3a95908 100644 --- a/main.go +++ b/main.go @@ -17,11 +17,12 @@ package main import ( "fmt" - "github.com/alecthomas/kong" - "github.com/sirupsen/logrus" "regexp" "strings" + "github.com/alecthomas/kong" + "github.com/sirupsen/logrus" + "github.com/percona/mongodb_exporter/exporter" ) From d35342b3cf20cf09dd2d212663d491d1f18ebe3d Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 00:24:21 +0300 Subject: [PATCH 13/19] PMM-13141 fix test. --- ...feature_compatibility_version_collector.go | 40 ++++--------------- go.mod | 1 + 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go index 17b8128f7..df49f0924 100644 --- a/exporter/feature_compatibility_version_collector.go +++ b/exporter/feature_compatibility_version_collector.go @@ -18,42 +18,23 @@ package exporter import ( "context" "fmt" - "strconv" - "sync" - "time" - "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" -) - -const ( - compatibilityModeOff = false // Only used in getDiagnosticData. + "strconv" ) type featureCompatibilityCollector struct { ctx context.Context base *baseCollector - - now func() time.Time - lock *sync.Mutex - lastScrape time.Time - lastCollectedMetrics primitive.M } // newProfileCollector creates a collector for being processed queries. func newFeatureCompatibilityCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger) *featureCompatibilityCollector { return &featureCompatibilityCollector{ - ctx: ctx, - base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "featureCompatibility"})), - lock: &sync.Mutex{}, - lastScrape: time.Time{}, - lastCollectedMetrics: primitive.M{}, - now: func() time.Time { - return time.Now() - }, + ctx: ctx, + base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "featureCompatibility"})), } } @@ -68,9 +49,6 @@ func (d *featureCompatibilityCollector) Collect(ch chan<- prometheus.Metric) { func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { defer measureCollectTime(ch, "mongodb", "profile")() - d.lock.Lock() - defer d.lock.Unlock() - cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}} res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) @@ -80,20 +58,16 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { return } - d.lastScrape = d.now() - rawValue := walkTo(m, []string{"featureCompatibilityVersion", "version"}) if rawValue != nil { - version, err := strconv.ParseFloat(fmt.Sprintf("%v", rawValue), 64) + versionString := fmt.Sprintf("%v", rawValue) + version, err := strconv.ParseFloat(versionString, 64) if err != nil { ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) return } - d.lastCollectedMetrics = primitive.M{"featureCompatibilityVersion": version} - } - labels := map[string]string{} - for _, metric := range makeMetrics("fcv", d.lastCollectedMetrics, labels, compatibilityModeOff) { - ch <- metric + d := prometheus.NewDesc("mongodb_fcv_feature_compatibility_version", "Feature compatibility version", []string{"version"}, map[string]string{}) + ch <- prometheus.MustNewConstMetric(d, prometheus.GaugeValue, version, versionString) } } diff --git a/go.mod b/go.mod index df0d6897f..dfd7423bb 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( ) require github.com/hashicorp/go-version v1.7.0 + require github.com/percona/percona-backup-mongodb v1.8.1-0.20240814130653-5285f7975ff6 require ( From b0a3b68a49e43f8d14562e72d61ce417d4f0e4df Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 00:34:32 +0300 Subject: [PATCH 14/19] PMM-13141 fix test. --- .../feature_compatibility_version_collector_test.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index eb3c009e5..0e8430cb1 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -42,9 +42,6 @@ func TestFCVCollector(t *testing.T) { defer database.Drop(ctx) //nolint:errcheck c := newFeatureCompatibilityCollector(ctx, client, logrus.New()) - c.now = func() time.Time { - return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o0, 0o0, time.UTC) - } sversion, _ := getMongoDBVersionInfo(t, "mongo-1-1") @@ -73,11 +70,6 @@ mongodb_fcv_featureCompatibilityVersion{} ` + mversion + err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) - // Less than 5 seconds, it should return the last scraped values. - c.now = func() time.Time { - return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o4, 0o0, time.UTC) - } - expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped @@ -86,10 +78,6 @@ mongodb_fcv_featureCompatibilityVersion{} ` + mversion + err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) - // After more than 5 seconds there should be a new scrape. - c.now = func() time.Time { - return time.Date(2024, 0o6, 14, 0o0, 0o0, 0o6, 0o0, time.UTC) - } expected = strings.NewReader(` # HELP mongodb_fcv_featureCompatibilityVersion fcv. # TYPE mongodb_fcv_featureCompatibilityVersion untyped From 642b62182c1d44058b7da0dcd006426fe7e8946f Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 02:21:51 +0300 Subject: [PATCH 15/19] PMM-13141 fix test. --- Makefile | 2 +- exporter/exporter.go | 3 +- exporter/exporter_test.go | 79 +++++++------------ ...feature_compatibility_version_collector.go | 11 ++- 4 files changed, 41 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 23e6c5d7a..a2eed500b 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ REPO ?= percona/$(NAME) GORELEASER_FLAGS ?= UID ?= $(shell id -u) -export TEST_MONGODB_IMAGE?=mongo:4.2 +export TEST_MONGODB_IMAGE?=mongo:4.4 export TEST_MONGODB_ADMIN_USERNAME?= export TEST_MONGODB_ADMIN_PASSWORD?= export TEST_MONGODB_USERNAME?= diff --git a/exporter/exporter.go b/exporter/exporter.go index 8b51531c4..5f991d288 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -180,6 +180,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol e.opts.EnableCurrentopMetrics = false e.opts.EnableProfile = false e.opts.EnableShards = false + e.opts.EnableFCV = false e.opts.EnablePBMMetrics = false } @@ -241,7 +242,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol registry.MustRegister(sc) } - if e.opts.EnableFCV { + if e.opts.EnableFCV && nodeType != typeMongos { fcvc := newFeatureCompatibilityCollector(ctx, client, e.opts.Logger) registry.MustRegister(fcvc) } diff --git a/exporter/exporter_test.go b/exporter/exporter_test.go index 4caad72b4..8f59c48e2 100644 --- a/exporter/exporter_test.go +++ b/exporter/exporter_test.go @@ -199,34 +199,11 @@ func TestMongoS(t *testing.T) { } } -func TestMongoUp(t *testing.T) { - ctx := context.Background() - - exporterOpts := &Opts{ - Logger: logrus.New(), - URI: "mongodb://127.0.0.1:123456/admin", - DirectConnect: true, - GlobalConnPool: false, - CollectAll: true, - } - - client, err := connect(ctx, exporterOpts) - assert.Error(t, err) - - e := New(exporterOpts) - nodeType, _ := getNodeType(ctx, client) - gc := newGeneralCollector(ctx, client, nodeType, e.opts.Logger) - - r := e.makeRegistry(ctx, client, new(labelsGetterMock), *e.opts) - - res := r.Unregister(gc) - assert.Equal(t, true, res) -} - func TestMongoUpMetric(t *testing.T) { ctx := context.Background() type testcase struct { + name string URI string clusterRole string Want int @@ -242,39 +219,41 @@ func TestMongoUpMetric(t *testing.T) { } for _, tc := range testCases { - exporterOpts := &Opts{ - Logger: logrus.New(), - URI: tc.URI, - ConnectTimeoutMS: 200, - DirectConnect: true, - GlobalConnPool: false, - CollectAll: true, - } + t.Run(tc.clusterRole+"/"+tc.URI, func(t *testing.T) { + exporterOpts := &Opts{ + Logger: logrus.New(), + URI: tc.URI, + ConnectTimeoutMS: 200, + DirectConnect: true, + GlobalConnPool: false, + CollectAll: true, + } - client, err := connect(ctx, exporterOpts) - if tc.Want == 1 { - assert.NoError(t, err, "Must be able to connect to %s", tc.URI) - } else { - assert.Error(t, err, "Must be unable to connect to %s", tc.URI) - } + client, err := connect(ctx, exporterOpts) + if tc.Want == 1 { + assert.NoError(t, err, "Must be able to connect to %s", tc.URI) + } else { + assert.Error(t, err, "Must be unable to connect to %s", tc.URI) + } - e := New(exporterOpts) - nodeType, _ := getNodeType(ctx, client) - gc := newGeneralCollector(ctx, client, nodeType, e.opts.Logger) - r := e.makeRegistry(ctx, client, new(labelsGetterMock), *e.opts) + e := New(exporterOpts) + nodeType, _ := getNodeType(ctx, client) + gc := newGeneralCollector(ctx, client, nodeType, e.opts.Logger) + r := e.makeRegistry(ctx, client, new(labelsGetterMock), *e.opts) - expected := strings.NewReader(fmt.Sprintf(` + expected := strings.NewReader(fmt.Sprintf(` # HELP mongodb_up Whether MongoDB is up. # TYPE mongodb_up gauge mongodb_up {cluster_role="%s"} %s`, tc.clusterRole, strconv.Itoa(tc.Want)) + "\n") - filter := []string{ - "mongodb_up", - } - err = testutil.CollectAndCompare(gc, expected, filter...) - assert.NoError(t, err, "mongodb_up metric should be %d", tc.Want) + filter := []string{ + "mongodb_up", + } + err = testutil.CollectAndCompare(gc, expected, filter...) + assert.NoError(t, err, "mongodb_up metric should be %d", tc.Want) - res := r.Unregister(gc) - assert.Equal(t, true, res) + res := r.Unregister(gc) + assert.Equal(t, true, res) + }) } } diff --git a/exporter/feature_compatibility_version_collector.go b/exporter/feature_compatibility_version_collector.go index df49f0924..96d996f52 100644 --- a/exporter/feature_compatibility_version_collector.go +++ b/exporter/feature_compatibility_version_collector.go @@ -18,11 +18,12 @@ package exporter import ( "context" "fmt" + "strconv" + "github.com/prometheus/client_golang/prometheus" "github.com/sirupsen/logrus" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" - "strconv" ) type featureCompatibilityCollector struct { @@ -50,10 +51,15 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { defer measureCollectTime(ch, "mongodb", "profile")() cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}} - res := d.base.client.Database("admin").RunCommand(d.ctx, cmd) + client := d.base.client + if client == nil { + return + } + res := client.Database("admin").RunCommand(d.ctx, cmd) m := make(map[string]interface{}) if err := res.Decode(&m); err != nil { + d.base.logger.Errorf("Failed to decode featureCompatibilityVersion: %v", err) ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) return } @@ -63,6 +69,7 @@ func (d *featureCompatibilityCollector) collect(ch chan<- prometheus.Metric) { versionString := fmt.Sprintf("%v", rawValue) version, err := strconv.ParseFloat(versionString, 64) if err != nil { + d.base.logger.Errorf("Failed to parse featureCompatibilityVersion: %v", err) ch <- prometheus.NewInvalidMetric(prometheus.NewInvalidDesc(err), err) return } From 1d9b5b1a00b2d8b5d2e0dfe6bf4d515072ef27c1 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 02:38:09 +0300 Subject: [PATCH 16/19] PMM-13141 fix test. --- ...re_compatibility_version_collector_test.go | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index 0e8430cb1..1f23b4990 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -59,29 +59,29 @@ func TestFCVCollector(t *testing.T) { // The last \n at the end of this string is important expected := strings.NewReader(` -# HELP mongodb_fcv_featureCompatibilityVersion fcv. -# TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{} ` + mversion + +# HELP mongodb_fcv_feature_compatibility_version fcv. +# TYPE mongodb_fcv_feature_compatibility_version untyped +mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") filter := []string{ - "mongodb_fcv_featureCompatibilityVersion", + "mongodb_fcv_feature_compatibility_version", } err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_featureCompatibilityVersion fcv. -# TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{} ` + mversion + +# HELP mongodb_fcv_feature_compatibility_version fcv. +# TYPE mongodb_fcv_feature_compatibility_version untyped +mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_featureCompatibilityVersion fcv. -# TYPE mongodb_fcv_featureCompatibilityVersion untyped -mongodb_fcv_featureCompatibilityVersion{} ` + mversion + +# HELP mongodb_fcv_feature_compatibility_version fcv. +# TYPE mongodb_fcv_feature_compatibility_version untyped +mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) From f4e5cdcc2d5e833eb3a783a263bcd5e3fd8e6068 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 02:41:50 +0300 Subject: [PATCH 17/19] PMM-13141 fix test. --- .../feature_compatibility_version_collector_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index 1f23b4990..e2a54ca1c 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -59,8 +59,8 @@ func TestFCVCollector(t *testing.T) { // The last \n at the end of this string is important expected := strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version fcv. -# TYPE mongodb_fcv_feature_compatibility_version untyped +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") @@ -71,16 +71,16 @@ mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version fcv. -# TYPE mongodb_fcv_feature_compatibility_version untyped +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version fcv. -# TYPE mongodb_fcv_feature_compatibility_version untyped +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + "\n") From 16b28b0595db3ccdff2088dd64ca9a284136169f Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 02:45:34 +0300 Subject: [PATCH 18/19] PMM-13141 fix test. --- exporter/feature_compatibility_version_collector_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index e2a54ca1c..61166ae4c 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -61,7 +61,7 @@ func TestFCVCollector(t *testing.T) { expected := strings.NewReader(` # HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. # TYPE mongodb_fcv_feature_compatibility_version gauge -mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + +mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n") filter := []string{ @@ -73,7 +73,7 @@ mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + expected = strings.NewReader(` # HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. # TYPE mongodb_fcv_feature_compatibility_version gauge -mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + +mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) assert.NoError(t, err) @@ -81,7 +81,7 @@ mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + expected = strings.NewReader(` # HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. # TYPE mongodb_fcv_feature_compatibility_version gauge -mongodb_fcv_feature_compatibility_version{version="` + mmv + `"} ` + mversion + +mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n") err = testutil.CollectAndCompare(c, expected, filter...) From 26288df10acf5f46cee61cf1d705d15fd6672f68 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 02:49:37 +0300 Subject: [PATCH 19/19] PMM-13141 fix test. --- exporter/feature_compatibility_version_collector_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exporter/feature_compatibility_version_collector_test.go b/exporter/feature_compatibility_version_collector_test.go index 61166ae4c..5196a8888 100644 --- a/exporter/feature_compatibility_version_collector_test.go +++ b/exporter/feature_compatibility_version_collector_test.go @@ -59,7 +59,7 @@ func TestFCVCollector(t *testing.T) { // The last \n at the end of this string is important expected := strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version # TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n") @@ -71,7 +71,7 @@ mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversi assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version # TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n") @@ -79,7 +79,7 @@ mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversi assert.NoError(t, err) expected = strings.NewReader(` -# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version. +# HELP mongodb_fcv_feature_compatibility_version Feature compatibility version # TYPE mongodb_fcv_feature_compatibility_version gauge mongodb_fcv_feature_compatibility_version{version="` + mversion + `"} ` + mversion + "\n")