Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMM-13141 Added feature compatibility version collector #863

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a117a22
PMM-13141 Added feature compatibility version collector
cfsalguero Jun 17, 2024
3b959cb
Merge branch 'main' into PMM-13141_featureCompatibilityVersion
cfsalguero Jun 17, 2024
c101dbb
PMM-13141 Fixed testing mongo version
cfsalguero Jun 17, 2024
dadf241
Merge branch 'PMM-13141_featureCompatibilityVersion' of github.com:cf…
cfsalguero Jun 17, 2024
69e32bb
PMM-13141 Ran format
cfsalguero Jun 17, 2024
44d3699
PMM-13141 Fix for linters
cfsalguero Jun 17, 2024
a249557
PMM-13141 Fixed tests for different mdb versions
cfsalguero Jun 17, 2024
31f4ef1
PMM-13141 Fix for linters
cfsalguero Jun 17, 2024
424e2c4
PMM-13141 Trigger build
cfsalguero Jun 17, 2024
d8e17f2
PMM-13141 Fix for linters
cfsalguero Jun 17, 2024
4dd88ab
PMM-13141 Trigger build
cfsalguero Jun 18, 2024
a797711
Merge branch 'main' into PMM-13141_featureCompatibilityVersion
JiriCtvrtka Jul 4, 2024
6cd943c
Merge branch 'refs/heads/main' into PMM-13141_featureCompatibilityVer…
BupycHuk Aug 5, 2024
130fa2a
PMM-13141 Removed scrape interval.
BupycHuk Aug 5, 2024
ba99506
PMM-13141 Removed last_scrape label.
BupycHuk Aug 5, 2024
5b6026b
PMM-13141 Fix linters.
BupycHuk Aug 7, 2024
73863bd
Merge branch 'main' into PMM-13141_featureCompatibilityVersion
JiriCtvrtka Aug 16, 2024
f9e78d2
Merge branch 'main' into PMM-13141_featureCompatibilityVersion
BupycHuk Sep 4, 2024
a0858ba
Merge branch 'main' into PMM-13141_featureCompatibilityVersion
BupycHuk Sep 10, 2024
d35342b
PMM-13141 fix test.
BupycHuk Sep 10, 2024
b0a3b68
PMM-13141 fix test.
BupycHuk Sep 10, 2024
642b621
PMM-13141 fix test.
BupycHuk Sep 10, 2024
1d9b5b1
PMM-13141 fix test.
BupycHuk Sep 10, 2024
f4e5cdc
PMM-13141 fix test.
BupycHuk Sep 10, 2024
16b28b0
PMM-13141 fix test.
BupycHuk Sep 10, 2024
26288df
PMM-13141 fix test.
BupycHuk Sep 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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?=
Expand Down
26 changes: 13 additions & 13 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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
Expand All @@ -14,7 +14,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
Expand All @@ -23,7 +23,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
Expand All @@ -32,7 +32,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
Expand All @@ -41,7 +41,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"
Expand Down Expand Up @@ -150,7 +150,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"
Expand All @@ -174,7 +174,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
Expand All @@ -183,7 +183,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
Expand All @@ -192,7 +192,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
Expand All @@ -204,7 +204,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"
Expand All @@ -224,7 +224,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:
Expand All @@ -240,7 +240,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:
Expand Down Expand Up @@ -270,7 +270,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
Expand Down
10 changes: 10 additions & 0 deletions exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type Opts struct {
EnableCollStats bool
EnableProfile bool
EnableShards bool
EnableFCV bool // Feature Compatibility Version.

EnableOverrideDescendingIndex bool

Expand Down Expand Up @@ -164,6 +165,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
e.opts.EnablePBMMetrics = true
}

Expand All @@ -178,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
}

Expand Down Expand Up @@ -239,6 +242,11 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol
registry.MustRegister(sc)
}

if e.opts.EnableFCV && nodeType != typeMongos {
fcvc := newFeatureCompatibilityCollector(ctx, client, e.opts.Logger)
registry.MustRegister(fcvc)
}

if e.opts.EnablePBMMetrics && requestOpts.EnablePBMMetrics {
pbmc := newPbmCollector(ctx, client, e.opts.URI, e.opts.Logger)
registry.MustRegister(pbmc)
Expand Down Expand Up @@ -320,6 +328,8 @@ func (e *Exporter) Handler() http.Handler {
requestOpts.EnableProfile = true
case "shards":
requestOpts.EnableShards = true
case "fcv":
requestOpts.EnableFCV = true
case "pbm":
requestOpts.EnablePBMMetrics = true
}
Expand Down
79 changes: 29 additions & 50 deletions exporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
})
}
}
80 changes: 80 additions & 0 deletions exporter/feature_compatibility_version_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// 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"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)

type featureCompatibilityCollector struct {
ctx context.Context
base *baseCollector
}

// 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"})),
}
}

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")()

cmd := bson.D{{Key: "getParameter", Value: 1}, {Key: "featureCompatibilityVersion", Value: 1}}
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
}

rawValue := walkTo(m, []string{"featureCompatibilityVersion", "version"})
if rawValue != nil {
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
}

d := prometheus.NewDesc("mongodb_fcv_feature_compatibility_version", "Feature compatibility version", []string{"version"}, map[string]string{})
ch <- prometheus.MustNewConstMetric(d, prometheus.GaugeValue, version, versionString)
}
}
Loading