func GetAllMonitors() []Monitor { var monitors []Monitor err := monitorCollection.Find(bson.M{}).All(&monitors) if err != nil { logger.Red("monitor", "Error getting monitors from Mongo: %s", err.Error()) } return monitors }
func GetMonitor(id string) (Monitor, error) { var monitor Monitor if !bson.IsObjectIdHex(id) { return monitor, ErrorInvalidId } err := monitorCollection.FindId(bson.ObjectIdHex(id)).One(&monitor) if err != nil { logger.Red("monitor", "Error getting monitors from Mongo: %s", err.Error()) return monitor, err } return monitor, nil }
func ListenLoop() { // Set maximum packet size to 9000 to support jumbo frames readBytes := make([]byte, 9000) for { _, peer, err := conn.ReadFrom(readBytes) if err != nil { logger.Red("icmpping", err.Error()) time.Sleep(5 * time.Second) continue } packet := gopacket.NewPacket(readBytes, layers.LayerTypeICMPv4, gopacket.NoCopy) ll := packet.Layers() if len(ll) > 0 && ll[0].LayerType() == layers.LayerTypeICMPv4 { icmp := ll[0].(*layers.ICMPv4) typ := uint8(icmp.TypeCode >> 8) if typ == layers.ICMPv4TypeDestinationUnreachable { if len(ll) > 1 { id, _ := decodeUnreachable(ll[1].LayerContents()) activeLock.RLock() ch, found := active[id] activeLock.RUnlock() if found { ch <- IcmpReply{Source: peer.String(), Status: Unreachable} continue } } } else if typ == layers.ICMPv4TypeEchoReply { activeLock.RLock() ch, found := active[icmp.Id] activeLock.RUnlock() if found { ch <- IcmpReply{Source: peer.String(), Status: Reply} continue } } } } }
func Loop(wg sync.WaitGroup) { _, err := GetHost("000000000000000000000000") if err != nil { p, found := plugins.GetPlugin("localtransport") if !found { logger.Red("monitor", "localtransport plugin not found") } host := Host{ Id: bson.ObjectIdHex("000000000000000000000000"), Name: "localhost", TransportId: "localtransport", Transport: p().(plugins.Transport), } hostCollection.Insert(host) logger.Yellow("monitor", "Added localhost transport with id %s", host.Id.String()) } ticker := time.Tick(time.Millisecond * 100) inFlight := make(map[bson.ObjectId]bool) inFlightLock := sync.RWMutex{} for t := range ticker { var monitors []Monitor err := monitorCollection.Find(bson.M{}).All(&monitors) if err != nil { logger.Red("monitor", "Error getting monitors from Mongo: %s", err.Error()) continue } for _, mon := range monitors { age := t.Sub(mon.LastCheck) // positive: past wait := mon.NextCheck.Sub(t) // positive: future inFlightLock.RLock() _, found := inFlight[mon.Id] inFlightLock.RUnlock() if found { // skipping monitors in flight } else if age > mon.Interval*2 && wait < -mon.Interval { checkIn := time.Duration(rand.Int63n(int64(mon.Interval))) mon.NextCheck = t.Add(checkIn) logger.Yellow("monitor", "%s %s: Delaying first check by %s", mon.Id.Hex(), mon.Agent.AgentId, checkIn) err = UpdateMonitor(&mon) if err != nil { logger.Red("Error updating: %v", err.Error()) } } else if wait < 0 { inFlightLock.Lock() inFlight[mon.Id] = true inFlightLock.Unlock() go func(mon Monitor) { var host Host hostCollection.FindId(mon.HostId).One(&host) r := mon.Agent.Run(host.Transport) if r.Status == plugins.Ok { logger.Green("monitor", "%s %s: %s [%s]: %s", mon.Id.Hex(), mon.Agent.AgentId, r.Text, r.Duration, r.Measurements) } else { logger.Red("monitor", "%s %s: %s [%s]", mon.Id.Hex(), mon.Agent.AgentId, r.Text, r.Duration) } mon.LastResult = r mon.LastCheck = t mon.NextCheck = t.Add(mon.Interval) err = UpdateMonitor(&mon) if err != nil { logger.Red("monitor", "Error updating: %s", err.Error()) } inFlightLock.Lock() delete(inFlight, mon.Id) inFlightLock.Unlock() }(mon) } } } wg.Done() }