Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
				}
			}
		}
	}
}
Beispiel #4
0
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()
}