changed server to use channels instead of cond for wakeup, removed config hashing, added config path to config struct
This commit is contained in:
parent
d5389caadb
commit
4c16211e89
@ -10,13 +10,16 @@ type Config struct {
|
|||||||
Groups map[string]*Group
|
Groups map[string]*Group
|
||||||
Alarms map[string]alarm.Alarm
|
Alarms map[string]alarm.Alarm
|
||||||
Interval time.Duration
|
Interval time.Duration
|
||||||
Hash string
|
Listen string
|
||||||
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
// Default check interval, 30 seconds
|
// Default check interval, 30 seconds
|
||||||
Interval: time.Second * 30,
|
Interval: time.Second * 30,
|
||||||
|
// Default listen address
|
||||||
|
Listen: "127.0.0.1:8282",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.binarythought.com/cdramey/alrm/alarm"
|
"git.binarythought.com/cdramey/alrm/alarm"
|
||||||
"git.binarythought.com/cdramey/alrm/check"
|
"git.binarythought.com/cdramey/alrm/check"
|
||||||
@ -30,6 +29,7 @@ type Parser struct {
|
|||||||
|
|
||||||
func (p *Parser) Parse(fn string) (*Config, error) {
|
func (p *Parser) Parse(fn string) (*Config, error) {
|
||||||
config := NewConfig()
|
config := NewConfig()
|
||||||
|
config.Path = fn
|
||||||
tok, err := NewTokenizer(fn)
|
tok, err := NewTokenizer(fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -70,6 +70,8 @@ func (p *Parser) Parse(fn string) (*Config, error) {
|
|||||||
fn, tok.Line(), value,
|
fn, tok.Line(), value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
case "listen":
|
||||||
|
config.Listen = value
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown key for set in %s, line %d: \"%s\"",
|
return nil, fmt.Errorf("unknown key for set in %s, line %d: \"%s\"",
|
||||||
fn, tok.Line(), tk,
|
fn, tok.Line(), tk,
|
||||||
@ -200,7 +202,6 @@ func (p *Parser) Parse(fn string) (*Config, error) {
|
|||||||
if err := tok.Err(); err != nil {
|
if err := tok.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.Hash = hex.EncodeToString(tok.Hash.Sum(nil))
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -19,7 +17,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Tokenizer struct {
|
type Tokenizer struct {
|
||||||
Hash hash.Hash
|
|
||||||
curline int
|
curline int
|
||||||
repline int
|
repline int
|
||||||
file *os.File
|
file *os.File
|
||||||
@ -36,7 +33,6 @@ func NewTokenizer(fn string) (*Tokenizer, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tk.Hash = sha256.New()
|
|
||||||
tk.reader = bufio.NewReader(tk.file)
|
tk.reader = bufio.NewReader(tk.file)
|
||||||
return tk, nil
|
return tk, nil
|
||||||
}
|
}
|
||||||
@ -62,7 +58,6 @@ func (t *Tokenizer) Scan() bool {
|
|||||||
t.err = fmt.Errorf("invalid utf-8 encoding on line %s", t.repline)
|
t.err = fmt.Errorf("invalid utf-8 encoding on line %s", t.repline)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
t.Hash.Write([]byte(string(r)))
|
|
||||||
|
|
||||||
switch state {
|
switch state {
|
||||||
case TK_NONE:
|
case TK_NONE:
|
||||||
|
26
main.go
26
main.go
@ -5,26 +5,27 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.binarythought.com/cdramey/alrm/config"
|
"git.binarythought.com/cdramey/alrm/config"
|
||||||
|
"git.binarythought.com/cdramey/alrm/server"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfgPath := flag.String("c", "", "path to configuration file")
|
cfgpath := flag.String("c", "", "path to configuration file")
|
||||||
debuglvl := flag.Int("d", 0, "debug level")
|
debuglvl := flag.Int("d", 0, "debug level")
|
||||||
|
|
||||||
flag.Usage = printUsage
|
flag.Usage = printUsage
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *cfgPath == "" {
|
if *cfgpath == "" {
|
||||||
searchpaths := []string{"/etc/alrmrc", "./alrmrc"}
|
searchpaths := []string{"/etc/alrmrc", "./alrmrc"}
|
||||||
for _, sp := range searchpaths {
|
for _, sp := range searchpaths {
|
||||||
if _, err := os.Stat(sp); err == nil {
|
if _, err := os.Stat(sp); err == nil {
|
||||||
*cfgPath = sp
|
*cfgpath = sp
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *cfgPath == "" {
|
if *cfgpath == "" {
|
||||||
fmt.Fprintf(os.Stderr, "cannot find configuration\n")
|
fmt.Fprintf(os.Stderr, "cannot find configuration\n")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -34,10 +35,10 @@ func main() {
|
|||||||
switch command {
|
switch command {
|
||||||
case "config":
|
case "config":
|
||||||
if *debuglvl > 0 {
|
if *debuglvl > 0 {
|
||||||
fmt.Printf("checking config %s .. \n", *cfgPath)
|
fmt.Printf("checking config %s .. \n", *cfgpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadConfig(*cfgPath, *debuglvl)
|
cfg, err := config.ReadConfig(*cfgpath, *debuglvl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -61,7 +62,7 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadConfig(*cfgPath, 0)
|
cfg, err := config.ReadConfig(*cfgpath, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -90,7 +91,7 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadConfig(*cfgPath, 0)
|
cfg, err := config.ReadConfig(*cfgpath, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -110,17 +111,14 @@ func main() {
|
|||||||
fmt.Printf("check successful\n")
|
fmt.Printf("check successful\n")
|
||||||
|
|
||||||
case "server":
|
case "server":
|
||||||
cfg, err := config.ReadConfig(*cfgPath, *debuglvl)
|
cfg, err := config.ReadConfig(*cfgpath, *debuglvl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = startServer(cfg, *debuglvl)
|
srv := server.NewServer(cfg, *debuglvl)
|
||||||
if err != nil {
|
srv.Start()
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
case "help", "":
|
case "help", "":
|
||||||
printUsage()
|
printUsage()
|
||||||
|
51
server.go
51
server.go
@ -1,51 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.binarythought.com/cdramey/alrm/config"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func startServer(cfg *config.Config, debuglvl int) error {
|
|
||||||
c := sync.NewCond(&sync.Mutex{})
|
|
||||||
for _, g := range cfg.Groups {
|
|
||||||
go worker(g, c, debuglvl)
|
|
||||||
}
|
|
||||||
|
|
||||||
t := time.NewTicker(cfg.Interval)
|
|
||||||
defer t.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case r := <-t.C:
|
|
||||||
if debuglvl > 0 {
|
|
||||||
fmt.Printf("Interval check at %s\n", r)
|
|
||||||
}
|
|
||||||
c.Broadcast()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func worker(g *config.Group, c *sync.Cond, debuglvl int) {
|
|
||||||
for {
|
|
||||||
if debuglvl > 2 {
|
|
||||||
fmt.Printf("%s goroutine waiting.. \n", g.Name)
|
|
||||||
}
|
|
||||||
c.L.Lock()
|
|
||||||
c.Wait()
|
|
||||||
c.L.Unlock()
|
|
||||||
if debuglvl > 2 {
|
|
||||||
fmt.Printf("%s goroutine wake.. \n", g.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, h := range g.Hosts {
|
|
||||||
for _, c := range h.Checks {
|
|
||||||
err := c.Check(debuglvl)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Check error: %s\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
47
server/server.go
Normal file
47
server/server.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.binarythought.com/cdramey/alrm/config"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
workers []*worker
|
||||||
|
cfg *config.Config
|
||||||
|
debuglvl int
|
||||||
|
httpsrv http.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *Server) Start() {
|
||||||
|
for _, w := range srv.workers {
|
||||||
|
go w.start(srv.debuglvl)
|
||||||
|
}
|
||||||
|
|
||||||
|
t := time.NewTicker(srv.cfg.Interval)
|
||||||
|
defer t.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case r := <-t.C:
|
||||||
|
if srv.debuglvl > 0 {
|
||||||
|
fmt.Printf("interval check at %s\n", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, w := range srv.workers {
|
||||||
|
select {
|
||||||
|
case w.wake <- true:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServer(cfg *config.Config, debuglvl int) *Server {
|
||||||
|
srv := &Server{cfg: cfg, debuglvl: debuglvl}
|
||||||
|
for _, g := range cfg.Groups {
|
||||||
|
w := &worker{group: g, wake: make(chan bool)}
|
||||||
|
srv.workers = append(srv.workers, w)
|
||||||
|
}
|
||||||
|
return srv
|
||||||
|
}
|
32
server/worker.go
Normal file
32
server/worker.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.binarythought.com/cdramey/alrm/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type worker struct {
|
||||||
|
wake chan bool
|
||||||
|
group *config.Group
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *worker) start(debuglvl int) {
|
||||||
|
for {
|
||||||
|
if debuglvl > 2 {
|
||||||
|
fmt.Printf("%s worker waiting.. \n", w.group.Name)
|
||||||
|
}
|
||||||
|
<-w.wake
|
||||||
|
if debuglvl > 2 {
|
||||||
|
fmt.Printf("%s worker wake.. \n", w.group.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range w.group.Hosts {
|
||||||
|
for _, c := range h.Checks {
|
||||||
|
err := c.Check(debuglvl)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("check error: %s\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user