gmon/monitor.go

104 lines
2.4 KiB
Go

package main
import (
"context"
"time"
"github.com/hamburghammer/gmon/alert"
"github.com/hamburghammer/gmon/analyse"
"github.com/hamburghammer/gmon/config"
"github.com/hamburghammer/gmon/stats"
)
// NewMonitoring a constructor for the Monitoring struct.
func NewMonitoring(statsClient stats.Client, notifierClient alert.Notifier, rules config.Rules, interval int) Monitoring {
return Monitoring{statsClient: statsClient, notifierClient: notifierClient, rules: rules, interval: interval, ctx: context.Background()}
}
// Monitoring hold all the configuration to monitor a service.
type Monitoring struct {
statsClient stats.Client
notifierClient alert.Notifier
rules config.Rules
interval int
ctx context.Context
}
// WithContext changes the context of the monitoring struct and returns it.
func (m Monitoring) WithContext(ctx context.Context) Monitoring {
m.ctx = ctx
return m
}
// Monitor the stats -> get, analyse and notify.
// This method can be canceled over the context and can be run in a goroutine if the used
// clients support shared usage.
// It currently monitors CPU, RAM and Disk usage with the given rule set.
// Returns an error if a client operation fails
func (m Monitoring) Monitor() error {
for {
select {
case <-m.ctx.Done():
logPackage.Warnln(m.ctx.Err())
return nil
default:
data, err := m.statsClient.GetData()
if err != nil {
return err
}
var f analyse.Analyser
f = analyse.CPURule{}
f.Analyse(stats.Data{})
m.applyRules(m.rules.GetCPU(), data)
if err != nil {
return err
}
m.applyRules(m.rules.GetDisk(), data)
if err != nil {
return err
}
m.applyRules(m.rules.GetRAM(), data)
if err != nil {
return err
}
time.Sleep(time.Duration(m.interval) * time.Minute)
}
}
}
func (m Monitoring) applyRules(rules []analyse.Analyser, stat stats.Data) error {
for _, rule := range rules {
err := m.applyRule(rule, stat)
if err != nil {
logPackage.Errorln(err)
continue
}
}
return nil
}
func (m Monitoring) applyRule(rule analyse.Analyser, stat stats.Data) error {
if rule.IsDeactivated() {
return nil
}
result, err := rule.Analyse(stat)
if err != nil {
return err
}
logPackage.Infoln(result)
if result.AlertStatus != analyse.StatusOK {
err = m.notifierClient.Notify(alert.Data{Title: result.Title, Message: result.StatusMessage})
if err != nil {
return err
}
}
return nil
}