Compare commits

...

5 Commits

Author SHA1 Message Date
Ian Fijolek
7d87c3d036 Add default values for AlertEvery
There is also a test error corrected in TestMonitorFailureAlertEvery
where the same test conditions were repeated twice.
2022-12-19 15:49:32 -08:00
Ian Fijolek
deec04bf0d Allow setting of global defaults for some values
This helps with reducing redundant config.

Note: There is no default for `alert_every` because the zero value has a
meaning and cannot be interpreted as an omission.
2022-12-19 15:49:32 -08:00
Ian Fijolek
958446050f Update linters 2022-12-19 15:34:47 -08:00
Ian Fijolek
88e94642d9 Remove some hooks included in golangci-lint and upgrade existing 2022-06-07 21:39:18 -07:00
Ian Fijolek
bc83a51907 Switch pre-commit url for golang 2022-04-04 20:12:01 -07:00
8 changed files with 91 additions and 60 deletions
+13 -25
View File
@@ -1,32 +1,22 @@
--- ---
linters: linters:
enable: enable:
- asciicheck - errname
- bodyclose - errorlint
- dogsled
- dupl
- exhaustive - exhaustive
- gochecknoinits
- gocognit
- gocritic
- gocyclo
- goerr113
- gofumpt - gofumpt
- goimports - goimports
- gomnd - gomnd
- goprintffuncname - goprintffuncname
# - gosec
# - ifshort
- interfacer
- maligned
- misspell - misspell
- nakedret - tagliatelle
- nestif - tenv
- nlreturn - testpackage
- noctx - thelper
- unparam - tparallel
- unconvert
- wrapcheck
- wsl - wsl
# - errorlint
disable: disable:
- gochecknoglobals - gochecknoglobals
@@ -34,15 +24,13 @@ linters-settings:
gosec: gosec:
excludes: excludes:
- G204 - G204
# gomnd: tagliatelle:
# settings: case:
# mnd: rules:
# ignored-functions: math.* yaml: snake
issues: issues:
exclude-rules: exclude-rules:
- path: _test\.go - path: _test\.go
linters: linters:
- errcheck
- gosec - gosec
- maligned
+3 -8
View File
@@ -1,7 +1,7 @@
--- ---
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0 rev: v4.4.0
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
- id: check-yaml - id: check-yaml
@@ -11,15 +11,10 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: check-merge-conflict - id: check-merge-conflict
- repo: https://github.com/golangci/golangci-lint - repo: https://github.com/golangci/golangci-lint
rev: v1.42.1 rev: v1.50.1
hooks: hooks:
- id: golangci-lint - id: golangci-lint
- repo: git://github.com/dnephin/pre-commit-golang
rev: v0.4.0
hooks:
- id: go-fmt
- id: go-imports
- repo: https://github.com/hadolint/hadolint - repo: https://github.com/hadolint/hadolint
rev: v2.4.0 rev: v2.12.1-beta
hooks: hooks:
- id: hadolint - id: hadolint
+3
View File
@@ -55,6 +55,9 @@ The global configurations are:
|key|value| |key|value|
|---|---| |---|---|
|`check_interval`|Maximum frequency to run checks for each monitor as duration, eg. 1m2s.| |`check_interval`|Maximum frequency to run checks for each monitor as duration, eg. 1m2s.|
|`default_alert_after`|A default value used as an `alert_after` value for a monitor if not specified or 0.|
|`default_alert_down`|Default down alerts to used by a monitor in case none are provided.|
|`default_alert_up`|Default up alerts to used by a monitor in case none are provided.|
|`monitors`|List of all monitors. Detailed description below| |`monitors`|List of all monitors. Detailed description below|
|`alerts`|List of all alerts. Detailed description below| |`alerts`|List of all alerts. Detailed description below|
+23
View File
@@ -14,6 +14,10 @@ var errInvalidConfig = errors.New("Invalid configuration")
// Config type is contains all provided user configuration // Config type is contains all provided user configuration
type Config struct { type Config struct {
CheckInterval SecondsOrDuration `yaml:"check_interval"` CheckInterval SecondsOrDuration `yaml:"check_interval"`
DefaultAlertAfter int16 `yaml:"default_alert_after"`
DefaultAlertEvery *int16 `yaml:"default_alert_every"`
DefaultAlertDown []string `yaml:"default_alert_down"`
DefaultAlertUp []string `yaml:"default_alert_up"`
Monitors []*Monitor Monitors []*Monitor
Alerts map[string]*Alert Alerts map[string]*Alert
} }
@@ -135,8 +139,27 @@ func (config Config) IsValid() (isValid bool) {
// Init performs extra initialization on top of loading the config from file // Init performs extra initialization on top of loading the config from file
func (config *Config) Init() (err error) { func (config *Config) Init() (err error) {
for _, monitor := range config.Monitors {
if monitor.AlertAfter == 0 && config.DefaultAlertAfter > 0 {
monitor.AlertAfter = config.DefaultAlertAfter
}
if monitor.AlertEvery == nil && config.DefaultAlertEvery != nil {
monitor.AlertEvery = config.DefaultAlertEvery
}
if len(monitor.AlertDown) == 0 && len(config.DefaultAlertDown) > 0 {
monitor.AlertDown = config.DefaultAlertDown
}
if len(monitor.AlertUp) == 0 && len(config.DefaultAlertUp) > 0 {
monitor.AlertUp = config.DefaultAlertUp
}
}
for name, alert := range config.Alerts { for name, alert := range config.Alerts {
alert.Name = name alert.Name = name
if err = alert.BuildTemplates(); err != nil { if err = alert.BuildTemplates(); err != nil {
return return
} }
+1
View File
@@ -14,6 +14,7 @@ func TestLoadConfig(t *testing.T) {
pyCompat bool pyCompat bool
}{ }{
{"./test/valid-config.yml", false, "Valid config file", false}, {"./test/valid-config.yml", false, "Valid config file", false},
{"./test/valid-config-default-values.yml", false, "Valid config file with default values", false},
{"./test/valid-default-log-alert.yml", false, "Valid config file with default log alert PyCompat", true}, {"./test/valid-default-log-alert.yml", false, "Valid config file with default log alert PyCompat", true},
{"./test/valid-default-log-alert.yml", true, "Invalid config file no log alert", false}, {"./test/valid-default-log-alert.yml", true, "Invalid config file no log alert", false},
{"./test/does-not-exist", true, "Invalid config path", false}, {"./test/does-not-exist", true, "Invalid config path", false},
+7 -7
View File
@@ -12,7 +12,7 @@ import (
type Monitor struct { //nolint:maligned type Monitor struct { //nolint:maligned
// Config values // Config values
AlertAfter int16 `yaml:"alert_after"` AlertAfter int16 `yaml:"alert_after"`
AlertEvery int16 `yaml:"alert_every"` AlertEvery *int16 `yaml:"alert_every"`
CheckInterval SecondsOrDuration `yaml:"check_interval"` CheckInterval SecondsOrDuration `yaml:"check_interval"`
Name string Name string
AlertDown []string `yaml:"alert_down"` AlertDown []string `yaml:"alert_down"`
@@ -129,16 +129,16 @@ func (monitor *Monitor) failure() (notice *AlertNotice) {
// Use alert cadence to determine if we should alert // Use alert cadence to determine if we should alert
switch { switch {
case monitor.AlertEvery > 0: case monitor.AlertEvery == nil, *monitor.AlertEvery == 0:
// Handle integer number of failures before alerting
if failureCount%monitor.AlertEvery == 0 {
notice = monitor.createAlertNotice(false)
}
case monitor.AlertEvery == 0:
// Handle alerting on first failure only // Handle alerting on first failure only
if failureCount == 0 { if failureCount == 0 {
notice = monitor.createAlertNotice(false) notice = monitor.createAlertNotice(false)
} }
case *monitor.AlertEvery > 0:
// Handle integer number of failures before alerting
if failureCount%*monitor.AlertEvery == 0 {
notice = monitor.createAlertNotice(false)
}
default: default:
// Handle negative numbers indicating an exponential backoff // Handle negative numbers indicating an exponential backoff
if failureCount >= int16(math.Pow(2, float64(monitor.alertCount))-1) { //nolint:gomnd if failureCount >= int16(math.Pow(2, float64(monitor.alertCount))-1) { //nolint:gomnd
+26 -17
View File
@@ -141,17 +141,19 @@ func TestMonitorSuccess(t *testing.T) {
// TestMonitorFailureAlertAfter tests that alerts will not trigger until // TestMonitorFailureAlertAfter tests that alerts will not trigger until
// hitting the threshold provided by AlertAfter // hitting the threshold provided by AlertAfter
func TestMonitorFailureAlertAfter(t *testing.T) { func TestMonitorFailureAlertAfter(t *testing.T) {
var alertEvery int16 = 1
cases := []struct { cases := []struct {
monitor Monitor monitor Monitor
expectNotice bool expectNotice bool
name string name string
}{ }{
{Monitor{AlertAfter: 1}, true, "Empty"}, // Defaults to true because and AlertEvery default to 0 {Monitor{AlertAfter: 1}, true, "Empty"}, // Defaults to true because and AlertEvery default to 0
{Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: 1}, true, "Alert after 1: first failure"}, {Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEvery}, true, "Alert after 1: first failure"},
{Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: 1}, true, "Alert after 1: second failure"}, {Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: &alertEvery}, true, "Alert after 1: second failure"},
{Monitor{failureCount: 0, AlertAfter: 20, AlertEvery: 1}, false, "Alert after 20: first failure"}, {Monitor{failureCount: 0, AlertAfter: 20, AlertEvery: &alertEvery}, false, "Alert after 20: first failure"},
{Monitor{failureCount: 19, AlertAfter: 20, AlertEvery: 1}, true, "Alert after 20: 20th failure"}, {Monitor{failureCount: 19, AlertAfter: 20, AlertEvery: &alertEvery}, true, "Alert after 20: 20th failure"},
{Monitor{failureCount: 20, AlertAfter: 20, AlertEvery: 1}, true, "Alert after 20: 21st failure"}, {Monitor{failureCount: 20, AlertAfter: 20, AlertEvery: &alertEvery}, true, "Alert after 20: 21st failure"},
} }
for _, c := range cases { for _, c := range cases {
@@ -172,6 +174,11 @@ func TestMonitorFailureAlertAfter(t *testing.T) {
// TestMonitorFailureAlertEvery tests that alerts will trigger // TestMonitorFailureAlertEvery tests that alerts will trigger
// on the expected intervals // on the expected intervals
func TestMonitorFailureAlertEvery(t *testing.T) { func TestMonitorFailureAlertEvery(t *testing.T) {
var alertEvery0, alertEvery1, alertEvery2 int16
alertEvery0 = 0
alertEvery1 = 1
alertEvery2 = 2
cases := []struct { cases := []struct {
monitor Monitor monitor Monitor
expectNotice bool expectNotice bool
@@ -186,20 +193,20 @@ func TestMonitorFailureAlertEvery(t *testing.T) {
For usabilty, this should be consistent. Consistent with what though? minitor-py? Or itself? Dun dun duuuunnnnn! For usabilty, this should be consistent. Consistent with what though? minitor-py? Or itself? Dun dun duuuunnnnn!
*/ */
{Monitor{AlertAfter: 1}, true, "Empty"}, // Defaults to true because AlertAfter and AlertEvery default to 0 {Monitor{AlertAfter: 1}, true, "Empty"}, // Defaults to true because AlertAfter and AlertEvery default to nil
// Alert first time only, after 1 // Alert first time only, after 1
{Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: 0}, true, "Alert first time only after 1: first failure"}, {Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEvery0}, true, "Alert first time only after 1: first failure"},
{Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: 0}, false, "Alert first time only after 1: second failure"}, {Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: &alertEvery0}, false, "Alert first time only after 1: second failure"},
{Monitor{failureCount: 2, AlertAfter: 1, AlertEvery: 0}, false, "Alert first time only after 1: third failure"}, {Monitor{failureCount: 2, AlertAfter: 1, AlertEvery: &alertEvery0}, false, "Alert first time only after 1: third failure"},
// Alert every time, after 1 // Alert every time, after 1
{Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: 1}, true, "Alert every time after 1: first failure"}, {Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEvery1}, true, "Alert every time after 1: first failure"},
{Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: 1}, true, "Alert every time after 1: second failure"}, {Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: &alertEvery1}, true, "Alert every time after 1: second failure"},
{Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: 1}, true, "Alert every time after 1: third failure"}, {Monitor{failureCount: 2, AlertAfter: 1, AlertEvery: &alertEvery1}, true, "Alert every time after 1: third failure"},
// Alert every other time, after 1 // Alert every other time, after 1
{Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: 2}, true, "Alert every other time after 1: first failure"}, {Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEvery2}, true, "Alert every other time after 1: first failure"},
{Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: 2}, false, "Alert every other time after 1: second failure"}, {Monitor{failureCount: 1, AlertAfter: 1, AlertEvery: &alertEvery2}, false, "Alert every other time after 1: second failure"},
{Monitor{failureCount: 2, AlertAfter: 1, AlertEvery: 2}, true, "Alert every other time after 1: third failure"}, {Monitor{failureCount: 2, AlertAfter: 1, AlertEvery: &alertEvery2}, true, "Alert every other time after 1: third failure"},
{Monitor{failureCount: 3, AlertAfter: 1, AlertEvery: 2}, false, "Alert every other time after 1: fourth failure"}, {Monitor{failureCount: 3, AlertAfter: 1, AlertEvery: &alertEvery2}, false, "Alert every other time after 1: fourth failure"},
} }
for _, c := range cases { for _, c := range cases {
@@ -220,6 +227,8 @@ func TestMonitorFailureAlertEvery(t *testing.T) {
// TestMonitorFailureExponential tests that alerts will trigger // TestMonitorFailureExponential tests that alerts will trigger
// with an exponential backoff after repeated failures // with an exponential backoff after repeated failures
func TestMonitorFailureExponential(t *testing.T) { func TestMonitorFailureExponential(t *testing.T) {
var alertEveryExp int16 = -1
cases := []struct { cases := []struct {
expectNotice bool expectNotice bool
name string name string
@@ -236,7 +245,7 @@ func TestMonitorFailureExponential(t *testing.T) {
// Unlike previous tests, this one requires a static Monitor with repeated // Unlike previous tests, this one requires a static Monitor with repeated
// calls to the failure method // calls to the failure method
monitor := Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: -1} monitor := Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEveryExp}
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) log.Printf("Testing case %s", c.name)
+12
View File
@@ -0,0 +1,12 @@
---
check_interval: 1
default_alert_down: ["log_command"]
default_alert_after: 1
monitors:
- name: Command
command: ["echo", "$PATH"]
alerts:
log_command:
command: ["echo", "regular", '"command!!!"', "{{.MonitorName}}"]