Skip to content

Commit 3887eab

Browse files
BupycHukademidoff
andauthored
PMM-12350 Fix node type detection. (#782)
* PMM-12350 Fix node type detection. * PMM-12350 Fix node type detection. --------- Co-authored-by: Alex Demidoff <[email protected]>
1 parent 153cdac commit 3887eab

File tree

5 files changed

+32
-49
lines changed

5 files changed

+32
-49
lines changed

exporter/exporter.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol
138138
e.logger.Errorf("Registry - Cannot get node type to check if this is a mongos : %s", err)
139139
}
140140

141-
isArbiter, err := isArbiter(ctx, client)
142-
if err != nil {
143-
e.logger.Errorf("Registry - Cannot get arbiterOnly to check if this is arbiter role : %s", err)
144-
}
145-
146141
// Enable collectors like collstats and indexstats depending on the number of collections
147142
// present in the database.
148143
limitsOk := false
@@ -168,7 +163,7 @@ func (e *Exporter) makeRegistry(ctx context.Context, client *mongo.Client, topol
168163
}
169164

170165
// arbiter only have isMaster privileges
171-
if isArbiter {
166+
if nodeType == typeArbiter {
172167
e.opts.EnableDBStats = false
173168
e.opts.EnableDBStatsFreeStorage = false
174169
e.opts.EnableCollStats = false

exporter/topology_info.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const (
4141
typeMongos mongoDBNodeType = "mongos"
4242
typeMongod mongoDBNodeType = "mongod"
4343
typeShardServer mongoDBNodeType = "shardsvr"
44+
typeArbiter mongoDBNodeType = "arbiter"
4445
typeOther mongoDBNodeType = ""
4546
)
4647

@@ -114,14 +115,14 @@ func (t *topologyInfo) loadLabels(ctx context.Context) error {
114115
t.labels[labelReplicasetName] = rs.Config.ID
115116
}
116117

117-
isArbiter, err := isArbiter(ctx, t.client)
118+
nodeType, err := getNodeType(ctx, t.client)
118119
if err != nil {
119120
return err
120121
}
121122

122123
cid, err := util.ClusterID(ctx, t.client)
123124
if err != nil {
124-
if !isArbiter { // arbiters don't have a cluster ID
125+
if nodeType != typeArbiter { // arbiters don't have a cluster ID
125126
return errors.Wrapf(ErrCannotGetTopologyLabels, "error getting cluster ID: %s", err)
126127
}
127128
}
@@ -136,26 +137,14 @@ func (t *topologyInfo) loadLabels(ctx context.Context) error {
136137
return nil
137138
}
138139

139-
func isArbiter(ctx context.Context, client *mongo.Client) (bool, error) {
140-
doc := struct {
141-
ArbiterOnly bool `bson:"arbiterOnly"`
142-
}{}
143-
144-
if err := client.Database("admin").RunCommand(ctx, primitive.M{"isMaster": 1}).Decode(&doc); err != nil {
145-
return false, errors.Wrap(err, "cannot check if the instance is an arbiter")
146-
}
147-
148-
return doc.ArbiterOnly, nil
149-
}
150-
151140
func getNodeType(ctx context.Context, client *mongo.Client) (mongoDBNodeType, error) {
152141
md := proto.MasterDoc{}
153142
if err := client.Database("admin").RunCommand(ctx, primitive.M{"isMaster": 1}).Decode(&md); err != nil {
154143
return "", err
155144
}
156145

157-
if md.SetName != nil || md.Hosts != nil {
158-
return typeShardServer, nil
146+
if md.ArbiterOnly {
147+
return typeArbiter, nil
159148
} else if md.Msg == typeIsDBGrid {
160149
// isdbgrid is always the msg value when calling isMaster on a mongos
161150
// see http://docs.mongodb.org/manual/core/sharded-cluster-query-router/

exporter/v1_compatibility.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ func specialMetrics(ctx context.Context, client *mongo.Client, m bson.M, l *logr
814814
}).Errorf("Cannot get node type: %s", err)
815815
}
816816

817-
if nodeType == typeMongod {
817+
if nodeType == typeMongod || nodeType == typeArbiter {
818818
if engine, err := storageEngine(m); err != nil {
819819
l.Errorf("cannot retrieve engine type: %s", err)
820820
} else {
@@ -823,8 +823,8 @@ func specialMetrics(ctx context.Context, client *mongo.Client, m bson.M, l *logr
823823
}
824824
metrics = append(metrics, serverVersion(buildInfo))
825825

826-
if isArbiter, _ := isArbiter(ctx, client); isArbiter {
827-
if hm := myRole(ctx, client, l); hm != nil {
826+
if nodeType == typeArbiter {
827+
if hm := arbiterMetrics(ctx, client, l); hm != nil {
828828
metrics = append(metrics, hm...)
829829
}
830830
} else {
@@ -931,34 +931,32 @@ func myState(ctx context.Context, client *mongo.Client) prometheus.Metric {
931931
return metric
932932
}
933933

934-
// myRole returns metrics based on the role of the mongo instance.
935-
func myRole(ctx context.Context, client *mongo.Client, l *logrus.Logger) []prometheus.Metric {
934+
// arbiterMetrics returns metrics for mongoDB arbiter instances.
935+
func arbiterMetrics(ctx context.Context, client *mongo.Client, l *logrus.Logger) []prometheus.Metric {
936936
response, err := util.MyRole(ctx, client)
937937
if err != nil {
938938
l.Errorf("cannot get role of the running instance: %s", err)
939939
return nil
940940
}
941941

942942
var metrics []prometheus.Metric
943-
if response.ArbiterOnly {
944-
createMetric := func(name, help string, value float64, labels map[string]string) {
945-
const prefix = "mongodb_mongod_replset_"
946-
d := prometheus.NewDesc(prefix+name, help, nil, labels)
947-
metrics = append(metrics, prometheus.MustNewConstMetric(d, prometheus.GaugeValue, value))
948-
}
943+
createMetric := func(name, help string, value float64, labels map[string]string) {
944+
const prefix = "mongodb_mongod_replset_"
945+
d := prometheus.NewDesc(prefix+name, help, nil, labels)
946+
metrics = append(metrics, prometheus.MustNewConstMetric(d, prometheus.GaugeValue, value))
947+
}
949948

950-
createMetric("my_state",
951-
"An integer between 0 and 10 that represents the replica state of the current member",
952-
float64(ArbiterState), map[string]string{
953-
"set": response.SetName,
954-
})
949+
createMetric("my_state",
950+
"An integer between 0 and 10 that represents the replica state of the current member",
951+
float64(ArbiterState), map[string]string{
952+
"set": response.SetName,
953+
})
955954

956-
createMetric("number_of_members",
957-
"The number of replica set members.",
958-
float64(len(response.Hosts)+len(response.Arbiters)), map[string]string{
959-
"set": response.SetName,
960-
})
961-
}
955+
createMetric("number_of_members",
956+
"The number of replica set members.",
957+
float64(len(response.Hosts)+len(response.Arbiters)), map[string]string{
958+
"set": response.SetName,
959+
})
962960

963961
return metrics
964962
}

exporter/v1_compatibility_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func TestMyState(t *testing.T) {
260260
}
261261
}
262262

263-
func TestMyRole(t *testing.T) {
263+
func TestArbiterMetrics(t *testing.T) {
264264
t.Parallel()
265265
t.Run("correctly gets member count from arbiter node", func(t *testing.T) {
266266
t.Parallel()
@@ -273,7 +273,7 @@ func TestMyRole(t *testing.T) {
273273
port, err := tu.PortForContainer(containerName)
274274
require.NoError(t, err)
275275
client := tu.TestClient(ctx, port, t)
276-
metrics := myRole(ctx, client, logger)
276+
metrics := arbiterMetrics(ctx, client, logger)
277277
var rsMembers dto.Metric
278278
for _, m := range metrics {
279279
if strings.HasPrefix(m.Desc().String(), `Desc{fqName: "mongodb_mongod_replset_number_of_members"`) {

internal/proto/proto.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
package proto
1717

1818
type MasterDoc struct {
19-
SetName interface{} `bson:"setName"`
20-
Hosts interface{} `bson:"hosts"`
21-
Msg string `bson:"msg"`
19+
SetName interface{} `bson:"setName"`
20+
Hosts interface{} `bson:"hosts"`
21+
Msg string `bson:"msg"`
22+
ArbiterOnly bool `bson:"arbiterOnly"`
2223
}

0 commit comments

Comments
 (0)