// Report collects the stat info for a single node and sends found hostnames on // the "discover" channel if checkShards is true. func (node *NodeMonitor) Poll(discover chan string, checkShards bool) (*status.ServerStatus, error) { stat := &status.ServerStatus{} log.Logvf(log.DebugHigh, "getting session on server: %v", node.host) s, err := node.sessionProvider.GetSession() if err != nil { log.Logvf(log.DebugLow, "got error getting session to server %v", node.host) return nil, err } log.Logvf(log.DebugHigh, "got session on server: %v", node.host) // The read pref for the session must be set to 'secondary' to enable using // the driver with 'direct' connections, which disables the built-in // replset discovery mechanism since we do our own node discovery here. s.SetMode(mgo.Eventual, true) // Disable the socket timeout - otherwise if db.serverStatus() takes a long time on the server // side, the client will close the connection early and report an error. s.SetSocketTimeout(0) defer s.Close() err = s.DB("admin").Run(bson.D{{"serverStatus", 1}, {"recordStats", 0}}, stat) if err != nil { log.Logvf(log.DebugLow, "got error calling serverStatus against server %v", node.host) return nil, err } statMap := make(map[string]interface{}) s.DB("admin").Run(bson.D{{"serverStatus", 1}, {"recordStats", 0}}, statMap) stat.Flattened = status.Flatten(statMap) node.Err = nil stat.SampleTime = time.Now() if stat.Repl != nil && discover != nil { for _, host := range stat.Repl.Hosts { discover <- host } for _, host := range stat.Repl.Passives { discover <- host } } node.alias = stat.Host stat.Host = node.host if discover != nil && stat != nil && status.IsMongos(stat) && checkShards { log.Logvf(log.DebugLow, "checking config database to discover shards") shardCursor := s.DB("config").C("shards").Find(bson.M{}).Iter() shard := ConfigShard{} for shardCursor.Next(&shard) { shardHosts := strings.Split(shard.Host, ",") for _, shardHost := range shardHosts { discover <- shardHost } } shardCursor.Close() } return stat, nil }
func TestIsMongos(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) runCheck := func(process string) bool { return status.IsMongos(&status.ServerStatus{ Process: process, }) } Convey("should accept reasonable process names", t, func() { So(runCheck("/mongos-prod.exe"), ShouldBeTrue) So(runCheck("/mongos.exe"), ShouldBeTrue) So(runCheck("mongos"), ShouldBeTrue) So(runCheck("mongodb/bin/mongos"), ShouldBeTrue) So(runCheck(`C:\data\mci\48de1dc1ec3c2be5dcd6a53739578de4\src\mongos.exe`), ShouldBeTrue) }) Convey("should accept reasonable process names", t, func() { So(runCheck("mongosx/mongod"), ShouldBeFalse) So(runCheck("mongostat"), ShouldBeFalse) So(runCheck("mongos_stuff/mongod"), ShouldBeFalse) So(runCheck("mongos.stuff/mongod"), ShouldBeFalse) So(runCheck("mongodb/bin/mongod"), ShouldBeFalse) }) }