示例#1
0
func New(proto, addr string, em *mail.Email, mons []monitors.Monitor) (monitors.Monitor, error) {
	a := new(Alive)
	var err error
	a.ln, err = net.Listen(proto, addr)
	if err != nil {
		return nil, e.Forward(err)
	}

	a.monitoring = true
	a.email = em
	a.status = status.NewStatuses("alive", em, definitions.LengthStatusHistory, status.NewStatus, nil, nil)

	multi, err := utilNet.Multi(registerChannels(mons))
	if err != nil {
		return nil, e.Forward(err)
	}

	go func() {
		for {
			conn, err := a.ln.Accept()
			if err != nil {
				a.status.Log(status.Protocol, "Accept connection failed: %v", e.Trace(e.Forward(err)))
				return
			}
			go func(conn net.Conn) {
				a.status.Log(status.Verbose, "Received a connection from %v", conn.RemoteAddr())
				multi.Add(conn)
			}(conn)
		}
	}()
	return a, nil
}
示例#2
0
func New(name, disk string, sleep int, minfree float32, em *mail.Email, alarm time.Duration) monitors.Monitor {
	if alarm == 0 {
		alarm = Alarm
	}
	dm := &Disk{
		MonitorBase:  base.New(),
		name:         name,
		disk:         disk,
		close:        make(chan bool),
		alertPeriode: alarm,
		email:        em,
		monitoring:   true,
	}

	dm.status = status.NewStatuses(name, em, definitions.LengthStatusHistory, status.NewStatus, dm.SendEvent, nil)

	go func() {
		for {
			select {
			case <-time.After(time.Duration(sleep) * time.Second):
				d, err := event.ProbeDisk(disk)
				if err != nil {
					dm.status.Log(status.Verbose, "DiskSpace failed with error: %v", e.Trace(e.Forward(err)))
					continue
				}
				percent := (float32(d.Free) / float32(d.Total)) * 100.0
				if percent < minfree {
					if dm.alert.Before(time.Now()) {
						dm.alert = time.Now().Add(dm.alertPeriode)
						dm.status.LogAndEmail(status.Normal, "Disk limit ["+disk+"]", "Disk %v is %.4f%% free.", disk, round.RoundDec32(percent, 4))
					}
				} else {
					if dm.alert.After(time.Now()) {
						dm.status.LogAndEmail(status.Normal, "Disk limit ["+disk+"]", "Disk %v is %.4f%% free.", disk, round.RoundDec32(percent, 4))
					}
					dm.alert = time.Time{}
				}
				dm.SendEvent(d)
			case <-dm.close:
				break
			}
		}
		dm.status.Log(status.Normal, "Disk monitor stopped for %v.", name)
	}()
	return dm
}
示例#3
0
func Init(d *Daemon) (monitors.Monitor, error) {
	pid, err := util.ReadPidInt(d.PidFile)
	if err != nil && !e.Contains(err, "no such file or directory") {
		return nil, e.Forward(err)
	}

	if d.DaemonName == "" {
		return nil, e.New("empty daemon name")
	}
	if d.RestartCmd == "" {
		return nil, e.New("empty restart command")
	}
	if d.RestartArgs == nil {
		return nil, e.New("restart arguments is invalid")
	}
	if d.PidFile == "" {
		return nil, e.New("empty pid file")
	}
	if d.Sleep <= 0 {
		return nil, e.New("sleep is equal or less than zero")
	}
	if d.Tries < 0 {
		return nil, e.New("tries is equal or less than zero")
	}
	if d.Prio < 0 {
		return nil, e.New("prio have to be greater or equal to zero")
	}
	if d.Queue == nil {
		return nil, e.New("invalid queue")
	}
	if d.ExecTimeout <= 0 {
		return nil, e.New("exectution timeout is greater than zero")
	}

	d.MonitorBase = base.New()
	d.pid = pid
	d.killMonitor = make(chan bool)
	d.running = true
	d.status = status.NewStatuses(d.DaemonName, d.Email, definitions.LengthStatusHistory, status.NewStatus, d.SendEvent, nil)

	d.fswatcher, err = fsnotify.NewWatcher()
	if err != nil {
		return nil, e.Forward(err)
	}
	go func() {
	F:
		for {
			select {
			case ev := <-d.fswatcher.Event:
				if ev == nil {
					//watcher closed
					return
				}
				if ev.Name != d.PidFile {
					continue F
				}
				if ev.IsDelete() {
					d.pid = -1
				} else if !(ev.IsCreate() && ev.IsModify()) {
					continue F
				}
				d.changePid()
			case err := <-d.fswatcher.Error:
				if err != nil {
					d.status.Log(status.Verbose, "Pid file %v watcher error: %v", d.PidFile, e.Trace(e.Forward(err)))
				}
			}
		}
	}()

	err = d.fswatcher.Watch(filepath.Dir(d.PidFile))
	if err != nil {
		return nil, e.Push(err, e.New("invalid pid file %v", d.PidFile))
	}

	d.monitor()
	return d, nil
}
示例#4
0
func Init(vs *VirtualServer) (monitors.Monitor, error) {

	if vs.VirtualServerName == "" {
		return nil, e.New("virtual server name empty")
	}
	if vs.PidFile == "" {
		return nil, e.New("pid file is requered")
	}
	if vs.RestartCmd == "" {
		return nil, e.New("empty restart command")
	}
	if vs.RestartArgs == nil {
		return nil, e.New("invalid restart command arguments")
	}
	if vs.MonitorUrl == nil {
		return nil, e.New("invalid monitor url")
	}
	if vs.Sleep <= 0 {
		return nil, e.New("sleep must be zero or greater value")
	}
	if vs.Tries < 0 {
		return nil, e.New("tries must be zero or greater value")
	}
	if vs.Email == nil {
		return nil, e.New("invalid email struct")
	}
	if vs.ForceKillCmd == "" {
		return nil, e.New("invalid force kill command")
	}
	if vs.ForceKillArgs == nil {
		return nil, e.New("invalid force kill arguments")
	}
	if vs.BeforeStartCmd == "" {
		return nil, e.New("invalid before star command")
	}
	if vs.BeforeStartArgs == nil {
		return nil, e.New("invalid before star arguments")
	}
	if vs.Prio < 0 {
		return nil, e.New("priority must be equal or greater than zero")
	}
	if vs.Queue == nil {
		return nil, e.New("invalid queue struct")
	}
	if vs.ExecTimeout <= 0 {
		return nil, e.New("exec timeout must be greater than zero")
	}

	vs.MonitorBase = base.New()
	vs.monitoring = true
	vs.close = make(chan bool)
	vs.status = status.NewStatuses(vs.VirtualServerName, vs.Email, definitions.LengthStatusHistory, status.NewStatus, vs.SendEvent, nil)
	st := status.NewStatuses(vs.VirtualServerName, vs.Email, definitions.LengthStatusHistory, status.NewStatus, nil, nil)

	vs.alive = &Alive{
		Url:      vs.MonitorUrl,
		Wait:     vs.ConnWait,
		Tries:    vs.ConnTries,
		Statuses: st,
	}

	vs.alive.Connect()

	go func() {
		events := vs.alive.Events()
		for {
			event := <-events
			if event == nil {
				return
			}
			st.Log(status.Normal, "Mensage from %v [%v]", event.Host(), event)
		}
	}()

	go func() {
		unmonitor := true
		tries := 0
	F:
		for {
			select {
			case <-time.After(vs.Sleep):
				if vs.Tries != 0 && tries > vs.Tries+1 {
					vs.monitoring = false
					if unmonitor {
						vs.status.LogAndEmail(status.Normal, "Unmonitor server %v.", vs.VirtualServerName)
						unmonitor = false
						continue F
					}
					continue F
				}

				if vs.alive.Is() {
					tries = 0
					vs.status.Log(status.Verbose, "%v server is running.", vs.VirtualServerName)
					continue F
				}

				tries++

				vs.status.Log(status.Verbose, "Monitor: Alive for %v failed", vs.VirtualServerName)

				err := vs.SendToQueue(func() error {
					vs.status.Log(status.Verbose, "Restarting %v...", vs.VirtualServerName)
					err := vs.restart()
					if err != nil {
						vs.status.Log(status.Verbose, "Monitor failed to restart %v. Forcing restart.", vs.VirtualServerName)
						err := vs.forceRestart()
						if err != nil {
							vs.status.Log(status.Verbose, "Monitor failed to force restart %v. Giving up! Failed: %v", vs.VirtualServerName, e.Trace(e.Forward(err)))
							return e.Forward(err)
						}
					}
					return nil
				})
				if err != nil {
					vs.status.Log(status.Verbose, "%v failed to send job to queue, error: %v", vs.VirtualServerName, e.Trace(e.Forward(err)))
					continue F
				}

				if !vs.alive.Is() {
					vs.SendToQueue(func() error {
						err = vs.forceRestart()
						if err != nil {
							vs.status.Log(status.Verbose, "Monitor failed to force restart %v. Giving up! Failed: %v", vs.VirtualServerName, e.Trace(e.Forward(err)))
							return e.Forward(err)
						}
						return nil
					})
				}
			case <-vs.close:
				return
			}
		}
	}()
	return vs, nil
}