WIP: temporary decisions for public api #1
							
								
								
									
										94
									
								
								cmd/watchdog/watchdog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								cmd/watchdog/watchdog.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | |||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"log" | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	watchdog "git.rootprojects.org/root/watchdog.go" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func usage() { | ||||||
|  | 	fmt.Println("Usage: watchdog -c config.json") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	if 3 != len(os.Args) { | ||||||
|  | 		usage() | ||||||
|  | 		os.Exit(1) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if "-c" != os.Args[1] { | ||||||
|  | 		usage() | ||||||
|  | 		os.Exit(1) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	filename := os.Args[2] | ||||||
|  | 	f, err := os.Open(filename) | ||||||
|  | 	if nil != err { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	configFile, err := ioutil.ReadAll(f) | ||||||
|  | 	if nil != err { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	config := &watchdog.Config{} | ||||||
|  | 	err = json.Unmarshal(configFile, config) | ||||||
|  | 	if nil != err { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//fmt.Printf("%#v\n", config) | ||||||
|  | 
 | ||||||
|  | 	done := make(chan struct{}, 1) | ||||||
|  | 
 | ||||||
|  | 	allWebhooks := make(map[string]watchdog.ConfigWebhook) | ||||||
|  | 
 | ||||||
|  | 	for i := range config.Webhooks { | ||||||
|  | 		h := config.Webhooks[i] | ||||||
|  | 		allWebhooks[h.Name] = h | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	logQueue := make(chan string, 10) | ||||||
|  | 	go logger(logQueue) | ||||||
|  | 	for i := range config.Watches { | ||||||
|  | 		c := config.Watches[i] | ||||||
|  | 		logQueue <- fmt.Sprintf("Watching '%s'", c.Name) | ||||||
|  | 		go func(c watchdog.ConfigWatch) { | ||||||
|  | 			d := watchdog.New(&watchdog.Dog{ | ||||||
|  | 				Name:        c.Name, | ||||||
|  | 				CheckURL:    c.URL, | ||||||
|  | 				Keywords:    c.Keywords, | ||||||
|  | 				Recover:     c.RecoverScript, | ||||||
|  | 				Webhooks:    c.Webhooks, | ||||||
|  | 				AllWebhooks: allWebhooks, | ||||||
|  | 				Logger:      logQueue, | ||||||
|  | 			}) | ||||||
|  | 			d.Watch() | ||||||
|  | 		}(config.Watches[i]) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if 0 == len(config.Watches) { | ||||||
|  | 		log.Fatal("Nothing to watch") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	<-done | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // This is so that the log messages don't trample | ||||||
|  | // over each other when they happen simultaneously. | ||||||
|  | func logger(msgs chan string) { | ||||||
|  | 	for { | ||||||
|  | 		msg := <-msgs | ||||||
|  | 		log.Println(msg) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										115
									
								
								watchdog.go
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								watchdog.go
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| package main | package watchdog | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| @ -6,90 +6,14 @@ import ( | |||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"log" |  | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"os" |  | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func usage() { |  | ||||||
| 	fmt.Println("Usage: watchdog -c config.json") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func main() { |  | ||||||
| 	if 3 != len(os.Args) { |  | ||||||
| 		usage() |  | ||||||
| 		os.Exit(1) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if "-c" != os.Args[1] { |  | ||||||
| 		usage() |  | ||||||
| 		os.Exit(1) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	filename := os.Args[2] |  | ||||||
| 	f, err := os.Open(filename) |  | ||||||
| 	if nil != err { |  | ||||||
| 		log.Fatal(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	configFile, err := ioutil.ReadAll(f) |  | ||||||
| 	if nil != err { |  | ||||||
| 		log.Fatal(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	config := &Config{} |  | ||||||
| 	err = json.Unmarshal(configFile, config) |  | ||||||
| 	if nil != err { |  | ||||||
| 		log.Fatal(err) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	//fmt.Printf("%#v\n", config) |  | ||||||
| 
 |  | ||||||
| 	done := make(chan struct{}, 1) |  | ||||||
| 
 |  | ||||||
| 	allWebhooks := make(map[string]ConfigWebhook) |  | ||||||
| 
 |  | ||||||
| 	for i := range config.Webhooks { |  | ||||||
| 		h := config.Webhooks[i] |  | ||||||
| 		allWebhooks[h.Name] = h |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	logQueue := make(chan string, 10) |  | ||||||
| 	go logger(logQueue) |  | ||||||
| 	for i := range config.Watches { |  | ||||||
| 		c := config.Watches[i] |  | ||||||
| 		logQueue <- fmt.Sprintf("Watching '%s'", c.Name) |  | ||||||
| 		go func(c ConfigWatch) { |  | ||||||
| 			d := New(&Dog{ |  | ||||||
| 				Name:        c.Name, |  | ||||||
| 				CheckURL:    c.URL, |  | ||||||
| 				Keywords:    c.Keywords, |  | ||||||
| 				Recover:     c.RecoverScript, |  | ||||||
| 				Webhooks:    c.Webhooks, |  | ||||||
| 				AllWebhooks: allWebhooks, |  | ||||||
| 				logger:      logQueue, |  | ||||||
| 			}) |  | ||||||
| 			d.Watch() |  | ||||||
| 		}(config.Watches[i]) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if 0 == len(config.Watches) { |  | ||||||
| 		log.Fatal("Nothing to watch") |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	<-done |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type Dog struct { | type Dog struct { | ||||||
| 	Name         string | 	Name         string | ||||||
| 	CheckURL     string | 	CheckURL     string | ||||||
| @ -97,7 +21,7 @@ type Dog struct { | |||||||
| 	Recover      string | 	Recover      string | ||||||
| 	Webhooks     []string | 	Webhooks     []string | ||||||
| 	AllWebhooks  map[string]ConfigWebhook | 	AllWebhooks  map[string]ConfigWebhook | ||||||
| 	logger       chan string | 	Logger       chan string | ||||||
| 	error        error | 	error        error | ||||||
| 	failures     int | 	failures     int | ||||||
| 	passes       int | 	passes       int | ||||||
| @ -121,7 +45,7 @@ func (d *Dog) Watch() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *Dog) watch() { | func (d *Dog) watch() { | ||||||
| 	d.logger <- fmt.Sprintf("Check: '%s'", d.Name) | 	d.Logger <- fmt.Sprintf("Check: '%s'", d.Name) | ||||||
| 
 | 
 | ||||||
| 	err := d.check() | 	err := d.check() | ||||||
| 	if nil == err { | 	if nil == err { | ||||||
| @ -183,11 +107,11 @@ func (d *Dog) check() error { | |||||||
| 
 | 
 | ||||||
| 	if !bytes.Contains(b, []byte(d.Keywords)) { | 	if !bytes.Contains(b, []byte(d.Keywords)) { | ||||||
| 		err = fmt.Errorf("Down: '%s' Not Found for '%s'", d.Keywords, d.Name) | 		err = fmt.Errorf("Down: '%s' Not Found for '%s'", d.Keywords, d.Name) | ||||||
| 		d.logger <- fmt.Sprintf("%s", err) | 		d.Logger <- fmt.Sprintf("%s", err) | ||||||
| 		d.error = err | 		d.error = err | ||||||
| 		return err | 		return err | ||||||
| 	} else { | 	} else { | ||||||
| 		d.logger <- fmt.Sprintf("Up: '%s'", d.Name) | 		d.Logger <- fmt.Sprintf("Up: '%s'", d.Name) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| @ -203,25 +127,25 @@ func (d *Dog) recover() { | |||||||
| 	pipe, err := cmd.StdinPipe() | 	pipe, err := cmd.StdinPipe() | ||||||
| 	pipe.Write([]byte(d.Recover)) | 	pipe.Write([]byte(d.Recover)) | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		d.logger <- fmt.Sprintf("[Recover] Could not write to bash '%s': %s", d.Recover, err) | 		d.Logger <- fmt.Sprintf("[Recover] Could not write to bash '%s': %s", d.Recover, err) | ||||||
| 	} | 	} | ||||||
| 	err = cmd.Start() | 	err = cmd.Start() | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		d.logger <- fmt.Sprintf("[Recover] Could not start '%s': %s", d.Recover, err) | 		d.Logger <- fmt.Sprintf("[Recover] Could not start '%s': %s", d.Recover, err) | ||||||
| 	} | 	} | ||||||
| 	err = pipe.Close() | 	err = pipe.Close() | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		d.logger <- fmt.Sprintf("[Recover] Could not close '%s': %s", d.Recover, err) | 		d.Logger <- fmt.Sprintf("[Recover] Could not close '%s': %s", d.Recover, err) | ||||||
| 	} | 	} | ||||||
| 	err = cmd.Wait() | 	err = cmd.Wait() | ||||||
| 	cancel() | 	cancel() | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		d.logger <- fmt.Sprintf("[Recover] '%s' failed for '%s': %s", d.Recover, d.Name, err) | 		d.Logger <- fmt.Sprintf("[Recover] '%s' failed for '%s': %s", d.Recover, d.Name, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *Dog) notify(hardFail bool) { | func (d *Dog) notify(hardFail bool) { | ||||||
| 	d.logger <- fmt.Sprintf("Notifying the authorities of %s's failure", d.Name) | 	d.Logger <- fmt.Sprintf("Notifying the authorities of %s's failure", d.Name) | ||||||
| 	d.lastNotified = time.Now() | 	d.lastNotified = time.Now() | ||||||
| 
 | 
 | ||||||
| 	for i := range d.Webhooks { | 	for i := range d.Webhooks { | ||||||
| @ -234,7 +158,7 @@ func (d *Dog) notify(hardFail bool) { | |||||||
| 		if !ok { | 		if !ok { | ||||||
| 			// TODO check in main when config is read | 			// TODO check in main when config is read | ||||||
| 			d.Webhooks[i] = "" | 			d.Webhooks[i] = "" | ||||||
| 			d.logger <- fmt.Sprintf("[Warning] Could not find webhook '%s' for '%s'", name, h.Name) | 			d.Logger <- fmt.Sprintf("[Warning] Could not find webhook '%s' for '%s'", name, h.Name) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -299,12 +223,12 @@ func (d *Dog) notify(hardFail bool) { | |||||||
| 
 | 
 | ||||||
| 		resp, err := client.Do(req) | 		resp, err := client.Do(req) | ||||||
| 		if nil != err { | 		if nil != err { | ||||||
| 			d.logger <- fmt.Sprintf("[Notify] HTTP Client Error for '%s': %s", h.Name, err) | 			d.Logger <- fmt.Sprintf("[Notify] HTTP Client Error for '%s': %s", h.Name, err) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { | 		if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { | ||||||
| 			d.logger <- fmt.Sprintf("[Notify] Response Error for '%s': %s", h.Name, resp.Status) | 			d.Logger <- fmt.Sprintf("[Notify] Response Error for '%s': %s", h.Name, resp.Status) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -314,12 +238,12 @@ func (d *Dog) notify(hardFail bool) { | |||||||
| 		decoder := json.NewDecoder(resp.Body) | 		decoder := json.NewDecoder(resp.Body) | ||||||
| 		err = decoder.Decode(&data) | 		err = decoder.Decode(&data) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			d.logger <- fmt.Sprintf("[Notify] Response Body Error for '%s': %s", h.Name, resp.Status) | 			d.Logger <- fmt.Sprintf("[Notify] Response Body Error for '%s': %s", h.Name, resp.Status) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// TODO some sort of way to determine if data is successful (keywords) | 		// TODO some sort of way to determine if data is successful (keywords) | ||||||
| 		d.logger <- fmt.Sprintf("[Notify] Success? %#v", data) | 		d.Logger <- fmt.Sprintf("[Notify] Success? %#v", data) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -362,12 +286,3 @@ func NewHTTPClient() *http.Client { | |||||||
| 	} | 	} | ||||||
| 	return client | 	return client | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // This is so that the log messages don't trample |  | ||||||
| // over each other when they happen simultaneously. |  | ||||||
| func logger(msgs chan string) { |  | ||||||
| 	for { |  | ||||||
| 		msg := <-msgs |  | ||||||
| 		log.Println(msg) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user