minitor-go/alert.go

98 lines
2.8 KiB
Go
Raw Normal View History

2019-09-21 22:03:26 +00:00
package main
import (
"bytes"
"log"
2019-09-21 22:03:26 +00:00
"os/exec"
"text/template"
"time"
)
2019-10-02 23:09:11 +00:00
// Alert is a config driven mechanism for sending a notice
2019-09-21 22:03:26 +00:00
type Alert struct {
Name string
Command []string
CommandShell string `yaml:"command_shell"`
2019-10-02 16:37:29 +00:00
commandTemplate []*template.Template
commandShellTemplate *template.Template
2019-09-21 22:03:26 +00:00
}
2019-10-02 23:09:11 +00:00
// AlertNotice captures the context for an alert to be sent
type AlertNotice struct {
MonitorName string
AlertCount int16
FailureCount int16
LastCheckOutput string
LastSuccess time.Time
IsUp bool
}
// IsValid returns a boolean indicating if the Alert has been correctly
// configured
2019-09-21 22:03:26 +00:00
func (alert Alert) IsValid() bool {
atLeastOneCommand := (alert.CommandShell != "" || alert.Command != nil)
atMostOneCommand := (alert.CommandShell == "" || alert.Command == nil)
return atLeastOneCommand && atMostOneCommand
}
2019-10-02 23:09:11 +00:00
// BuildTemplates compiles command templates for the Alert
2019-09-21 22:03:26 +00:00
func (alert *Alert) BuildTemplates() {
if alert.commandTemplate == nil && alert.Command != nil {
// build template
2019-10-02 16:37:29 +00:00
log.Println("Building template for command...")
alert.commandTemplate = []*template.Template{}
for i, cmdPart := range alert.Command {
alert.commandTemplate = append(alert.commandTemplate, template.Must(
template.New(alert.Name+string(i)).Parse(cmdPart),
))
}
log.Printf("Template built: %v", alert.commandTemplate)
2019-09-21 22:03:26 +00:00
} else if alert.commandShellTemplate == nil && alert.CommandShell != "" {
2019-10-02 16:37:29 +00:00
log.Println("Building template for shell command...")
2019-09-21 22:03:26 +00:00
alert.commandShellTemplate = template.Must(
template.New(alert.Name).Parse(alert.CommandShell),
)
2019-10-02 16:37:29 +00:00
log.Printf("Template built: %v", alert.commandShellTemplate)
2019-09-21 22:03:26 +00:00
} else {
log.Fatalf("No template provided for alert %s", alert.Name)
2019-09-21 22:03:26 +00:00
}
}
2019-10-02 23:09:11 +00:00
// Send will send an alert notice by executing the command template
func (alert Alert) Send(notice AlertNotice) {
2019-09-21 22:03:26 +00:00
var cmd *exec.Cmd
if alert.commandTemplate != nil {
// build template
2019-10-02 16:37:29 +00:00
log.Println("Send command thing...")
command := []string{}
for _, cmdTmp := range alert.commandTemplate {
var commandBuffer bytes.Buffer
err := cmdTmp.Execute(&commandBuffer, notice)
if err != nil {
panic(err)
}
command = append(command, commandBuffer.String())
}
cmd = exec.Command(command[0], command[1:]...)
2019-09-21 22:03:26 +00:00
} else if alert.commandShellTemplate != nil {
var commandBuffer bytes.Buffer
err := alert.commandShellTemplate.Execute(&commandBuffer, notice)
if err != nil {
panic(err)
}
2019-10-02 16:37:29 +00:00
shellCommand := commandBuffer.String()
2019-10-02 16:37:29 +00:00
log.Printf("About to run alert command: %s", shellCommand)
cmd = ShellCommand(shellCommand)
2019-09-21 22:03:26 +00:00
} else {
2019-10-02 16:37:29 +00:00
panic("No template compiled?")
}
output, err := cmd.CombinedOutput()
log.Printf("Check %s\n---\n%s\n---", alert.Name, string(output))
if err != nil {
panic(err)
2019-09-21 22:03:26 +00:00
}
}