Skip to content

Commit 959dc79

Browse files
committed
PMM-13477 Support MongoDB 8.0
1 parent 66ac77f commit 959dc79

File tree

9 files changed

+53
-31
lines changed

9 files changed

+53
-31
lines changed

exporter/exporter.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package exporter
1919
import (
2020
"context"
2121
"fmt"
22+
"go.mongodb.org/mongo-driver/bson"
2223
"net/http"
2324
_ "net/http/pprof"
2425
"strconv"
@@ -129,12 +130,29 @@ func (e *Exporter) getTotalCollectionsCount() int {
129130
return e.totalCollectionsCount
130131
}
131132

133+
type MongoVersion struct {
134+
VersionString string `bson:"version"`
135+
PSMDBVersion string `bson:"psmdbVersion"`
136+
Version []int `bson:"versionArray"`
137+
}
138+
139+
func getMongoVersion(ctx context.Context, client *mongo.Client) (*MongoVersion, error) {
140+
var ver MongoVersion
141+
err := client.Database("admin").RunCommand(ctx, bson.D{{"buildInfo", 1}}).Decode(&ver)
142+
return &ver, err
143+
}
144+
132145
func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topologyInfo labelsGetter, requestOpts Opts) *prometheus.Registry {
133146
registry := prometheus.NewRegistry()
134147

135148
nodeType, err := getNodeType(ctx, client)
136149
if err != nil {
137-
e.logger.Errorf("Registry - Cannot get node type to check if this is a mongos : %s", err)
150+
e.logger.Errorf("Registry - Cannot get node type : %s", err)
151+
}
152+
153+
version, err := getMongoVersion(ctx, client)
154+
if err != nil {
155+
e.logger.Warnf("Registry - Cannot get MongoDB version: %s", err)
138156
}
139157

140158
gc := newGeneralCollector(ctx, client, nodeType, e.opts.Logger)
@@ -234,7 +252,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol
234252
// replSetGetStatus is not supported through mongos.
235253
if e.opts.EnableReplicasetStatus && nodeType != typeMongos && requestOpts.EnableReplicasetStatus {
236254
rsgsc := newReplicationSetStatusCollector(ctx, client, e.opts.Logger,
237-
e.opts.CompatibleMode, topologyInfo)
255+
e.opts.CompatibleMode, topologyInfo, version)
238256
registry.MustRegister(rsgsc)
239257
}
240258

exporter/exporter_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ func TestMongoS(t *testing.T) {
187187

188188
e := New(exporterOpts)
189189

190-
rsgsc := newReplicationSetStatusCollector(ctx, client, e.opts.Logger,
191-
e.opts.CompatibleMode, new(labelsGetterMock))
190+
rsgsc := newReplicationSetStatusCollector(ctx, client, e.opts.Logger, e.opts.CompatibleMode, new(labelsGetterMock), nil)
192191

193192
r := e.makeRegistry(ctx, client, new(labelsGetterMock), *e.opts)
194193

exporter/metrics.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package exporter
1717

1818
import (
19-
"fmt"
2019
"regexp"
2120
"strings"
2221
"time"
@@ -187,15 +186,6 @@ func makeRawMetric(prefix, name string, value interface{}, labels map[string]str
187186
rm.lv = append(rm.lv, name)
188187
}
189188

190-
if name == "start" || name == "end" {
191-
fmt.Println("fqName: ", fqName)
192-
fmt.Println("help: ", help)
193-
fmt.Println("val: ", *f)
194-
fmt.Println("vt: ", metricType)
195-
fmt.Println("ln: ", rm.ln)
196-
fmt.Println("lv: ", rm.lv)
197-
}
198-
199189
return rm, nil
200190
}
201191

exporter/replset_status_collector.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package exporter
1717

1818
import (
1919
"context"
20+
"strings"
2021

2122
"github.com/prometheus/client_golang/prometheus"
2223
"github.com/sirupsen/logrus"
@@ -35,16 +36,19 @@ type replSetGetStatusCollector struct {
3536

3637
compatibleMode bool
3738
topologyInfo labelsGetter
39+
40+
version *MongoVersion
3841
}
3942

4043
// newReplicationSetStatusCollector creates a collector for statistics on replication set.
41-
func newReplicationSetStatusCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, compatible bool, topology labelsGetter) *replSetGetStatusCollector {
44+
func newReplicationSetStatusCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, compatible bool, topology labelsGetter, version *MongoVersion) *replSetGetStatusCollector {
4245
return &replSetGetStatusCollector{
4346
ctx: ctx,
4447
base: newBaseCollector(client, logger.WithFields(logrus.Fields{"collector": "replset_status"})),
4548

4649
compatibleMode: compatible,
4750
topologyInfo: topology,
51+
version: version,
4852
}
4953
}
5054

@@ -81,9 +85,16 @@ func (d *replSetGetStatusCollector) collect(ch chan<- prometheus.Metric) {
8185
logger.Debug("replSetGetStatus result:")
8286
debugResult(logger, m)
8387

84-
for _, metric := range makeMetrics("", m, d.topologyInfo.baseLabels(), d.compatibleMode) {
88+
for _, metric := range makeMetrics("replset", m, d.topologyInfo.baseLabels(), d.compatibleMode) {
8589
ch <- metric
8690
}
91+
if d.compatibleMode && strings.HasPrefix(d.version.VersionString, "8.") {
92+
logger.Infof("collecting compatibility metrics for version %s", d.version.VersionString)
93+
metrics := replSetMetrics(m, logger)
94+
for _, metric := range metrics {
95+
ch <- metric
96+
}
97+
}
8798
}
8899

89100
var _ prometheus.Collector = (*replSetGetStatusCollector)(nil)

exporter/replset_status_collector_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestReplsetStatusCollector(t *testing.T) {
3636

3737
ti := labelsGetterMock{}
3838

39-
c := newReplicationSetStatusCollector(ctx, client, logrus.New(), false, ti)
39+
c := newReplicationSetStatusCollector(ctx, client, logrus.New(), false, ti, nil)
4040

4141
// The last \n at the end of this string is important
4242
expected := strings.NewReader(`
@@ -66,7 +66,7 @@ func TestReplsetStatusCollectorNoSharding(t *testing.T) {
6666

6767
ti := labelsGetterMock{}
6868

69-
c := newReplicationSetStatusCollector(ctx, client, logrus.New(), false, ti)
69+
c := newReplicationSetStatusCollector(ctx, client, logrus.New(), false, ti, nil)
7070

7171
// Replication set metrics should not be generated for unsharded server
7272
count := testutil.CollectAndCount(c)

exporter/secondary_lag_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package exporter
1717

1818
import (
1919
"context"
20+
"github.com/sirupsen/logrus"
2021
"strings"
2122
"testing"
2223
"time"
@@ -126,7 +127,7 @@ func TestSecondaryLag(t *testing.T) {
126127
assert.NoError(t, err)
127128

128129
m, _ = m["data"].(bson.M)
129-
metrics := replSetMetrics(m)
130+
metrics := replSetMetrics(m, logrus.WithField("component", "test"))
130131
var lag prometheus.Metric
131132
for _, m := range metrics {
132133
if strings.HasPrefix(m.Desc().String(), `Desc{fqName: "mongodb_mongod_replset_member_replication_lag"`) {

exporter/topology_info.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (t *topologyInfo) loadLabels(ctx context.Context) error {
103103

104104
t.labels = make(map[string]string)
105105

106-
role, err := getClusterRole(ctx, t.client)
106+
role, err := getClusterRole(ctx, t.client, t.logger)
107107
if err != nil {
108108
return errors.Wrap(err, "cannot get node type for topology info")
109109
}
@@ -157,13 +157,12 @@ func getNodeType(ctx context.Context, client *mongo.Client) (mongoDBNodeType, er
157157
return typeMongod, nil
158158
}
159159

160-
func getClusterRole(ctx context.Context, client *mongo.Client) (string, error) {
160+
func getClusterRole(ctx context.Context, client *mongo.Client, logger *logrus.Entry) (string, error) {
161161
cmdOpts := primitive.M{}
162162
// Not always we can get this info. For example, we cannot get this for hidden hosts so
163163
// if there is an error, just ignore it
164164
res := client.Database("admin").RunCommand(ctx, primitive.D{
165165
{Key: "getCmdLineOpts", Value: 1},
166-
{Key: "recordStats", Value: 1},
167166
})
168167

169168
if res.Err() != nil {
@@ -174,6 +173,9 @@ func getClusterRole(ctx context.Context, client *mongo.Client) (string, error) {
174173
return "", errors.Wrap(err, "cannot decode getCmdLineOpts response")
175174
}
176175

176+
logger.Debug("getCmdLineOpts response:")
177+
debugResult(logger, cmdOpts)
178+
177179
if walkTo(cmdOpts, []string{"parsed", "sharding", "configDB"}) != nil {
178180
return "mongos", nil
179181
}

exporter/topology_info_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ func TestGetClusterRole(t *testing.T) {
136136
require.NoError(t, err)
137137

138138
client := tu.TestClient(ctx, port, t)
139-
nodeType, err := getClusterRole(ctx, client)
139+
logger := logrus.WithField("component", "test")
140+
nodeType, err := getClusterRole(ctx, client, logger)
140141
assert.NoError(t, err)
141142
assert.Equal(t, tc.want, nodeType, fmt.Sprintf("container name: %s, port: %s", tc.containerName, port))
142143
}

exporter/v1_compatibility.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,10 @@ func specialMetrics(ctx context.Context, client *mongo.Client, m bson.M, nodeTyp
812812

813813
if nodeType != typeArbiter {
814814
metrics = append(metrics, myState(ctx, client))
815-
if rm := replSetMetrics(m); rm != nil {
816-
metrics = append(metrics, rm...)
815+
if replSetGetStatus, ok := m["replSetGetStatus"].(bson.M); ok {
816+
if rm := replSetMetrics(replSetGetStatus, l); rm != nil {
817+
metrics = append(metrics, rm...)
818+
}
817819
}
818820

819821
if nodeType != typeMongos {
@@ -982,17 +984,15 @@ func oplogStatus(ctx context.Context, client *mongo.Client) ([]prometheus.Metric
982984
return []prometheus.Metric{headMetric, tailMetric}, nil
983985
}
984986

985-
func replSetMetrics(d bson.M) []prometheus.Metric {
986-
replSetGetStatus, ok := d["replSetGetStatus"].(bson.M)
987-
if !ok {
988-
return nil
989-
}
987+
func replSetMetrics(d bson.M, l *logrus.Entry) []prometheus.Metric {
990988
var repl proto.ReplicaSetStatus
991-
b, err := bson.Marshal(replSetGetStatus)
989+
b, err := bson.Marshal(d)
992990
if err != nil {
991+
l.Warnf("cannot marshal replica set status: %s", err)
993992
return nil
994993
}
995994
if err := bson.Unmarshal(b, &repl); err != nil {
995+
l.Warnf("cannot unmarshal replica set status: %s", err)
996996
return nil
997997
}
998998

0 commit comments

Comments
 (0)