Skip to content

Commit 3f822ad

Browse files
authored
PMM-10631: Add label to mongodb_version_info metric with Edition info (#552)
* PMM-10631: Add label to mongodb_version_info metric with Edition info * PMM-10631: Fix tests * PMM-10631: Add test for testing mongo db version with edition information * PMM-10631: Fix test
1 parent 804443c commit 3f822ad

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

exporter/diagnostic_data_collector_test.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,65 @@ func TestDiagnosticDataCollector(t *testing.T) {
7474
assert.NoError(t, err)
7575
}
7676

77+
func TestDiagnosticDataCollectorWithCompatibleMode(t *testing.T) {
78+
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
79+
defer cancel()
80+
81+
client := tu.DefaultTestClient(ctx, t)
82+
logger := logrus.New()
83+
ti := labelsGetterMock{}
84+
85+
serverVersion, err := getMongoDBVersion(t, client, ctx, logger)
86+
if err != nil {
87+
assert.Fail(t, err.Error())
88+
return
89+
}
90+
91+
c := newDiagnosticDataCollector(ctx, client, logger, true, ti)
92+
93+
// The last \n at the end of this string is important
94+
expected := strings.NewReader(fmt.Sprintf(`
95+
# HELP mongodb_version_info The server version
96+
# TYPE mongodb_version_info gauge
97+
mongodb_version_info{edition="Community",mongodb="%s"} 1`, serverVersion) + "\n")
98+
99+
// Filter metrics for 2 reasons:
100+
// 1. The result is huge
101+
// 2. We need to check against know values. Don't use metrics that return counters like uptime
102+
// or counters like the number of transactions because they won't return a known value to compare
103+
filter := []string{
104+
"mongodb_version_info",
105+
}
106+
107+
err = testutil.CollectAndCompare(c, expected, filter...)
108+
assert.NoError(t, err)
109+
}
110+
111+
func getMongoDBVersion(t *testing.T, client *mongo.Client, ctx context.Context, logger *logrus.Logger) (string, error) {
112+
var m bson.M
113+
cmd := bson.D{{Key: "getDiagnosticData", Value: "1"}}
114+
res := client.Database("admin").RunCommand(ctx, cmd)
115+
if res.Err() != nil {
116+
return "", res.Err()
117+
}
118+
119+
if err := res.Decode(&m); err != nil {
120+
logger.Errorf("cannot run getDiagnosticData: %s", err)
121+
}
122+
123+
m, ok := m["data"].(bson.M)
124+
if !ok {
125+
return "", errors.New("cannot decode getDiagnosticData")
126+
}
127+
128+
v := walkTo(m, []string{"serverStatus", "version"})
129+
serverVersion, ok := v.(string)
130+
if !ok {
131+
serverVersion = "server version is unavailable"
132+
}
133+
return serverVersion, nil
134+
}
135+
77136
func TestAllDiagnosticDataCollectorMetrics(t *testing.T) {
78137
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
79138
defer cancel()
@@ -229,7 +288,7 @@ func TestDisconnectedDiagnosticDataCollector(t *testing.T) {
229288
mongodb_mongod_storage_engine{engine="Engine is unavailable"} 1
230289
# HELP mongodb_version_info The server version
231290
# TYPE mongodb_version_info gauge
232-
mongodb_version_info{mongodb="server version is unavailable"} 1` + "\n")
291+
mongodb_version_info{edition="",mongodb="server version is unavailable"} 1` + "\n")
233292
// Filter metrics for 2 reasons:
234293
// 1. The result is huge
235294
// 2. We need to check against know values. Don't use metrics that return counters like uptime

exporter/v1_compatibility.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -783,8 +783,13 @@ func specialMetrics(ctx context.Context, client *mongo.Client, m bson.M, l *logr
783783
metrics = append(metrics, metric)
784784
}
785785

786+
edition, err := retrieveMongoDBEdition(ctx, client, l)
787+
if err != nil {
788+
l.Warnf("cannot retreive MongoDB edition: %s", err)
789+
}
790+
786791
metrics = append(metrics, storageEngine(m))
787-
metrics = append(metrics, serverVersion(m))
792+
metrics = append(metrics, serverVersion(m, edition))
788793
metrics = append(metrics, myState(ctx, client))
789794

790795
if mm := replSetMetrics(m); mm != nil {
@@ -800,6 +805,30 @@ func specialMetrics(ctx context.Context, client *mongo.Client, m bson.M, l *logr
800805
return metrics
801806
}
802807

808+
func retrieveMongoDBEdition(ctx context.Context, client *mongo.Client, l *logrus.Logger) (string, error) {
809+
buildInfoCmd := bson.D{bson.E{Key: "buildInfo", Value: 1}}
810+
res := client.Database("admin").RunCommand(ctx, buildInfoCmd)
811+
812+
var buildInfoDoc bson.M
813+
err := res.Decode(&buildInfoDoc)
814+
if err != nil {
815+
return "", errors.Wrap(err, "Failed to run buildInfo command")
816+
}
817+
818+
var edition string
819+
modules, ok := buildInfoDoc["modules"].(bson.A)
820+
if !ok {
821+
return "", errors.Wrap(err, "Failed to cast module information variable")
822+
}
823+
if len(modules) > 0 && modules[0].(string) == "enterprise" {
824+
edition = "Enterprise"
825+
} else {
826+
edition = "Community"
827+
}
828+
l.Debug("MongoDB edition: ", edition)
829+
return edition, nil
830+
}
831+
803832
func storageEngine(m bson.M) prometheus.Metric {
804833
v := walkTo(m, []string{"serverStatus", "storageEngine", "name"})
805834
name := "mongodb_mongod_storage_engine"
@@ -817,7 +846,7 @@ func storageEngine(m bson.M) prometheus.Metric {
817846
return metric
818847
}
819848

820-
func serverVersion(m bson.M) prometheus.Metric {
849+
func serverVersion(m bson.M, edition string) prometheus.Metric {
821850
v := walkTo(m, []string{"serverStatus", "version"})
822851
name := "mongodb_version_info"
823852
help := "The server version"
@@ -826,7 +855,7 @@ func serverVersion(m bson.M) prometheus.Metric {
826855
if !ok {
827856
serverVersion = "server version is unavailable"
828857
}
829-
labels := map[string]string{"mongodb": serverVersion}
858+
labels := map[string]string{"mongodb": serverVersion, "edition": edition}
830859

831860
d := prometheus.NewDesc(name, help, nil, labels)
832861
metric, _ := prometheus.NewConstMetric(d, prometheus.GaugeValue, float64(1))

0 commit comments

Comments
 (0)