diff --git a/alrmrc b/alrmrc index e512ccc..d353a81 100644 --- a/alrmrc +++ b/alrmrc @@ -9,7 +9,7 @@ monitor group webservers check ping # checks are not named, so multiple is okay monitor host gateway address 10.79.37.220 - check ping + check ping count 10 interval 100ms # Hosts without any checks will always be successful monitor host database address 10.11.135.103 diff --git a/check/check.go b/check/check.go index e5b25d5..2c80ea8 100644 --- a/check/check.go +++ b/check/check.go @@ -12,7 +12,7 @@ type AlrmCheck interface { func NewCheck(name string, addr string) (AlrmCheck, error) { switch name { case "ping": - return &CheckPing{Type: "ping", Address: addr}, nil + return NewCheckPing(addr), nil default: return nil, fmt.Errorf("unknown check name \"%s\"", name) } diff --git a/check/check_ping.go b/check/check_ping.go index e9cb740..29e824b 100644 --- a/check/check_ping.go +++ b/check/check_ping.go @@ -4,6 +4,15 @@ import ( "alrm/check/ping" "fmt" "time" + "strings" + "strconv" +) + +const ( + TK_NONE = iota + TK_COUNT + TK_TIMEOUT + TK_INTERVAL ) type CheckPing struct { @@ -11,6 +20,16 @@ type CheckPing struct { Address string Count int Timeout time.Duration + Interval time.Duration + state int +} + +func NewCheckPing(addr string) *CheckPing { + return &CheckPing{ + Type: "ping", Address: addr, + Count: 1, Timeout: time.Second * 5, + Interval: time.Second, + } } func (c *CheckPing) Check(debuglvl int) error { @@ -23,8 +42,10 @@ func (c *CheckPing) Check(debuglvl int) error { return err } - p.Count = 1 - p.Timeout = time.Second * 5 + p.Count = c.Count + p.Timeout = c.Timeout + p.Interval = c.Interval + err = p.Run() if err != nil { return err @@ -36,11 +57,51 @@ func (c *CheckPing) Check(debuglvl int) error { } if debuglvl > 0 { - fmt.Printf("Ping RTT: %s\n", stats.Rtts[0]) + for i, r := range stats.Rtts { + fmt.Printf("Ping %d: %s\n", i+1, r) + } } return nil } func (c *CheckPing) Parse(tk string) (bool, error) { - return false, nil + var err error + switch c.state { + case TK_NONE: + switch strings.ToLower(tk){ + case "count": + c.state = TK_COUNT + case "timeout": + c.state = TK_TIMEOUT + case "interval": + c.state = TK_INTERVAL + default: + return false, nil + } + + case TK_COUNT: + c.Count, err = strconv.Atoi(tk) + if err != nil { + return false, fmt.Errorf("invalid count \"%s\"", tk) + } + c.state = TK_NONE + + case TK_TIMEOUT: + c.Timeout, err = time.ParseDuration(tk) + if err != nil { + return false, fmt.Errorf("invalid timeout \"%s\"", tk) + } + c.state = TK_NONE + + case TK_INTERVAL: + c.Interval, err = time.ParseDuration(tk) + if err != nil { + return false, fmt.Errorf("invalid interval \"%s\"", tk) + } + c.state = TK_NONE + + default: + return false, fmt.Errorf("invalid state in check_ping") + } + return true, nil } diff --git a/config/parser.go b/config/parser.go index f41f551..99a52e4 100644 --- a/config/parser.go +++ b/config/parser.go @@ -49,14 +49,14 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { p.setState(TK_SET) default: return nil, fmt.Errorf("invalid token in %s, line %d: \"%s\"", - fn, p.Line+1, tk) + fn, p.Line, tk) } case TK_SET: key := strings.ToLower(tk) if !scan.Scan() { return nil, fmt.Errorf("empty value name for set in %s, line %d", - fn, p.Line+1) + fn, p.Line) } value := scan.Text() @@ -66,12 +66,12 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { if err != nil { return nil, fmt.Errorf( "invalid number for interval in %s, line %d: \"%s\"", - fn, p.Line+1, value, + fn, p.Line, value, ) } default: return nil, fmt.Errorf("unknown key for set in %s, line %d: \"%s\"", - fn, p.Line+1, tk, + fn, p.Line, tk, ) } p.prevState() @@ -94,7 +94,7 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { p.lastgroup, err = config.NewGroup(tk) if err != nil { return nil, fmt.Errorf("%s in %s, line %d", - err.Error(), fn, p.Line+1, + err.Error(), fn, p.Line, ) } continue @@ -115,7 +115,7 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { p.lastgroup, err = config.NewGroup(tk) if err != nil { return nil, fmt.Errorf("%s in %s, line %d", - err.Error(), fn, p.Line+1, + err.Error(), fn, p.Line, ) } } @@ -124,7 +124,7 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { p.lasthost, err = p.lastgroup.NewHost(tk) if err != nil { return nil, fmt.Errorf("%s in %s, line %d", - err.Error(), fn, p.Line+1, + err.Error(), fn, p.Line, ) } continue @@ -134,7 +134,7 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { case "address": if !scan.Scan() { return nil, fmt.Errorf("empty address for host in %s, line %d", - fn, p.Line+1) + fn, p.Line) } p.lasthost.Address = scan.Text() @@ -151,13 +151,14 @@ func (p *Parser) Parse(fn string) (*AlrmConfig, error) { p.lastcheck, err = p.lasthost.NewCheck(tk) if err != nil { return nil, fmt.Errorf("%s in %s, line %d", - err.Error(), fn, p.Line+1) + err.Error(), fn, p.Line) } continue } cont, err := p.lastcheck.Parse(tk) if err != nil { - return nil, err + return nil, fmt.Errorf("%s in %s, line %d", + err.Error(), fn, p.Line) } if !cont { p.lastcheck = nil