Move monitor init to it's own method and refactor config validate to return err
This commit is contained in:
parent
3fb418151b
commit
9e20c00dde
@ -4,7 +4,7 @@ name: test
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: test
|
- name: test
|
||||||
image: golang:1.20
|
image: golang:1.21
|
||||||
environment:
|
environment:
|
||||||
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
|
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
|
||||||
commands:
|
commands:
|
||||||
@ -30,7 +30,7 @@ trigger:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build all binaries
|
- name: build all binaries
|
||||||
image: golang:1.20
|
image: golang:1.21
|
||||||
environment:
|
environment:
|
||||||
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
|
VERSION: ${DRONE_TAG:-${DRONE_COMMIT}}
|
||||||
commands:
|
commands:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.20 AS builder
|
FROM golang:1.21 AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
203
config.go
203
config.go
@ -6,21 +6,26 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.iamthefij.com/iamthefij/slog"
|
"git.iamthefij.com/iamthefij/slog"
|
||||||
/*
|
|
||||||
* "github.com/hashicorp/hcl/v2"
|
|
||||||
* "github.com/hashicorp/hcl/v2/gohcl"
|
|
||||||
*/
|
|
||||||
"github.com/hashicorp/hcl/v2/hclsimple"
|
"github.com/hashicorp/hcl/v2/hclsimple"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errInvalidConfig = errors.New("Invalid configuration")
|
var (
|
||||||
|
ErrLoadingConfig = errors.New("Failed to load or parse configuration")
|
||||||
|
ErrConfigInit = errors.New("Failed to initialize configuration")
|
||||||
|
ErrInvalidConfig = errors.New("Invalid configuration")
|
||||||
|
ErrNoAlerts = errors.New("No alerts provided")
|
||||||
|
ErrInvalidAlert = errors.New("Invalid alert configuration")
|
||||||
|
ErrNoMonitors = errors.New("No monitors provided")
|
||||||
|
ErrInvalidMonitor = errors.New("Invalid monitor configuration")
|
||||||
|
ErrUnknownAlert = errors.New("Unknown alert")
|
||||||
|
)
|
||||||
|
|
||||||
// Config type is contains all provided user configuration
|
// Config type is contains all provided user configuration
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CheckIntervalStr string `hcl:"check_interval"`
|
CheckIntervalStr string `hcl:"check_interval"`
|
||||||
CheckInterval time.Duration
|
CheckInterval time.Duration
|
||||||
|
|
||||||
DefaultAlertAfter *int `hcl:"default_alert_after,optional"`
|
DefaultAlertAfter int `hcl:"default_alert_after,optional"`
|
||||||
DefaultAlertEvery *int `hcl:"default_alert_every,optional"`
|
DefaultAlertEvery *int `hcl:"default_alert_every,optional"`
|
||||||
DefaultAlertDown []string `hcl:"default_alert_down,optional"`
|
DefaultAlertDown []string `hcl:"default_alert_down,optional"`
|
||||||
DefaultAlertUp []string `hcl:"default_alert_up,optional"`
|
DefaultAlertUp []string `hcl:"default_alert_up,optional"`
|
||||||
@ -30,6 +35,76 @@ type Config struct {
|
|||||||
alertLookup map[string]*Alert
|
alertLookup map[string]*Alert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init performs extra initialization on top of loading the config from file
|
||||||
|
func (config *Config) Init() (err error) {
|
||||||
|
config.CheckInterval, err = time.ParseDuration(config.CheckIntervalStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse top level check_interval duration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.DefaultAlertAfter == 0 {
|
||||||
|
minAlertAfter := 1
|
||||||
|
config.DefaultAlertAfter = minAlertAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, monitor := range config.Monitors {
|
||||||
|
if err = monitor.Init(
|
||||||
|
config.DefaultAlertAfter,
|
||||||
|
config.DefaultAlertEvery,
|
||||||
|
config.DefaultAlertDown,
|
||||||
|
config.DefaultAlertUp,
|
||||||
|
); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = config.BuildAllTemplates()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid checks config validity and returns true if valid
|
||||||
|
func (config Config) IsValid() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Validate alerts
|
||||||
|
if len(config.Alerts) == 0 {
|
||||||
|
err = errors.Join(err, ErrNoAlerts)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, alert := range config.Alerts {
|
||||||
|
if !alert.IsValid() {
|
||||||
|
err = errors.Join(err, fmt.Errorf("%w: %s", ErrInvalidAlert, alert.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate monitors
|
||||||
|
if len(config.Monitors) == 0 {
|
||||||
|
err = errors.Join(err, ErrNoMonitors)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, monitor := range config.Monitors {
|
||||||
|
if !monitor.IsValid() {
|
||||||
|
err = errors.Join(err, fmt.Errorf("%w: %s", ErrInvalidMonitor, monitor.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all Monitor alerts actually exist
|
||||||
|
for _, isUp := range []bool{true, false} {
|
||||||
|
for _, alertName := range monitor.GetAlertNames(isUp) {
|
||||||
|
if _, ok := config.GetAlert(alertName); !ok {
|
||||||
|
err = errors.Join(
|
||||||
|
err,
|
||||||
|
fmt.Errorf("%w: %s. %w: %s", ErrInvalidMonitor, monitor.Name, ErrUnknownAlert, alertName),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAlert returns an alert by name
|
||||||
func (c Config) GetAlert(name string) (*Alert, bool) {
|
func (c Config) GetAlert(name string) (*Alert, bool) {
|
||||||
if c.alertLookup == nil {
|
if c.alertLookup == nil {
|
||||||
c.alertLookup = map[string]*Alert{}
|
c.alertLookup = map[string]*Alert{}
|
||||||
@ -54,119 +129,25 @@ func (c *Config) BuildAllTemplates() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid checks config validity and returns true if valid
|
|
||||||
func (config Config) IsValid() (isValid bool) {
|
|
||||||
isValid = true
|
|
||||||
|
|
||||||
// Validate alerts
|
|
||||||
if len(config.Alerts) == 0 {
|
|
||||||
// This should never happen because there is a default alert named 'log' for now
|
|
||||||
slog.Errorf("Invalid alert configuration: Must provide at least one alert")
|
|
||||||
|
|
||||||
isValid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, alert := range config.Alerts {
|
|
||||||
if !alert.IsValid() {
|
|
||||||
slog.Errorf("Invalid alert configuration: %+v", alert.Name)
|
|
||||||
|
|
||||||
isValid = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate monitors
|
|
||||||
if len(config.Monitors) == 0 {
|
|
||||||
slog.Errorf("Invalid monitor configuration: Must provide at least one monitor")
|
|
||||||
|
|
||||||
isValid = false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, monitor := range config.Monitors {
|
|
||||||
if !monitor.IsValid() {
|
|
||||||
slog.Errorf("Invalid monitor configuration: %s", monitor.Name)
|
|
||||||
|
|
||||||
isValid = false
|
|
||||||
}
|
|
||||||
// Check that all Monitor alerts actually exist
|
|
||||||
for _, isUp := range []bool{true, false} {
|
|
||||||
for _, alertName := range monitor.GetAlertNames(isUp) {
|
|
||||||
if _, ok := config.GetAlert(alertName); !ok {
|
|
||||||
slog.Errorf(
|
|
||||||
"Invalid monitor configuration: %s. Unknown alert %s",
|
|
||||||
monitor.Name, alertName,
|
|
||||||
)
|
|
||||||
|
|
||||||
isValid = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValid
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init performs extra initialization on top of loading the config from file
|
|
||||||
func (config *Config) Init() (err error) {
|
|
||||||
config.CheckInterval, err = time.ParseDuration(config.CheckIntervalStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to parse top level check_interval duration: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, monitor := range config.Monitors {
|
|
||||||
// TODO: Move this to a Monitor.Init() method
|
|
||||||
|
|
||||||
// Parse the check_interval string into a time.Duration
|
|
||||||
if monitor.CheckIntervalStr != nil {
|
|
||||||
monitor.CheckInterval, err = time.ParseDuration(*monitor.CheckIntervalStr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to parse check_interval duration for monitor %s: %w", monitor.Name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default values for monitor alerts
|
|
||||||
if monitor.AlertAfter == 0 && config.DefaultAlertAfter != nil {
|
|
||||||
monitor.AlertAfter = *config.DefaultAlertAfter
|
|
||||||
} else if monitor.AlertAfter == 0 {
|
|
||||||
monitor.AlertAfter = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if monitor.AlertEvery == nil {
|
|
||||||
monitor.AlertEvery = config.DefaultAlertEvery
|
|
||||||
}
|
|
||||||
|
|
||||||
if monitor.AlertDown == nil {
|
|
||||||
monitor.AlertDown = config.DefaultAlertDown
|
|
||||||
}
|
|
||||||
|
|
||||||
if monitor.AlertUp == nil {
|
|
||||||
monitor.AlertUp = config.DefaultAlertUp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = config.BuildAllTemplates()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadConfig will read config from the given path and parse it
|
// LoadConfig will read config from the given path and parse it
|
||||||
func LoadConfig(filePath string) (config Config, err error) {
|
func LoadConfig(filePath string) (Config, error) {
|
||||||
err = hclsimple.DecodeFile(filePath, nil, &config)
|
var config Config
|
||||||
if err != nil {
|
|
||||||
return
|
if err := hclsimple.DecodeFile(filePath, nil, &config); err != nil {
|
||||||
|
slog.Debugf("Failed to load config from %s: %v", filePath, err)
|
||||||
|
return config, errors.Join(ErrLoadingConfig, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debugf("Config values:\n%v\n", config)
|
slog.Debugf("Config values:\n%v\n", config)
|
||||||
|
|
||||||
// Finish initializing configuration
|
// Finish initializing configuration
|
||||||
if err = config.Init(); err != nil {
|
if err := config.Init(); err != nil {
|
||||||
return
|
return config, errors.Join(ErrConfigInit, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.IsValid() {
|
if err := config.IsValid(); err != nil {
|
||||||
err = errInvalidConfig
|
return config, errors.Join(ErrInvalidConfig, err)
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, err
|
return config, nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package main_test
|
package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
m "git.iamthefij.com/iamthefij/minitor-go"
|
m "git.iamthefij.com/iamthefij/minitor-go"
|
||||||
@ -9,15 +10,17 @@ import (
|
|||||||
func TestLoadConfig(t *testing.T) {
|
func TestLoadConfig(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
configPath string
|
configPath string
|
||||||
expectErr bool
|
expectedErr error
|
||||||
name string
|
name string
|
||||||
}{
|
}{
|
||||||
{"./test/does-not-exist", true, "Invalid config path"},
|
{"./test/does-not-exist", m.ErrLoadingConfig, "Invalid config path"},
|
||||||
{"./test/invalid-config-missing-alerts.hcl", true, "Invalid config missing alerts"},
|
{"./test/invalid-config-wrong-hcl-type.hcl", m.ErrLoadingConfig, "Incorrect HCL type"},
|
||||||
{"./test/invalid-config-type.hcl", true, "Invalid config type for key"},
|
{"./test/invalid-config-missing-alerts.hcl", m.ErrNoAlerts, "Invalid config missing alerts"},
|
||||||
{"./test/invalid-config-unknown-alert.hcl", true, "Invalid config unknown alert"},
|
{"./test/invalid-config-missing-alerts.hcl", m.ErrInvalidConfig, "Invalid config general"},
|
||||||
{"./test/valid-config-default-values.hcl", false, "Valid config file with default values"},
|
{"./test/invalid-config-invalid-duration.hcl", m.ErrConfigInit, "Invalid config type for key"},
|
||||||
{"./test/valid-config.hcl", false, "Valid config file"},
|
{"./test/invalid-config-unknown-alert.hcl", m.ErrUnknownAlert, "Invalid config unknown alert"},
|
||||||
|
{"./test/valid-config-default-values.hcl", nil, "Valid config file with default values"},
|
||||||
|
{"./test/valid-config.hcl", nil, "Valid config file"},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
c := c
|
c := c
|
||||||
@ -27,9 +30,10 @@ func TestLoadConfig(t *testing.T) {
|
|||||||
|
|
||||||
_, err := m.LoadConfig(c.configPath)
|
_, err := m.LoadConfig(c.configPath)
|
||||||
hasErr := (err != nil)
|
hasErr := (err != nil)
|
||||||
|
expectErr := (c.expectedErr != nil)
|
||||||
|
|
||||||
if hasErr != c.expectErr {
|
if hasErr != expectErr || !errors.Is(err, c.expectedErr) {
|
||||||
t.Errorf("LoadConfig(%v), expected_error=%v actual=%v", c.name, c.expectErr, err)
|
t.Errorf("LoadConfig(%v), expected_error=%v actual=%v", c.name, c.expectedErr, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
|||||||
module git.iamthefij.com/iamthefij/minitor-go
|
module git.iamthefij.com/iamthefij/minitor-go
|
||||||
|
|
||||||
go 1.20
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.iamthefij.com/iamthefij/slog v1.3.0
|
git.iamthefij.com/iamthefij/slog v1.3.0
|
||||||
|
2
go.sum
2
go.sum
@ -24,6 +24,7 @@ github.com/hashicorp/hcl/v2 v2.11.1 h1:yTyWcXcm9XB0TEkyU/JCRU6rYy4K+mgLtzn2wlrJb
|
|||||||
github.com/hashicorp/hcl/v2 v2.11.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
|
github.com/hashicorp/hcl/v2 v2.11.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
@ -41,6 +42,7 @@ github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5E
|
|||||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
61
monitor.go
61
monitor.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
@ -31,8 +32,40 @@ type Monitor struct { //nolint:maligned
|
|||||||
lastCheckDuration time.Duration
|
lastCheckDuration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid returns a boolean indicating if the Monitor has been correctly
|
// Init initializes the Monitor with default values
|
||||||
// configured
|
func (monitor *Monitor) Init(defaultAlertAfter int, defaultAlertEvery *int, defaultAlertDown []string, defaultAlertUp []string) error {
|
||||||
|
// Parse the check_interval string into a time.Duration
|
||||||
|
if monitor.CheckIntervalStr != nil {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
monitor.CheckInterval, err = time.ParseDuration(*monitor.CheckIntervalStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse check_interval duration for monitor %s: %w", monitor.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default values for monitor alerts
|
||||||
|
if monitor.AlertAfter == 0 {
|
||||||
|
minAlertAfter := 1
|
||||||
|
monitor.AlertAfter = max(defaultAlertAfter, minAlertAfter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if monitor.AlertEvery == nil {
|
||||||
|
monitor.AlertEvery = defaultAlertEvery
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(monitor.AlertDown) == 0 {
|
||||||
|
monitor.AlertDown = defaultAlertDown
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(monitor.AlertUp) == 0 {
|
||||||
|
monitor.AlertUp = defaultAlertUp
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid returns a boolean indicating if the Monitor has been correctly configured
|
||||||
func (monitor Monitor) IsValid() bool {
|
func (monitor Monitor) IsValid() bool {
|
||||||
// TODO: Refactor and return an error containing more information on what was invalid
|
// TODO: Refactor and return an error containing more information on what was invalid
|
||||||
hasCommand := len(monitor.Command) > 0
|
hasCommand := len(monitor.Command) > 0
|
||||||
@ -53,8 +86,7 @@ func (monitor Monitor) LastOutput() string {
|
|||||||
return monitor.lastOutput
|
return monitor.lastOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldCheck returns a boolean indicating if the Monitor is ready to be
|
// ShouldCheck returns a boolean indicating if the Monitor is ready to be be checked again
|
||||||
// be checked again
|
|
||||||
func (monitor Monitor) ShouldCheck() bool {
|
func (monitor Monitor) ShouldCheck() bool {
|
||||||
if monitor.lastCheck.IsZero() || monitor.CheckInterval == 0 {
|
if monitor.lastCheck.IsZero() || monitor.CheckInterval == 0 {
|
||||||
return true
|
return true
|
||||||
@ -65,8 +97,7 @@ func (monitor Monitor) ShouldCheck() bool {
|
|||||||
return sinceLastCheck >= monitor.CheckInterval
|
return sinceLastCheck >= monitor.CheckInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check will run the command configured by the Monitor and return a status
|
// Check will run the command configured by the Monitor and return a status and a possible AlertNotice
|
||||||
// and a possible AlertNotice
|
|
||||||
func (monitor *Monitor) Check() (bool, *AlertNotice) {
|
func (monitor *Monitor) Check() (bool, *AlertNotice) {
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
if len(monitor.Command) > 0 {
|
if len(monitor.Command) > 0 {
|
||||||
@ -105,6 +136,15 @@ func (monitor *Monitor) Check() (bool, *AlertNotice) {
|
|||||||
return isSuccess, alertNotice
|
return isSuccess, alertNotice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAlertNames gives a list of alert names for a given monitor status
|
||||||
|
func (monitor Monitor) GetAlertNames(up bool) []string {
|
||||||
|
if up {
|
||||||
|
return monitor.AlertUp
|
||||||
|
}
|
||||||
|
|
||||||
|
return monitor.AlertDown
|
||||||
|
}
|
||||||
|
|
||||||
// IsUp returns the status of the current monitor
|
// IsUp returns the status of the current monitor
|
||||||
func (monitor Monitor) IsUp() bool {
|
func (monitor Monitor) IsUp() bool {
|
||||||
return monitor.alertCount == 0
|
return monitor.alertCount == 0
|
||||||
@ -173,15 +213,6 @@ func (monitor *Monitor) failure() (notice *AlertNotice) {
|
|||||||
return notice
|
return notice
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAlertNames gives a list of alert names for a given monitor status
|
|
||||||
func (monitor Monitor) GetAlertNames(up bool) []string {
|
|
||||||
if up {
|
|
||||||
return monitor.AlertUp
|
|
||||||
}
|
|
||||||
|
|
||||||
return monitor.AlertDown
|
|
||||||
}
|
|
||||||
|
|
||||||
func (monitor Monitor) createAlertNotice(isUp bool) *AlertNotice {
|
func (monitor Monitor) createAlertNotice(isUp bool) *AlertNotice {
|
||||||
// TODO: Maybe add something about recovery status here
|
// TODO: Maybe add something about recovery status here
|
||||||
return &AlertNotice{
|
return &AlertNotice{
|
||||||
|
12
test/invalid-config-wrong-hcl-type.hcl
Normal file
12
test/invalid-config-wrong-hcl-type.hcl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
check_interval = "1s"
|
||||||
|
|
||||||
|
alert "log_command" {
|
||||||
|
command = "should be a list"
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor "Command" {
|
||||||
|
command = ["echo", "$PATH"]
|
||||||
|
alert_down = ["log_command"]
|
||||||
|
alert_every = 2
|
||||||
|
check_interval = "10s"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user